Android의 백그라운드 스레드에서 Toast를 어떻게 표시합니까?


답변:


246

스레드에서 ActivityrunOnUiThread메서드를 호출하여 수행 할 수 있습니다 .

activity.runOnUiThread(new Runnable() {
    public void run() {
        Toast.makeText(activity, "Hello", Toast.LENGTH_SHORT).show();
    }
});

이 작업을 수행하는 방법을 잘 모르겠습니다. 기존 public void run ()이 있습니다. 이 코드를 거기에 넣어 보았습니다. 작동하지 않았기 때문에 옳지 않다는 것을 알고 있지만 정말 붙어 있습니다.
SwimBikeRun 2012 년

14
생성자의 비 UI 스레드에 "활동"이 전달됩니까? 별도의 스레드 내에서 사용중인 활동 개체를 가져 오는 올바른 방법은 무엇입니까?
snapfractalpop 2012 년

설정 Thread받는 객체의 참조를 ActivityActivityonResume. 설정 해제 그것의 ActivityonPause. 아래에있는 A을 모두 수행 synchronized잠금이 모두 ActivityThread존중.
JohnnyLambada

5
때때로 Activity인스턴스에 대한 액세스 권한이 없습니다. 대신 간단한 도우미 클래스를 사용할 수 있습니다. 여기를 참조하십시오. stackoverflow.com/a/18280318/1891118
Oleksii K.

5
나는 일반적으로 MyActivity.this.runOnUiThread()내부 Thread/ 내에서 잘 작동 한다는 것을 발견했습니다 AsyncTask.
Anthony Atkinson

62

나는 showToast어디에서나 호출 할 수 있는 내 활동에 메서드를 호출 하는 것을 좋아합니다 ...

public void showToast(final String toast)
{
    runOnUiThread(() -> Toast.makeText(MyActivity.this, toast, Toast.LENGTH_SHORT).show());
}

그런 다음 MyActivity이러한 스레드 에서 가장 자주 호출합니다 .

showToast(getString(R.string.MyMessage));

3
감사합니다. 지금 대부분의 활동을 추가하고 있습니다.
Gene Myers

1
TOAST의 경우 항상 Activity Context가 아닌 Application Context를 사용하십시오!
Yousha Aleayoub

1
@youshaAleayoub 왜?
OneWorld

1
@OneWorld, 증명 : 1- 토스트 메시지의 경우 Google Dev Guide는 애플리케이션 컨텍스트를 사용하고 명시 적으로 사용하라고 말합니다. 2- stackoverflow.com/a/4128799/1429432 3- stackoverflow.com/a/10347346/1429432 4- groups.google.com/d/msg/android-developers/3i8M6-wAIwM/…
Yousha Aleayoub

@YoushaAleayoub 당신이 제공 한 링크에서 많은 토론과 추측이 있습니다. 예를 들어 RomainGuy는 증명 번호에 메모리 누수가 없다고 말합니다. 4. 일부 링크는 2009 년 Android 초창기의 것입니다. 또한 사람들은 다른 링크에서 두 가지 컨텍스트를 모두 사용할 수 있다고 말합니다. 활동 및 적용. 더 최신의 실제 증거 기반 증거가 있습니까? 1에 대한 링크가 있습니까?
OneWorld

28

이것은 다른 답변과 유사하지만 새로운 사용 가능한 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();
            }
        });
    }
}

당신이 가진 맥락이 완벽한 답인 활동이 아닐 때. 감사합니다!
francas

17

지역 정보를 포함하여 거의 어디에서 작품 당신이이하지 않는 것이 한 가지 방법 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.


10

마찬가지로 , 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();
}

6

때로는 다른 메시지 Thread를 UI 스레드 로 보내야합니다 . 이러한 유형의 시나리오는 UI 스레드에서 네트워크 / IO 작업을 실행할 수 없을 때 발생합니다.

아래 예제는 해당 시나리오를 처리합니다.

  1. UI 스레드가 있습니다.
  2. IO 작업을 시작해야하므로 RunnableUI 스레드에서 실행할 수 없습니다 . 따라서 Runnable핸들러에 게시하십시오 .HandlerThread
  3. 결과를 가져 Runnable와서 UI 스레드로 다시 보내고 Toast메시지를 표시 합니다.

해결책:

  1. HandlerThread 생성 및 시작
  2. 다음에서 Looper 를 사용 하여 처리기 를 만듭니다 .HandlerThreadrequestHandler
  3. Main Thread에서 Looper를 사용하여 핸들러 만들기 : responseHandlerhandleMessage메서드 재정의
  4. postRunnable작업에requestHandler
  5. 내부 Runnable작업 호출 sendMessageresponseHandler
  6. sendMessage결과는 handleMessage에서 호출 됩니다 responseHandler.
  7. 에서 속성 가져 오기 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);
    }

유용한 기사 :

handlerthreads 및 Android 앱에서 사용해야하는 이유

android-looper-handler-handlerthread-i


5
  1. UI 스레드 처리기 인스턴스 가져 오기 및 사용 handler.sendMessage();
  2. 호출 post()방법handler.post();
  3. runOnUiThread()
  4. view.post()

3

메시지 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당신이이 토스트를 표시합니다.


2

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();
        }
    });
}

나를 위해 잘 작동했습니다.


0

같은 문제가 발생했습니다.

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();
    }
});

작동했습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.