【Android】UIインタフェース外のスレッド、UIインタフェースのリフレッシュ制御

4454 ワード

一、問題の導入
例外:Only the original thread that created a view hierarchy can touch its viewsのソリューション
なぜこのような異常が発生したのでしょうか.

各アプリケーションapkが最初に起動すると、Androidは対応するメインスレッド(Main Thread)
メインスレッドは、UIに関連するイベント、例えば、ユーザのキーイベント、ユーザが画面に接触するイベント、およびスクリーン描画イベント、
は、関連するイベントを対応するコンポーネントに配布して処理するため、メインスレッドは通常UIスレッドとも呼ばれる.wbr>
ただしAndroidアプリケーションの開発に際しては、
Android UI操作はスレッドセキュリティではなく、UIスレッドで実行する必要があります.UIスレッドを非UIスレッドで直接操作する場合、
はandroidを投げ出す.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that
created a view hierarchy can touch its views、これは通常のjavaプログラムとは異なります.
UIスレッドはイベントの傍受と描画を担当するため、UIスレッドがいつでもユーザのニーズに応えることを保証しなければならない.
UIスレッドの操作は割り込みイベントのように短く、時間のかかる操作(ネットワーク接続など)は別のスレッドを開く必要があり、
でなければ、UIスレッドが5 sを超えるとユーザ要求に応答しない場合、ダイアログボックスがポップアップしてユーザ終了アプリケーション(ANP)を通知します.wbr>
新しく開いたスレッドでUIを設定する必要がある場合、単一スレッドモデルに違反する可能性があります.
従ってandroidは、スレッド間通信を保証するMessage Queueメカニズムを採用している.wbr>
Message Queueは、Handlerを介して送信されたメッセージを格納するメッセージキューです.
Androidは、最初の起動時にUI threadに関連付けられたメッセージキューをデフォルトで作成します.
はLooperを通過することができる.myQueue()は、プログラムのいくつかの上位コンポーネントを管理するために現在のスレッドのメッセージキューを取得し、
activities,broadcast receiversなど、独自のサブスレッドでHandlerとUI threadとの通信を作成できます.
Handlerは、sendまたはpostの2つの方法でメッセージをmessage queueに送信します.
どちらのメッセージもmessage queueキューの最後に挿入され、先進的な先頭に立って実行されます.
しかし、この2つの方法で送信されるメッセージの実行方法は、
1)sendによって送信されるメッセージオブジェクトは、handlerのhandleMessage()関数によって処理されます.
2)postメソッドでrunnableオブジェクトを送信すると、自分で実行されます.
各グラフィックインタフェース付きアプリケーションが起動すると、UIスレッドと呼ばれるプライマリスレッドが作成されます.
このスレッドは自動的にmessage queueを作成し、システムからのメッセージはこのmessage queueに投入されます.
先進先出順に処理する.
UIスレッドグラフィックインタフェースにおけるviewはpost法によりGUIスレッドのmessage queueにrunnableを1つ配達することができる.wbr>
UIスレッド以外のスレッドの場合、デフォルトではmessage queueは作成されません.
UIスレッドの場合、onCreateなどのhandlerを直接作成してhandleMessageを再ロードできます.
message queueを作成するプロセスを省く.
二、解決策一
final Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
if(msg.what==0)/成功
{
Log.d(TAG, "**********************start****************************");
playVideo(strVideoPath);//インタフェースの更新方法を含める
Log.d(TAG, "***********************end*****************************");
}
}
};
new Thread()
{
@Override
public void run()
{
//handler.post(runnableUi);
try{
Log.d(TAG, "######################start###############################");
handler.sendEmptyMessage(0);//UIスレッド外でUIスレッドを更新したい
Log.d(TAG, "######################end###############################");
}
catch(Exception e)
{
Log.d(TAG, "***************************"+e.toString());
}
}
}.start();
三、ソリューション二
Runnable   runnableUi=new  Runnable(){  
@Override
public void run() {
//インターフェイスの更新
textView.setText("the Content is:"+content);
}
};
new Thread(){
public void run(){
content=df.downLoadFiles();
handler.post(runnableUi);
}
}.start();

四、特に注意して、関数パッケージを導入する時、間違ったパッケージを導入しないでください
import android.os.Handler;//これは正しいかばんです.
import java.util.logging.Handler;//このかばんではなく、前のかばんです