Làm cách nào để hiển thị Bánh mì nướng từ chuỗi nền trên Android?


Câu trả lời:


246

Bạn có thể làm điều đó bằng cách gọi một Activity's runOnUiThreadphương pháp từ chủ đề của bạn:

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

Tôi không chắc mình hiểu cách thực hiện việc này. Tôi có public void run () hiện tại. Tôi đã thử đặt mã này ở đó. Tôi biết điều đó là không đúng vì nó không hoạt động, nhưng tôi thực sự rất bế tắc.
SwimBikeRun

14
"Hoạt động" có được chuyển tới không-ui-thread trong hàm tạo của nó không? Cách phù hợp để lấy đối tượng hoạt động mà bạn đang sử dụng từ bên trong chuỗi riêng là gì?
snapfractalpop

Đặt Threadtham chiếu của đối tượng thành Activitytrong Activity's onResume. Bỏ đặt nó trong Activity's onPause. Làm cả hai dưới một synchronizedkhóa mà cả hai ActivityThreadtôn trọng.
JohnnyLambada

5
đôi khi không có quyền truy cập vào ActivityVí dụ, bạn có thể sử dụng đơn giản helper-class thay vào đó, xem tại đây: stackoverflow.com/a/18280318/1891118
Oleksii K.

5
Tôi thường thấy rằng nó MyActivity.this.runOnUiThread()hoạt động tốt từ bên trong Thread/ AsyncTask.
Anthony Atkinson

62

Tôi muốn có một phương thức trong hoạt động của mình được gọi là phương thức showToastmà tôi có thể gọi từ mọi nơi ...

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

Sau đó, tôi thường xuyên gọi nó từ bên trong MyActivitytrên bất kỳ chuỗi nào như thế này ...

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

3
Cảm ơn, tôi đang thêm hầu hết các hoạt động này.
Gene Myers

1
Đối với TOAST, luôn sử dụng Ngữ cảnh ứng dụng, không phải Ngữ cảnh hoạt động!
Yousha Aleayoub

1
@YoushaAleayoub tại sao?
OneWorld

1
@OneWorld, bằng chứng: 1- Đối với tin nhắn nâng ly, Google Dev Guide sử dụng ngữ cảnh ứng dụng và nói rõ ràng là sử dụng nó. 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 Có rất nhiều thảo luận và phỏng đoán trong các liên kết bạn cung cấp. Ví dụ: RomainGuy nói rằng không có bộ nhớ bị rò rỉ trong bằng chứng của bạn không. 4. Một số liên kết có từ những ngày đầu của Android vào năm 2009. Cũng có người nói trong các liên kết khác rằng bạn có thể sử dụng cả hai ngữ cảnh. Hoạt động và ứng dụng. Có lẽ bạn có một bằng chứng dựa trên bằng chứng thực tế cập nhật hơn? Bạn có một liên kết cho 1?
OneWorld

28

Điều này tương tự với các câu trả lời khác, tuy nhiên được cập nhật cho các apis mới có sẵn và sạch hơn nhiều. Ngoài ra, đừng cho rằng bạn đang ở trong Bối cảnh hoạt động.

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

Khi bối cảnh bạn có không phải là một hoạt động là câu trả lời hoàn hảo. Cảm ơn rất nhiều!
francas

17

Một cách tiếp cận hoạt động ở hầu hết mọi nơi, kể cả từ những nơi bạn không có Activityhoặc View, là lấy một Handlerchuỗi chính và hiển thị lời chúc mừng:

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

Ưu điểm của phương pháp này là nó hoạt động với bất kỳ Context, bao gồm ServiceApplication.


10

Như thế này hoặc thế này , với một Runnablecho thấy Toast. Cụ thể,

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

Đôi khi, bạn phải gửi tin nhắn từ người khác Threadđến chuỗi giao diện người dùng. Loại kịch bản này xảy ra khi bạn không thể thực hiện các hoạt động Mạng / IO trên chuỗi giao diện người dùng.

Ví dụ dưới đây xử lý tình huống đó.

  1. Bạn có chuỗi giao diện người dùng
  2. Bạn phải bắt đầu hoạt động IO và do đó bạn không thể chạy Runnabletrên chuỗi giao diện người dùng. Vì vậy, đăng của bạn Runnableđể xử lý trênHandlerThread
  3. Nhận kết quả từ Runnablevà gửi nó trở lại chuỗi giao diện người dùng và hiển thị một Toastthông báo.

Giải pháp:

  1. Tạo một HandlerThread và khởi động nó
  2. Tạo một Trình xử với Vòng lặp từ HandlerThread:requestHandler
  3. Tạo một trình xử lý với Looper từ Main Thread: responseHandlervà ghi đè handleMessagephương thức
  4. postmột Runnablenhiệm vụ trênrequestHandler
  5. Bên trong Runnablecông việc, hãy gọi sendMessagevềresponseHandler
  6. sendMessageKết quả này gọi handleMessagetrong responseHandler.
  7. Nhận các thuộc tính từ Messagevà xử lý nó, cập nhật giao diện người dùng

Mã mẫu:

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

Các bài viết hữu ích:

handlerthreads-and-why-you-should-be-using-them-in-your-android-apps

android-looper-handler-handlerthread-i


5
  1. Nhận phiên bản Trình xử lý chuỗi giao diện người dùng và sử dụng handler.sendMessage();
  2. post()Phương thức gọihandler.post();
  3. runOnUiThread()
  4. view.post()

3

Bạn có thể sử dụng Looperđể gửi Toasttin nhắn. Đi qua liên kết này để biết thêm chi tiết.

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

và nó được gọi trong chuỗi của bạn. Bối cảnh có thể Activity.getContext()bắt nguồn từ việc Activitybạn phải nâng cốc chúc mừng.


2

Tôi thực hiện cách tiếp cận này dựa trên câu trả lời 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();
        }
    });
}

Làm việc tốt cho tôi.


0

Tôi gặp phải vấn đề tương tự :

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.

Trước: hàm onCreate

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

Sau: hàm onCreate

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

nó đã làm việc.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.