스레드에서 토스트 메시지를 표시하려면 어떻게 해야합니까?
스레드에서 토스트 메시지를 표시하려면 어떻게 해야합니까?
답변:
스레드에서 Activity
의 runOnUiThread
메서드를 호출하여 수행 할 수 있습니다 .
activity.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(activity, "Hello", Toast.LENGTH_SHORT).show();
}
});
Thread
받는 객체의 참조를 Activity
에 Activity
의 onResume
. 설정 해제 그것의 Activity
의 onPause
. 아래에있는 A을 모두 수행 synchronized
잠금이 모두 Activity
와 Thread
존중.
Activity
인스턴스에 대한 액세스 권한이 없습니다. 대신 간단한 도우미 클래스를 사용할 수 있습니다. 여기를 참조하십시오. stackoverflow.com/a/18280318/1891118
MyActivity.this.runOnUiThread()
내부 Thread
/ 내에서 잘 작동 한다는 것을 발견했습니다 AsyncTask
.
나는 showToast
어디에서나 호출 할 수 있는 내 활동에 메서드를 호출 하는 것을 좋아합니다 ...
public void showToast(final String toast)
{
runOnUiThread(() -> Toast.makeText(MyActivity.this, toast, Toast.LENGTH_SHORT).show());
}
그런 다음 MyActivity
이러한 스레드 에서 가장 자주 호출합니다 .
showToast(getString(R.string.MyMessage));
이것은 다른 답변과 유사하지만 새로운 사용 가능한 API로 업데이트되고 훨씬 더 깔끔합니다. 또한 활동 컨텍스트에 있다고 가정하지 않습니다.
public class MyService extends AnyContextSubclass {
public void postToastMessage(final String message) {
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(getContext(), message, Toast.LENGTH_LONG).show();
}
});
}
}
지역 정보를 포함하여 거의 어디에서 작품 당신이이하지 않는 것이 한 가지 방법 Activity
또는 View
하는 잡아하는 것입니다 Handler
메인 스레드와 토스트를 보여줍니다
public void toast(final Context context, final String text) {
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
public void run() {
Toast.makeText(context, text, Toast.LENGTH_LONG).show();
}
});
}
이 방법의 장점은 모든 작동한다는 것입니다 Context
포함 Service
하고 Application
.
마찬가지로 이 나 이 , A를 Runnable
보여줍니다 그 Toast
. 즉,
Activity activity = // reference to an Activity
// or
View view = // reference to a View
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
showToast(activity);
}
});
// or
view.post(new Runnable() {
@Override
public void run() {
showToast(view.getContext());
}
});
private void showToast(Context ctx) {
Toast.makeText(ctx, "Hi!", Toast.LENGTH_SHORT).show();
}
때로는 다른 메시지 Thread
를 UI 스레드 로 보내야합니다 . 이러한 유형의 시나리오는 UI 스레드에서 네트워크 / IO 작업을 실행할 수 없을 때 발생합니다.
아래 예제는 해당 시나리오를 처리합니다.
Runnable
UI 스레드에서 실행할 수 없습니다 . 따라서 Runnable
핸들러에 게시하십시오 .HandlerThread
Runnable
와서 UI 스레드로 다시 보내고 Toast
메시지를 표시 합니다.해결책:
HandlerThread
requestHandler
responseHandler
및 handleMessage
메서드 재정의post
Runnable
작업에requestHandler
Runnable
작업 호출 sendMessage
에responseHandler
sendMessage
결과는 handleMessage
에서 호출 됩니다 responseHandler
.Message
및 처리, UI 업데이트샘플 코드 :
/* Handler thread */
HandlerThread handlerThread = new HandlerThread("HandlerThread");
handlerThread.start();
Handler requestHandler = new Handler(handlerThread.getLooper());
final Handler responseHandler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(Message msg) {
//txtView.setText((String) msg.obj);
Toast.makeText(MainActivity.this,
"Runnable on HandlerThread is completed and got result:"+(String)msg.obj,
Toast.LENGTH_LONG)
.show();
}
};
for ( int i=0; i<5; i++) {
Runnable myRunnable = new Runnable() {
@Override
public void run() {
try {
/* Add your business logic here and construct the
Messgae which should be handled in UI thread. For
example sake, just sending a simple Text here*/
String text = "" + (++rId);
Message msg = new Message();
msg.obj = text.toString();
responseHandler.sendMessage(msg);
System.out.println(text.toString());
} catch (Exception err) {
err.printStackTrace();
}
}
};
requestHandler.post(myRunnable);
}
유용한 기사 :
메시지 Looper
를 보내는 데 사용할 수 있습니다 Toast
. 자세한 내용은 이 링크 를 참조하십시오.
public void showToastInThread(final Context context,final String str){
Looper.prepare();
MessageQueue queue = Looper.myQueue();
queue.addIdleHandler(new IdleHandler() {
int mReqCount = 0;
@Override
public boolean queueIdle() {
if (++mReqCount == 2) {
Looper.myLooper().quit();
return false;
} else
return true;
}
});
Toast.makeText(context, str,Toast.LENGTH_LONG).show();
Looper.loop();
}
그리고 그것은 당신의 스레드에서 호출됩니다. 상황이 될 수 있습니다 Activity.getContext()
으로부터 점점 Activity
당신이이 토스트를 표시합니다.
mjaggard 답변을 기반 으로이 접근 방식을 만들었습니다.
public static void toastAnywhere(final String text) {
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
public void run() {
Toast.makeText(SuperApplication.getInstance().getApplicationContext(), text,
Toast.LENGTH_LONG).show();
}
});
}
나를 위해 잘 작동했습니다.
같은 문제가 발생했습니다.
E/AndroidRuntime: FATAL EXCEPTION: Thread-4
Process: com.example.languoguang.welcomeapp, PID: 4724
java.lang.RuntimeException: Can't toast on a thread that has not called Looper.prepare()
at android.widget.Toast$TN.<init>(Toast.java:393)
at android.widget.Toast.<init>(Toast.java:117)
at android.widget.Toast.makeText(Toast.java:280)
at android.widget.Toast.makeText(Toast.java:270)
at com.example.languoguang.welcomeapp.MainActivity$1.run(MainActivity.java:51)
at java.lang.Thread.run(Thread.java:764)
I/Process: Sending signal. PID: 4724 SIG: 9
Application terminated.
이전 : onCreate 함수
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
Toast.makeText(getBaseContext(), "Thread", Toast.LENGTH_LONG).show();
}
});
thread.start();
이후 : onCreate 함수
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getBaseContext(), "Thread", Toast.LENGTH_LONG).show();
}
});
작동했습니다.