Android'de bir arka plan iş parçacığından bir Toast nasıl görüntülersiniz?


Yanıtlar:


246

İş parçacığınızdan bir Activity's runOnUiThreadyöntemini çağırarak yapabilirsiniz :

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

Bunu nasıl yapacağımı anladığımdan emin değilim. Mevcut genel boşluğum var (). Bu kodu oraya koymayı denedim. Bunun doğru olmadığını biliyorum çünkü işe yaramadı, ama gerçekten sıkıştım.
SwimBikeRun

14
"Etkinlik" yapıcısında ui olmayan iş parçacığına mı aktarılır? Kullandığınız etkinlik nesnesini ayrı iş parçacığından almanın doğru yolu nedir?
snapfractalpop

Set Threadiçin nesnenin referansını Activityiçinde Activity's onResume. Activity'S ayarını kaldırın onPause. Her synchronizedikisini de Activityhem Threadsaygı hem de saygı duyan bir kilit altında yapın .
JohnnyLambada

5
bazen Activityörneğe erişim yoktur , bunun yerine basit yardımcı sınıfı kullanabilirsiniz, buraya bakın: stackoverflow.com/a/18280318/1891118
Oleksii K.

5
Genelde bunun MyActivity.this.runOnUiThread()bir iç Thread/ içinden gayet iyi çalıştığını buldum AsyncTask.
Anthony Atkinson

62

Aktivitemde showToasther yerden arayabileceğim bir yöntemin olmasını seviyorum ...

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

Daha sonra bunu en sık bunun MyActivitygibi herhangi bir iş parçacığı içinden ararım ...

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

3
Teşekkürler, bu çoğu etkinliği şimdi ekliyorum.
Gene Myers

1
TOAST için her zaman Etkinlik Bağlamını değil, Uygulama Bağlamını kullanın!
Yousha Aleayoub

1
@YoushaAleayoub neden?
OneWorld

1
@OneWorld, kanıtlar: 1- Bir tost mesajı için, Google Dev Guide uygulama bağlamını kullanır ve açıkça bunu kullanmasını söyler. 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 Sağladığınız bağlantılarda çok fazla tartışma ve tahmin var. Örneğin RomainGuy, kanıt numaranızda bellek sızıntısı olmadığını söylüyor. 4. Bağlantılardan bazıları Android'in 2009'daki ilk günlerinden. Ayrıca insanlar diğer bağlantılarda her iki bağlamı da kullanabileceğinizi söylüyor. Etkinlik ve uygulama. Belki daha güncel gerçek kanıta dayalı kanıtınız vardır? 1 için bağlantınız var mı?
OneWorld

28

Bu, diğer yanıtlara benzer, ancak yeni mevcut API'ler için güncellenmiştir ve çok daha temizdir. Ayrıca, bir Aktivite Bağlamında olduğunuzu varsaymaz.

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

Sahip olduğunuz bağlam, mükemmel yanıt olan bir etkinlik olmadığında. Çok teşekkürler!
francas

17

Hemen hemen her yerden işe yarayan bir yaklaşım, Activityya da olmadığın yerler de dahil olmak üzere, ana iş parçacığına Viewa kapmak Handlerve tostu göstermektir:

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

Bu yaklaşımın avantajı, ve Contextdahil olmak üzere herhangi biriyle çalışmasıdır .ServiceApplication


10

Gibi bu ya bu , bir ile Runnablegösteriler olduğunu Toast. Yani,

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

Bazen, diğerinden ThreadUI iş parçacığına mesaj göndermeniz gerekir . Bu tür bir senaryo, UI iş parçacığında Ağ / GÇ işlemlerini yürütemediğinizde ortaya çıkar.

Aşağıdaki örnek bu senaryoyu ele almaktadır.

  1. UI Konu başlığınız var
  2. IO işlemini başlatmanız gerekir ve bu nedenle RunnableUI iş parçacığı üzerinde çalıştıramazsınız . Öyleyse Runnableişleyiciye gönderHandlerThread
  3. Sonucu alın ve RunnableUI iş parçacığına geri gönderin ve bir Toastmesaj gösterin .

Çözüm:

  1. Bir HandlerThread oluşturun ve başlatın
  2. Bir oluşturun işleyicisi ile Lüper dan HandlerThread:requestHandler
  3. Ana İş Parçacığından Looper ile İşleyici oluşturun: responseHandlerve geçersiz kılma handleMessageyöntemi
  4. postüzerine bir RunnablegörevrequestHandler
  5. İç Runnablegörev, sendMessageararesponseHandler
  6. Bu sendMessagesonucu çağırma handleMessageiçinde responseHandler.
  7. Özelliklerini alın Messageve işleyin, kullanıcı arayüzünü güncelleyin

Basit kod:

    /* 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);
    }

Yararlı makaleler:

handlerthreads-niçin-sen-kullanarak olmalıdır-onları-in-your-android-uygulamalar

robot-ilmek işleyicisi-handlerthread-ı


5
  1. UI Thread Handler örneğini alın ve kullanın handler.sendMessage();
  2. Çağrı post()yöntemihandler.post();
  3. runOnUiThread()
  4. view.post()

3

Mesaj Loopergöndermek için kullanabilirsiniz Toast. Daha fazla ayrıntı için bu bağlantıya gidin .

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

ve ipliğinizde çağrılır. Bağlam , kadeh Activity.getContext()kaldırmak zorunda Activityolduğunuzdan geliyor olabilir.


2

Bu yaklaşımı mjaggard cevabına dayanarak yaptım:

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

Benim için iyi çalıştı.


0

Aynı problemle karşılaştım :

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.

Önce: onCreate işlevi

Thread thread = new Thread(new Runnable() {
    @Override
    public void run() {
        Toast.makeText(getBaseContext(), "Thread", Toast.LENGTH_LONG).show();
    }
});
thread.start();

Sonra: onCreate işlevi

runOnUiThread(new Runnable() {
    @Override
    public void run() {
        Toast.makeText(getBaseContext(), "Thread", Toast.LENGTH_LONG).show();
    }
});

işe yaradı.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.