不良コード表示-Android画面UIにおけるスレッド制約


オリジナルの文章は、転載があれば、出典を明記してください.http://blog.csdn.net/yihui823/article/details/6722784
 
これは私自身が精錬した簡単な言い方です.
非UIマスタースレッドでは、UIの表示を変更することはできません.
 
主な意味は、UIマスタースレッドでは、文字、可視性、サイズなどのプロパティを含むUIの各オブジェクトの表示効果を任意に変更することができます.
 
マスタースレッドとは?
    簡単に言えば、onCreateやonResumeなどのシステム呼び出しの関数に入るとき、このときがマスタースレッドです.
    もちろんシステム呼び出しであり、私たち自身のコード呼び出しonCreateなどの関数ではありません.
これには、onClick関数などのボタンなどのコントロールのイベントリスニングも含まれます.
これに対応して、これらの関数で呼び出されないコードは、UIマスタースレッドではありません.
この場合、システムは異常を放出します.
android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
 
この制限はjava自体のswingにも存在する.任意のスレッドがUIの表示を変更することを許可すると、画面が混乱するに違いない.
次のコードはエラーです.
 
public class TemppjActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
 
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,   WindowManager.LayoutParams.FLAG_FULLSCREEN);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
       
        setContentView(R.layout.main);
       
        final Button btn = (Button) findViewById(R.id.btn);
        btn.setOnClickListener(new OnClickListener() {
           @Override
           public void onClick(View v) {
              btn.setText("I Clicked!");
           }
        });
       
        final DateFormat f = DateFormat.getDateTimeInstance();
       
        TimerTask t = new TimerTask() {
           @Override
           public void run() {
              btn.setText(f.format(new Date()));
           }
        };
       
        Timer ti = new Timer();
        ti.schedule(t, 0, 5000);
    }
}

 
赤い行を見ると、1つのタイミングで実行されるスレッドでボタンの表示テキストを制御します.このプログラムを実行するとCalledFromWrongThreadException異常が発生します.
 
では、もし私たちがこの需要があればどうしますか?できるかどうか.もちろんできます.この場合、Handlerを使う必要があります.
コードをどのように変更する必要があるかを見てみましょう.
 
public class TemppjActivity extends Activity {
   
    private Handler handle;
   
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
 
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,   WindowManager.LayoutParams.FLAG_FULLSCREEN);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
       
        setContentView(R.layout.main);
 
        final Button btn = (Button) findViewById(R.id.btn);
        final DateFormat f = DateFormat.getDateTimeInstance();
       
        handle = new Handler() {
         public void handleMessage(Message msg) { 
               btn.setText(f.format(new Date()));
             };
        };
       
        btn.setOnClickListener(new OnClickListener() {
           @Override
           public void onClick(View v) {
              btn.setText("I Clicked!");
           }
        });
       
       
        TimerTask t = new TimerTask() {
           @Override
           public void run() {
              handle.sendEmptyMessage(0);
           }
        };
       
        Timer ti = new Timer();
        ti.schedule(t, 0, 5000);
    }
}

すなわち、非UIマスタスレッドでは、UIを変更する必要がある場合、UIマスタインタフェースにメッセージを送信する.
handle.sendEmptyMessage(0);
メッセージは複雑ですが、ここでは空のメッセージを送信するだけです.
マスタスレッドではhandlerによってこれらのメッセージが処理され、メッセージが受信されると各コントロールの変更が処理されます.
handleMessage関数では、UIをどのように変更するかを具体的に制御できます.