我们知道在Android中,要更新UI只能在UI主线程去更新,而不允许在子线程直接去操作UI,但是很多时候,很多耗时的工作都交给子线程去实现,当子线程执行完这些耗时的工作后,我们希望去修改UI,但Android中又不允许在子线程中去直接修改UI,如:在子线程中执行从服务器下载一张图片的任务,下载完成后,希望这张图片显示一个ImageView上,在子线程中又不能直接操作ImageView,这怎么办呢?我们只能把这张图片发送给UI主线程,然后在主线程中去显示这张图片。为了能够实现这种子线程和主线程之间的数据交换,Android提供了异步消息处理机制来解决这个问题。Android的异步消息处理机制如:Handler异步消息处理机制和AsyncTask异步任务(内部实现也是基于异步消息处理机制)。Handler异步消息处理机制由Message,Handler,MessageQueue和Looper四个部分组成。
一. 先看Android中启动子线程的方法:
例子:创建和启动子线程的三个方法,Android中多线程的写法和Java多线程写法基本上都是一样的。
(1)布局文件内容:三个按钮,分别用于启动三个子线程
<LinearLayout
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"
tools:context=".MainActivity"
android:orientation="vertical"
> <Button
android:id="@+id/button01"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="第一种方式启动子线程"
/> <Button
android:id="@+id/button02"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="第二种方式启动子线程"
/> <Button
android:id="@+id/button03"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="第三种方式启动子线程"
/> </LinearLayout>
(2) MainActivity:先打印出主线程的ID,分别点击三个按钮,启动三个不同的子线程,在子线程分别打印出子线程的ID
package zst.zst.thread01;
import java.util.TreeMap;
import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity implements OnClickListener{
private Button button01;
private Button button02;
private Button button03; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button01 = (Button)findViewById(R.id.button01);
button02 = (Button)findViewById(R.id.button02);
button03 = (Button)findViewById(R.id.button03);
button01.setOnClickListener(this);
button02.setOnClickListener(this);
button03.setOnClickListener(this); //主线程ID
System.out.println("主线程的ID-----> " + String.valueOf(Thread.currentThread().getId()));
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button01:
//第一种启动子线程的方法
FirstThread firstThread = new FirstThread();
firstThread.start(); break;
case R.id.button02:
//第二种启动子线程的方法
SecondThread secondThread = new SecondThread();
new Thread(secondThread).start(); break;
case R.id.button03:
//第三种启动子线程的方法,和第二种方法是同一种启动方法,只不过这里用匿名内部类,这种方法最常见
new Thread(new Runnable() { @Override
public void run() {
System.out.println("第三个子线程的ID---> " + String.valueOf(Thread.currentThread().getId()));
}
}).start(); break;
default:
break;
} }
//第一种方法定义一个线程
class FirstThread extends Thread{
@Override
public void run() {
System.out.println("第一个子线程的ID---> " + String.valueOf(Thread.currentThread().getId()));
} } //第二种方法定义一个线程
class SecondThread implements Runnable{
@Override
public void run() {
System.out.println("第二个子线程的ID---> " + String.valueOf(Thread.currentThread().getId()));
} } }
(3)
输出: