2022年2月24日 星期四

Android Studio - Message(訊息)(五十)

Android Studio - Message(訊息)(五十):

Message(訊息)是代表一堆資料數據,像郵件,利用 Message 類別,將想傳送的資料藉由 Bundle(附加檔) 夾帶在 Message 中傳送給 Handler,讓 Handler 可以在接受到資訊後更新介面。Android 使用 Message 對象來管理訊息數據,並將這些 Message 對象發到訊息隊列中進行管理。Message 對象放入訊息隊列以及從訊息隊列取出並處理,這些操作都是通過 Handler 對象來管理的。但是執行這些機制的最外層是通過 Looper 對象進行管理的。

Android Studio Message(訊息)結構
Message:訊息,其中包含了訊息 ID,訊息處理對象以及處理的數據等,由 MessageQueue 統一隊列,終由 Handler 處理。
Android Studio Message(訊息)結構
Handler 的背後有著 Looper 以及 MessageQueue 的協助,三者通力合作,分工明確。
  • Thread:線程,負責調度整個消息循環,即消息循環的執行場所
  • Handler(管理程序) : 負責傳送並處理訊息,面向開發者,提供 API,並隱藏背後實現的細節
  • Looper(訊息環):負責關聯 Thread 以及訊息的分發在該 Thread 下從 MessageQueue 獲取 Message,分發給 Handler
  • MessageQueue:訊息隊列,用來存放 Handler 發送過來的消息,並按照 FIFO 規則執行。當然,存放 Message 並非實際意義的保存,而是將 Message 以鍊表的方式串聯起來的,等待 Looper 的抽取

獲取 Message 大概有如下幾種方式::

Message message = myHandler.obtainMessage();  //通過 Handler 範例獲取

Message message1 = Message.obtain();           //通過 Message 獲取

Message message2 = new Message();              //直接建立新的 Message 範例


使用 sendMessage 方法:

public class MainActivity extends Activity implements Button.OnClickListener {

   

    private TextView statusTextView = null;

 

    //uiHandler在主線程中創建,所以自動綁定主執行緒

    private Handler uiHandler = new Handler(){

        @Override

        public void handleMessage(Message msg) {

            switch (msg.what){

                case 1:

                    System.out.println("handleMessage thread id " + Thread.currentThread().getId());

                    System.out.println("msg.arg1:" + msg.arg1);

                    System.out.println("msg.arg2:" + msg.arg2);

                    MainActivity.this.statusTextView.setText("檔下載完成");

                    break;

            }

        }

    };

 

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        statusTextView = (TextView)findViewById(R.id.statusTextView);

        Button btnDownload = (Button)findViewById(R.id.btnDownload);

        btnDownload.setOnClickListener(this);

        System.out.println("Main thread id " + Thread.currentThread().getId());

    }

 

    @Override

    public void onClick(View v) {

        DownloadThread downloadThread = new DownloadThread();

        downloadThread.start();

    }

 

    class DownloadThread extends Thread{

        @Override

        public void run() {

            try{

                System.out.println("DownloadThread id " + Thread.currentThread().getId());

                System.out.println("開始下載檔案");

                //此處讓線程DownloadThread休眠5秒中,模擬檔的耗時過程

                Thread.sleep(5000);

                System.out.println("檔下載完成");

                //檔下載完成後更新UI

                Message msg = new Message();

                //雖然Message的構造函數式public的,我們也可以通過以下兩種方式通過迴圈物件獲取Message

                //msg = Message.obtain(uiHandler);

                //msg = uiHandler.obtainMessage();

 

                //what是我們自訂的一個Message的識別碼,以便於在HandlerhandleMessage方法中根據what識別

                //出不同的Message,以便我們做出不同的處理操作

                msg.what = 1;

 

                //我們可以通過arg1arg2Message傳入簡單的資料

                msg.arg1 = 123;

                msg.arg2 = 321;

                //我們也可以通過給obj賦值Object類型傳遞向Message傳入任意資料

                //msg.obj = null;

                //我們還可以通過setData方法和getData方法向Message中寫入和讀取Bundle類型的資料

                //msg.setData(null);

                //Bundle data = msg.getData();

 

                //將該Message發送給對應的Handler

                uiHandler.sendMessage(msg);

            }catch (InterruptedException e){

                e.printStackTrace();

            }

        }

    }

}


2022年 2月 24日(Thu)天氣報告
氣溫:29.0°F / -2.0°C @ 07:00
風速:每小時 3公里
降雨機會:2%
相對濕度:百分之 87%
天氣:局部有雲

沒有留言:

張貼留言