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();
}
}