我们知道在Android中,要更新UI只能在UI主线程去更新,而不允许在子线程直接去操作UI,但是很多时候,很多耗时的工作都交给子线程去实现,当子线程执行完这些耗时的工作后,我们希望去修改UI,但Android中又不允许在子线程中去直接修改UI,如:在子线程中执行从服务器下载一张图片的任务,下载完成后,希望这张图片显示一个ImageView上,在子线程中又不能直接操作ImageView,这怎么办呢?我们只能把这张图片发送给UI主线程,然后在主线程中去显示这张图片。为了能够实现这种子线程和主线程之间的数据交换,Android提供了异步消息处理机制来解决这个问题。Android的异步消息处理机制如:Handler异步消息处理机制和AsyncTask异步任务(内部实现也是基于异步消息处理机制)。Handler异步消息处理机制由Message,Handler,MessageQueue和Looper四个部分组成。
一. 先看Android中启动子线程的方法:
例子:创建和启动子线程的三个方法,Android中多线程的写法和Java多线程写法基本上都是一样的。
(1)布局文件内容:三个按钮,分别用于启动三个子线程
1 <LinearLayout 2 xmlns:android="http://schemas.android.com/apk/res/android" 3 xmlns:tools="http://schemas.android.com/tools" 4 android:layout_width="match_parent" 5 android:layout_height="match_parent" 6 tools:context=".MainActivity" 7 android:orientation="vertical" 8 > 9 10 <Button 11 android:id="@+id/button01" 12 android:layout_width="match_parent" 13 android:layout_height="wrap_content" 14 android:text="第一种方式启动子线程" 15 /> 16 17 <Button 18 android:id="@+id/button02" 19 android:layout_width="match_parent" 20 android:layout_height="wrap_content" 21 android:text="第二种方式启动子线程" 22 /> 23 24 <Button 25 android:id="@+id/button03" 26 android:layout_width="match_parent" 27 android:layout_height="wrap_content" 28 android:text="第三种方式启动子线程" 29 /> 30 31 </LinearLayout>
(2) MainActivity:先打印出主线程的ID,分别点击三个按钮,启动三个不同的子线程,在子线程分别打印出子线程的ID
1 package zst.zst.thread01; 2 import java.util.TreeMap; 3 import android.os.Bundle; 4 import android.app.Activity; 5 import android.view.View; 6 import android.view.View.OnClickListener; 7 import android.widget.Button; 8 public class MainActivity extends Activity implements OnClickListener{ 9 private Button button01; 10 private Button button02; 11 private Button button03; 12 13 @Override 14 protected void onCreate(Bundle savedInstanceState) { 15 super.onCreate(savedInstanceState); 16 setContentView(R.layout.activity_main); 17 button01 = (Button)findViewById(R.id.button01); 18 button02 = (Button)findViewById(R.id.button02); 19 button03 = (Button)findViewById(R.id.button03); 20 button01.setOnClickListener(this); 21 button02.setOnClickListener(this); 22 button03.setOnClickListener(this); 23 24 //主线程ID 25 System.out.println("主线程的ID-----> " + String.valueOf(Thread.currentThread().getId())); 26 } 27 @Override 28 public void onClick(View v) { 29 switch (v.getId()) { 30 case R.id.button01: 31 //第一种启动子线程的方法 32 FirstThread firstThread = new FirstThread(); 33 firstThread.start(); 34 35 break; 36 case R.id.button02: 37 //第二种启动子线程的方法 38 SecondThread secondThread = new SecondThread(); 39 new Thread(secondThread).start(); 40 41 break; 42 case R.id.button03: 43 //第三种启动子线程的方法,和第二种方法是同一种启动方法,只不过这里用匿名内部类,这种方法最常见 44 new Thread(new Runnable() { 45 46 @Override 47 public void run() { 48 System.out.println("第三个子线程的ID---> " + String.valueOf(Thread.currentThread().getId())); 49 } 50 }).start(); 51 52 break; 53 default: 54 break; 55 } 56 57 } 58 //第一种方法定义一个线程 59 class FirstThread extends Thread{ 60 @Override 61 public void run() { 62 System.out.println("第一个子线程的ID---> " + String.valueOf(Thread.currentThread().getId())); 63 } 64 65 66 } 67 68 //第二种方法定义一个线程 69 class SecondThread implements Runnable{ 70 @Override 71 public void run() { 72 System.out.println("第二个子线程的ID---> " + String.valueOf(Thread.currentThread().getId())); 73 } 74 75 } 76 77 78 }
(3)
输出: