Android UIスレッドを更新する方法

3979 ワード

リファレンス
Processes and Threads
ポイント
  • Do not block the UI thread
  • Do not access the Android UI toolkit from outside the UI thread

  • こう書くのはまちがっている
            findViewById(R.id.demo).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            Bitmap b = loadImageFromNetwork("http://www.baidu.com/img/bdlogo.png");
                            mImageView.setImageBitmap(b);
                        }
                    }).start();
                }
            });
    

    do not access the Android UI toolkit from outside the UI thread—this sample modifies the ImageView from the worker thread instead of the UI thread. This can result in undefined and unexpected behavior, which can be difficult and time-consuming to track down.
    こんな風に変えられる
    Android offers several ways to access the UI thread from other threads. Here is a list of methods that can help:
  • Activity.runOnUiThread(Runnable)
  • View.post(Runnable)
  • View.postDelayed(Runnable, long)
  •         findViewById(R.id.demo).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            final Bitmap bitmap = loadImageFromNetwork(http://www.baidu.com/img/bdlogo.png);
                            MainActivity.this.runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    mImageView.setImageBitmap(bitmap);
                                }
                            });
                        }
                    }).start();
                }
            });
    

    runOnUIThreadのソースコードを見てみましょう.
        public final void runOnUiThread(Runnable action) {
            if (Thread.currentThread() != mUiThread) {
                mHandler.post(action);
            } else {
                action.run();
            }
        }
    

    この方法は,まず現在のスレッドがUIスレッドであるかどうかを判断し,そうでなければHandlerのpostメソッドを用い,そうであればrunメソッドを直接呼び出すことになる.
    私たちは引き続きViewを見ます.post(Runnable)の書き方:
            findViewById(R.id.demo).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            final Bitmap bitmap = loadImageFromNetwork(http://www.baidu.com/img/bdlogo.png);
                            mImageView.post(new Runnable() {
                                @Override
                                public void run() {
                                    mImageView.setImageBitmap(bitmap);
                                }
                            });
                        }
                    }).start();
                }
            });
    

    ビューを表示します.Post(Runnable)のソース:
        public boolean post(Runnable action) {
            final AttachInfo attachInfo = mAttachInfo;
            if (attachInfo != null) {
                return attachInfo.mHandler.post(action);
            }
            // Assume that post will succeed later
            ViewRootImpl.getRunQueue().post(action);
            return true;
        }
    

    実際にHandlerのpostメソッドも呼び出されていることがわかります.View.Runnable,long(Runnable,long)はViewより優れている.post(Runnable)は時間パラメータを多くして、よく理解して、余計なことをしません.
    以上より,前述した3つの方法はいずれもHandle+Messageのパッケージであることが分かる.
    AsyncTaskによるUIの更新
    Androidの連中は本当に開発者のことを考えていますね.AsyncTaskは本当に使いやすいですね.また、以下の点に注意してください.
  • AsyncTaskはUIスレッドに宣言する必要があります.
  • AsyncTaskはUIスレッド上でインスタンス化する必要があります.
  • はexecute()メソッドでタスクを実行する必要があります.
  • onPreExecute()、onPostExecute(Resut)、doInBackground(Params...)、onProgressUpdate(Progress...) 方法.