ゼロからAndroidメッセージメカニズムを知る

5603 ワード

深入浅出の原則に基づいて、本文はスレッドからHandlerのメッセージングメカニズムの内容を詳しく紹介して、中間は多くブログを引用して、もし理解しないならば、やはりリンクの中の内容を詳しく見て、私のような基礎がしっかりしていない同級生の学習の下に適しています.
まず、なぜ非同期のタスクがあるのかというと、メインスレッド(UIスレッド)で時間のかかる操作を操作するとカートンになりやすい場合、Androidはメインスレッドで時間のかかる操作(ネットワークへのアクセス、データベースの操作)をしてはいけないことを規定しています.
現在最も基礎的な非同期タスクの使用方法:1.Handlerメッセージングメカニズムを使用する;2.AsyncTask非同期タスクを使用する.
マルチスレッドを実現する方法に慣れていない場合は、javaスレッドシリーズ---RunnableとThreadの違いを狂ってください.
結論:実現方式は1.Runnableインタフェースを実現する2.Threadクラスのマルチスレッドを継承することは必ずRunnableインタフェースを実現することを主とし、Runnableを使用してマルチスレッドを実現することは資源共有の目的を達成することができる.また、ThreadクラスもRunnableの実の息子である.
この場合、ハンドラーの実装方法を手書きで書くことができない場合は、Androidハンドラーの詳細な使用方法の例を狂ってください.
使用法:1.handlerを作成したスレッドにバインドすると、簡単で乱暴で面白くありません.
    //  handler        handler(UI  )
    Handler handler = new Handler();

    //              
    handler.removeCallbacks(update_thread);

    Runnable update_thread = new Runnable()
    {
        public void run()
        {
            //UI  
        }
    };
    handler.post(update_thread);
    //           


2.handlerのメッセージキューメカニズム、ゆっくりした前戯足
    //   :
    update_progress_handler.post(update_thread);

    //    handler,          
    Handler update_progress_handler = new Handler()
    {
        @Override
        public void handleMessage(Message msg) {
            // UI  
            // msg.arg1 = "bilibili"
        }
    };

    Runnable update_thread = new Runnable()
    {
        public void run() {
            Message msg = update_progress_handler.obtainMessage();
            //           ,msg  handleMessage   
            msg.arg1 = "bilibili";
            update_progress_handler.sendMessage(msg);
        }
    };

    //  
    update_progress_handler.removeCallbacks(update_thread);

3.自分でリンクを見よう…
handler.sendMessage(msg)とhandler.post(Runnable)はどんな場合に使うか知っています.次は硬い料理です.
気をつけてください:Android非同期メッセージ処理メカニズムは、Looper、Handler、Messageの3つの関係を深く理解させます.
結論
1.まずLooper.prepare()はこのスレッドにLooperインスタンスを保存し、次にこのインスタンスにMessageQueueオブジェクトを保存する.Looper.prepare()は1つのスレッドで1回しか呼び出せないため、MessageQueueは1つのスレッドに1つしか存在しません.2、Looper.loop()は、現在のスレッドを無限ループにし、MessageQueueのインスタンスからメッセージを読み取り、msg.target.dispatchMessage(msg)メソッドをコールバックします.3.Handlerの構築方法は、まず現在のスレッドに保存されているLooperインスタンスを取得し、さらにLooperインスタンスのMessageQueueに関連付ける.4、HandlerのsendMessageメソッドは、msgのtargetにhandler自身に割り当てられ、MessageQueueに追加されます.5.Handlerインスタンスを構築する際、handleMessageメソッド、すなわちmsg.target.dispatchMessage(msg)が最終的に呼び出すメソッドを書き換える
また、最終呼び出しの方法はすべてこれなので注意してください.
public void dispatchMessage(Message msg) {  
      if (msg.callback != null) { 
          handleCallback(msg);  
      } else {  
          if (mCallback != null) {  
              if (mCallback.handleMessage(msg)) {  
                  return;  
              }  
          }  
          handleMessage(msg);  
      }  
  } 

配布メッセージプロセス:
Messageのmsg.callbackが空でない場合、コールバック方法msg.callback.run()HandlerのmCallbackが空でない場合、コールバック方法mCallback.handleMessage(msg);最後にHandler自身のコールバックメソッドhandleMessage()が呼び出され、このメソッドはデフォルトで空であり、Handlerサブクラスはこのメソッドを上書きすることによって具体的な論理を完了する.
メッセージ配信の優先度:
Messageのコールバック方法:message.callback.run()で、優先度が最も高い.HandlerにおけるCallbackのコールバック方法:Handler.mCallback.handleMessage(msg)で、優先度は1に次ぐ.Handlerのデフォルトメソッド:Handler.handleMessage(msg)、優先度が最も低い.
多くの場合、メッセージ配信後の処理方法は第3のケース、すなわちHandler.handleMessage()であり、一般的には、この方法を上書きすることによって独自のビジネスロジックを実現することが多い.
何も知らないのか?方向を変えてあなたに一回言って、内容を補充して、全体の過程のAndroidメッセージのメカニズムの原理の剖析をもっとよく理解することができます-閉ループの総括
結論
(a)MessageQueueとLooper:一対一の関係であり、MessageQueueの作成後にLooperに置かれる.(b)Looperとスレッド:1つのスレッドが1つしかなく、作成後はThreadLocalに保存し、ThreadLocal.get()を取得すればよい.(c)HandlerとLooper:Handlerの作成時にThreadLocalからLooperを取得し,Handler変数はこのLooper,HandlerとLooperバインドを指す.(d)MessageとHandler:HandlerがMessageを送信するとき,Messageのtarget属性はこのHandlerを指し,このMessage(e)メッセージプール:only oneを処理するためにこのHandlerを配布するためのものであり,すべてのスレッドが共有される.
今はAndroidのメッセージメカニズムが抜けていますが、たまに使うときは非同期のメッセージ処理メカニズムを考え、Handlerを使ってメッセージを送信したり受信したりします.
この時、AsyncTaskをマスターしなければなりません.Android AsyncTaskは完全に解析し、ソースコードの観点から徹底的に理解しなければなりません.
強い突起:
 *                                       
 *  1                  onPreExecute      UI  
 *  2                  doInBackground        
 *  3                  publishProgress       
 *  4                  onProgressUpdate    UI  
 *  5                  onPostExecute       UI  

次の操作を行います.
private class MyTask extends AsyncTask {
        @Override
        protected void onPreExecute() {
            //onPreExecute               UI  
        }

        //doInBackground          ,         UI
        @Override
        protected String doInBackground(String... params) {
            //doInBackground          ,         UI
            //      UI        
            publishProgress(i);
            return null;
        }

        @Override
        protected void onProgressUpdate(Integer... progresses) {
            //onProgressUpdate          
        }

        @Override
        protected void onPostExecute(String result) {
            //onPostExecute               UI,    
        }

        @Override
        protected void onCancelled() {
            //onCancelled                UI
        }
    }

呼び出し:
               //     new    ,           ,       
                mTask = new MyTask();
                mTask.execute();

                //           ,onCancelled       
                mTask.cancel(true);

結論:
AsyncTaskも非同期メッセージ処理メカニズムを使用していますが、非常に良いパッケージを作っています.