關于線程通信模型

01消息分發

  • 當Message對象被發送到Handler,并嘗試被處理時,Handler會對消息進行分發,即決定由誰處理消息。

  • 在消息機制中,可以有一下3種處理消息的方式:

     【高優先級】在創建Message對象時,調用Message類的靜態方法public static Message obtain(Handler h,Runnable callback),指定callback 參數,則由callback處理消息;
    
     【中等優先級】在創建Handler 對象時,調用public Handler(Callback callback)構造方法,指定callback ,將由Handler.Callback接口中定義的 public boolean handleMessage(Message msg) 方法處理消息;
    
    【低等優先級】自定義類繼承Handler類,創建自定義的Handler對象,并在自定義類中重寫public void handlerMessage(Message msg) 方法,由重寫的方法處理消息;
    

代碼

處理消息方式一

布局部分

  <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        tools:context="cn.tedu.third.MainActivity" >
    
         <ProgressBar
            android:id="@+id/progressBar1"
            style="?android:attr/progressBarStyleHorizontal"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="88dp"
            android:max="100"
            android:progress="0    />
    
        <Button
            android:id="@+id/btn_progress"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@+id/progressBar1"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="70dp"
            android:text="更新進度" 
            android:onClick="showProgress"/>
    </RelativeLayout>

Activity中

    import android.app.Activity;
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.Message;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.view.View;
    import android.widget.ProgressBar;
    
    public class MainActivity extends Activity {
        private Handler handler;
        private ProgressBar pbProgress;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            handler=new Handler();
            pbProgress=(ProgressBar) findViewById(R.id.progressBar1);
        }
    
        public void showProgress(View v){
            new UpdateProgressThread().start();
            
        }
        
        private class UpdateProgressThread extends Thread{
            private int i=0;
            @Override
            public void run() {
                for(;i<100;i++){
                    Message msg =Message.obtain(handler, new Runnable() {
                        
                        @Override
                        public void run() {
                            
                            pbProgress.setProgress(i+1);
                        }
                    });
                    msg.sendToTarget();
                    
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                
                }
            }
        }   
    }

處理消息方式二

布局部分與上面布局一樣

activity中

    import android.app.Activity;
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.Handler.Callback;
    import android.os.Message;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.view.View;
    import android.widget.ProgressBar;
    
    
    public class MainActivity extends Activity {
        private ProgressBar pbProgress;
        private Handler handler;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            handler=new Handler(new InnerCallBack());
            pbProgress=(ProgressBar) findViewById(R.id.progressBar1);
        }
        
        
        public void showProgress(View v){
            new UpdateProgressThread().start();
            
        }
        
        private class InnerCallBack implements Callback{
    
            @Override
            public boolean handleMessage(Message msg) {
                if(MESSAGE_UPDATE_PROGRESS==msg.what){
                    pbProgress.setProgress(msg.arg1);
                }
                return false;
            }
            
        }
        
        private static final int MESSAGE_UPDATE_PROGRESS = 0;
        
        private class UpdateProgressThread extends Thread{
    
            @Override
            public void run() {
                for(int i =0 ;i<100;i++){
                    Message.obtain(handler, MESSAGE_UPDATE_PROGRESS, i+1, 0).sendToTarget();
                    
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                
                }
                
            }
        }

    }

處理消息方式三

布局部分與上面布局一樣

activity中

        import android.app.Activity;
        import android.os.Bundle;
        import android.os.Handler;
        import android.os.Message;
        import android.view.Menu;
        import android.view.MenuItem;
        import android.view.View;
        import android.widget.Button;
        import android.widget.ProgressBar;
        
        public class MainActivity extends Activity {
            private ProgressBar pbProgress;
        
            private Handler handler;
            
            private static final int MESSAGE_UPDATE_PROGRESS = 0;
        
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);
                handler=new InnerHandler();
                pbProgress=(ProgressBar) findViewById(R.id.progressBar1);
            }
        
            public void showProgress(View v) {
                new UpdateProgressThread().start();
        
            }
            
            private class InnerHandler extends Handler{
                @Override
                public void handleMessage(Message msg) {
                    if(MESSAGE_UPDATE_PROGRESS==msg.what){
                        pbProgress.setProgress(msg.arg1);
                    }
                }
            }
            
            
            private class UpdateProgressThread extends Thread{
        
                @Override
                public void run() {
                    for(int i =0;i<100;i++){
                        Message.obtain(handler, MESSAGE_UPDATE_PROGRESS, i+1, 0).sendToTarget();
                    
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    
                    }
                 
                }
            }
        }

02.線程通信模型詳解

  • 由于向目標線程發送消息的線程可能比較多,為了確保目標線程能收到這些消息,并逐一處理,在消息機制中,存在4中角色:

      1.Message :消息的載體;
      2.Handler:發送消息、處理消息
      3.MessageQueue:消息隊列;
      4.Looper:消息隊列的管理者;
    
c.png

Message

  Message是消息機制中信息的載體;

Handler

- Handler用于執行消息的發出和處理;
- Handler關聯一個獨立的線程及消息隊列,即Handler在那個線程創建,則綁定到那個線程的消息隊列;
- Handler的創建決定了他所在的線程,則處理對應線程中收到的消息;

MessageQueue

  - MessageQueue是Message的容器,它是一個先進先出、后進后出的隊列;
  - 任何Message在被發出后,都會被先放到MessageQueue中,然后再逐一的發送給目標;
  - MessageQueue由Looper實現管理,因此,開發人員無須對其進行處理。

Looper

- Looper是MessageQueue的管理者;
- 當Message被發出后,由Looper關聯的MessageQueue.IdleHandler將其添加到MessageQueue中;
- Looper在工作時,會循環讀取MessageQueue,然后實現消息的發送;
- 每個線程都有獨立的Looper,由各個Looper管理各個線程的消息隊列;
- Looper必須調用Prepare()系列方法進行初始化,然后再調用loop()方法才會開始工作;
- 每個Handler在初始化之前,對應的線程中必須有匹配的Looper,而主線程默認即存在已經啟動的Looper。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容