java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
Androidでは、Activityで新しく起動したスレッドがこのActivityのUIコンポーネントにアクセスすることは許可されていません.これにより、新しく起動したスレッドはUIコンポーネントの属性値を変更できません.
Javaが表示されます.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()異常
しかし、実際には、データリフレッシュUIコントロールを非同期で取得する必要がある場合が多く、HandlerメッセージメカニズムとAsyncTask非同期タスクの2つの解決方法が採用されています.
まず、異常を引き起こす例です.
上記の例では、スレッド内で1秒間休眠するとトーストメッセージが表示されjavaが現れる.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()異常.
正しい方法は次のとおりです.
HandlerオブジェクトのhandlerMessageメソッドを書き換えて、必要な処理を行います.
もちろんこの方法だけが私たちのニーズを実現できるわけではありません.
runOnUIThread(Runnable action)Activityに含まれるメソッドでは、指定したactionをUIスレッドで実行し、現在のスレッドがUIスレッドである場合、actionはすぐに実行します.現在のスレッドがUIスレッドでない場合、actionはUIのメッセージキューにイベントを送信します.
View post(Runnable aciton);
View postDelayed(Runnable action, long delayMillis);
この二つの方法も同じ理屈だ.
次は非同期タスクの処理です.
onProgressUpdateメソッドの実行publishProgressメソッド呼び出しを受信した後、UIスレッドで実行し、UIコントロールを処理します.たとえば、私たちが行ったダウンロードは、ダウンロードが何パーセントになったかを表示する必要があります.publishProgress(Value)を停止せずに更新し、進捗バーで更新します.
onPostExecute()メソッドは、doInBackground()メソッドの終了後にUIスレッドで実行され、resultを処理します.
doInBackground()メソッドでは、バックグラウンドスレッドで私たちの非同期タスクを処理し、Toastのような操作はできません.javaも出ます.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()異常.
Javaが表示されます.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()異常
しかし、実際には、データリフレッシュUIコントロールを非同期で取得する必要がある場合が多く、HandlerメッセージメカニズムとAsyncTask非同期タスクの2つの解決方法が採用されています.
まず、異常を引き起こす例です.
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
Thread.sleep(1000);
Toast.makeText(getApplicationContext(), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 0).show();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
上記の例では、スレッド内で1秒間休眠するとトーストメッセージが表示されjavaが現れる.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()異常.
正しい方法は次のとおりです.
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
Thread.sleep(1000);
handler.sendEmptyMessage(0);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 0).show();
}
};
HandlerオブジェクトのhandlerMessageメソッドを書き換えて、必要な処理を行います.
もちろんこの方法だけが私たちのニーズを実現できるわけではありません.
runOnUIThread(Runnable action)Activityに含まれるメソッドでは、指定したactionをUIスレッドで実行し、現在のスレッドがUIスレッドである場合、actionはすぐに実行します.現在のスレッドがUIスレッドでない場合、actionはUIのメッセージキューにイベントを送信します.
View post(Runnable aciton);
View postDelayed(Runnable action, long delayMillis);
この二つの方法も同じ理屈だ.
次は非同期タスクの処理です.
private class MyTask extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
publishProgress();
return null;
}
@Override
protected void onProgressUpdate(Void... values) {
// TODO Auto-generated method stub
super.onProgressUpdate(values);
try {
Thread.sleep(1000);
Toast.makeText(getApplicationContext(), "doInBackground", 0).show();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(), "onPostExecute", 0).show();
super.onPostExecute(result);
}
}
onProgressUpdateメソッドの実行publishProgressメソッド呼び出しを受信した後、UIスレッドで実行し、UIコントロールを処理します.たとえば、私たちが行ったダウンロードは、ダウンロードが何パーセントになったかを表示する必要があります.publishProgress(Value)を停止せずに更新し、進捗バーで更新します.
onPostExecute()メソッドは、doInBackground()メソッドの終了後にUIスレッドで実行され、resultを処理します.
doInBackground()メソッドでは、バックグラウンドスレッドで私たちの非同期タスクを処理し、Toastのような操作はできません.javaも出ます.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()異常.