《第一行代碼》第十章筆記
線程用法
new Thread(new Runnable() {
@Override
public void run() {
// 處理具體的邏輯
}
}).start();
子線程中更新UI
如果想要更新應(yīng)用程序里的UI元素, 則必須在主線程中進(jìn)行, 否則就會(huì)出現(xiàn)異常
解決辦法:
主線程中寫一個(gè)Handler用來處理消息,子線程中發(fā)送消息
主線程:
private Handler handler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case UPDATE_TEXT:
// 在這里可以進(jìn)行UI操作
text.setText("Nice to meet you");
break;
default:
break;
}
}
};
子線程:
new Thread(new Runnable() {
@Override
public void run() {
Message message = new Message();
message.what = UPDATE_TEXT;
handler.sendMessage(message); // 將Message對(duì)象發(fā)送出去
}
}).start();
解析異步消息處理機(jī)制

使用AsyncTask——基于異步消息處理機(jī)制,更好的封裝,更方便使用
為了更加方便我們在子線程中對(duì)UI進(jìn)行操作, Android還提供了另外一些好用的工具, 比如AsyncTask。
借助AsyncTask, 即使你對(duì)異步消息處理機(jī)制完全不了解, 也可以十分簡單地從子線程切換到主線程。
當(dāng)然, AsyncTask背后的實(shí)現(xiàn)原理也是基于異步消息處理機(jī)制的, 只是Android幫我們做了很好的封裝而已。
在繼承時(shí)我們可以為AsyncTask類指定3個(gè)泛型參數(shù), 這3個(gè)參數(shù)的用途如下。
- Params 。 在執(zhí)行AsyncTask時(shí)需要傳入的參數(shù), 可用于在后臺(tái)任務(wù)中使用。
- Progress 。 后臺(tái)任務(wù)執(zhí)行時(shí), 如果需要在界面上顯示當(dāng)前的進(jìn)度, 則使用這里指定的泛
型作為進(jìn)度單位。- Result 。 當(dāng)任務(wù)執(zhí)行完畢后, 如果需要對(duì)結(jié)果進(jìn)行返回, 則使用這里指定的泛型作為返回值類
在onPreExecute()方法中進(jìn)行一些界面上的初始化操作, 比如顯示一個(gè)進(jìn)度條對(duì)話框等
在doInBackground() 方法中執(zhí)行具體的耗時(shí)任務(wù),
在onProgressUpdate() 方法中進(jìn)行UI操作,
在onPostExecute() 方法中執(zhí)行一些任務(wù)的收尾工作
如果想要啟動(dòng)這個(gè)任務(wù), 只需編寫以下代碼即可:
new DownloadTask().execute();
這樣就不用考慮異步消息處理機(jī)制了
AndroidThreadTest 的完整代碼
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/change_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Change Text" />
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Hello world"
android:textSize="20sp" />
</RelativeLayout>
mainActivity.java:
package com.example.androidthreadtest;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
public static final int UPDATE_TEXT = 1;
private TextView text;
private Handler handler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case UPDATE_TEXT:
// 在這里可以進(jìn)行UI操作
text.setText("Nice to meet you");
break;
default:
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text = (TextView) findViewById(R.id.text);
Button changeText = (Button) findViewById(R.id.change_text);
changeText.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.change_text:
new Thread(new Runnable() {
@Override
public void run() {
Message message = new Message();
message.what = UPDATE_TEXT;
handler.sendMessage(message); // 將Message對(duì)象發(fā)送出去
}
}).start();
break;
default:
break;
}
}
}