1. 程式人生 > >Android多執行緒程式設計————微信頁面載入示例

Android多執行緒程式設計————微信頁面載入示例

為什麼使用多執行緒?

       因為所有程式碼都預設執行在主執行緒當中,所以當程式執行需要執行一些耗時操作,如發起一條網路請求時,由於網速等原因,伺服器未必立刻響應請求,如果不將這類操作放在子執行緒裡去執行,就會導致主執行緒被阻塞住。

 

現在我們實現一個簡單的微信初始化載入頁面的過程

      首先,微信初始化載入頁面,並不需要進行任何控制元件的點選監聽,所以,在這裡新建一個活動並且在設定為程式入口,命名為LoadingActivity.java和自定義佈局。在佈局中,使用android:background = “@繪製/載入”

的方式載入圖片。

 

1.執行緒的基本用法

使用匿名類的方式實現可執行介面(更常見),如下:

new Thread(new Runnable() {
	@Override
	public void run() {
	// 處理具體的邏輯
	}}).start();

 

2.在子執行緒中不能直接更新UI

Android的UI是執行緒不安全的,想更新應用程式裡的UI元素,則必須在主執行緒中進行,否則會出現異常。

若必須在子執行緒中執行耗時任務,根據任務執行結果更新相應UI控制元件?

Android提供了一套非同步訊息處理機制

 

解析非同步訊息處理機制

        Android中的非同步訊息處理主要由四個部分組成,Message,Handler,MessageQueue和Looper。這裡只需使用訊息,Handler這兩部分。

1.訊息

線上程之間傳遞的訊息,可在內部攜帶少量資訊,用於在不同執行緒間交換資料。什麼欄位是訊息的標記,obj欄位攜帶物件物件,arg1和arg2欄位攜帶整型資料。

2.處理程式

處理者,主要用於傳送和處理訊息。傳送訊息sendMessage()方法,而發出的訊息經過一系列地輾轉處理後,最終會傳遞到Handler的handleMessage()方法中。

3. MessageQueue

訊息佇列,主要存放所有通過處理程式傳送的訊息(一直存在於訊息佇列中等待被處理)。每個執行緒中只會有一個的MessageQueue物件。

4. Looper

是每個執行緒中MessageQueue的管家,呼叫Looper的loop()方法會進入到一個無限迴圈當中,然後每當發現MessageQueue中存在一條訊息,就會將它取出,並傳遞到Handler的handleMessage()方法中。每個執行緒中也只會有一個Looper物件。

 

 

 

以下是示例程式碼段

public class LoadingActivity extends AppCompatActivity {
    ImageView starApp;//進行登入影象載入

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_loading);
        starApp =findViewById(R.id.starApp);//控制元件繫結
        loadingPicture();
    }

    boolean values = false;//標誌位
    Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (msg.what ==1){
                starApp.setImageResource((Integer) msg.obj);//圖片屬性需要強轉
                values =true;
            }
        }


    };

    private void loadingPicture() {
        new Thread(new Runnable() {//常見的使用匿名類的方式實現Runnable介面
            @Override
            public void run() {
                try {
                    Thread.sleep(2000);//設定延遲2s
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                Message message = new Message();
                message.what = 1;//what 欄位是訊息的標記
                message.obj = R.drawable.loading; //obj 欄位攜帶Object物件,

                handler.sendMessage(message);
                /*傳送訊息sendMessage()方法,而發出的訊息經過一系列地輾轉處理後,最終會傳遞到Handler 的handleMessage()方法中。
                 */
                if (values =true){//如果是turn,則開始載入
                    Intent intent = new Intent(LoadingActivity.this,LoginActivity.class);
                    startActivity(intent);
                    finish();//點選取消就可以返回退出程式(模擬器桌面)
                }
            }
        }).start();
    }
}