android 提示異常:java.lang.RuntimeException: Can't create handler inside thread that has not called
阿新 • • 發佈:2019-01-13
出現此異常,可能是在子執行緒彈Toast/Dialog或者其他了, 切記,Toast/Dialog只能在UI執行緒彈出。
處理的話,要麼子執行緒也可以,要麼都放主執行緒,以下兩種方式分別對應。
Android-在子執行緒中顯示Toast和Dialog
Android中有句話說,只能在主執行緒(UI執行緒)中更新UI,這是因為Android的主執行緒(UI執行緒)是不安全的。所以在子執行緒如果要顯示Toast或者Dialog,我們需要通知主執行緒來顯示 ,有兩種方法可以解決此問題:
(1)在UI程式碼的前後加上Loop.prepare()和Loop.loop();例如:
Looper.prepare(); showExitDialog(App.getInstance().getCurrentActivity()); Looper.loop();
(2)通過handler訊息來建立,具體方法是建立一個handler,然後在子執行緒中傳送一個Message訊息,在handler收到訊息後建立Toast或Dialog.
public class DialogActivity extends Activity{ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); new Thread(new TestThread(this)).start(); } Handler hmessage = new Handler() { @Override public void handleMessage(Message msg) { if (msg.what == 1) { dialog(); Toast.makeText(DialogActivity.this, "333", Toast.LENGTH_LONG).show(); } super.handleMessage(msg); } }; private void dialog() { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setMessage("確認退出嗎?"); builder.setTitle("提示"); builder.setPositiveButton("確認", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }); builder.setNegativeButton("取消", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }); builder.create().show(); } class TestThread implements Runnable { private DialogActivity da = null; public TestThread(DialogActivity da) { this.da = da; } @Override public void run() { hmessage.sendEmptyMessage(1); } } }
注:
1、Looper用來為一個執行緒開啟一個訊息迴圈。預設情況下,子執行緒是有沒有Looper的。Looper通過MessageQueue來存放訊息和事件,一個執行緒只能有一個Looper,對應一個MessageQueue。
2、在子執行緒中直接new Handler()會報錯,原因是沒有建立Looper,需先用Looper.prepare啟用Looper。
Looper.loop()讓Looper開始工作。