实现多线程的方式

在Android系统里的线程分为有消息循环的线程和没有消息循环的线程。我们上一节介绍的应用程序主线程就是一个有消息循环的线程,而通过直接继承Thread类的线程是没有消息循环的线程,当然我们也可以通过在线程里调用Looper.prepare(),让系统为该线程建立一个消息队列。

下面我们介绍两种常用的多线程方式。

11.3.1  Thread

通过继承Thread类进行多线程编程是最简单的方式之一。

其基本步骤如下。

(1)继承Thead类生成其子类,并实现其run()方法,该方法就是我们需要线程完成其功能的地方,例如在run()里进行网上图片的下载。

(2)在活动Activity里相应的地方实例化Thread子类并调用start()运行线程。

(3)在线程运行过程中如果需要更新UI,则通过Activity的handler发送消息给主线程。

下面是线程示例。

Threadtest.java

1.   class Threadtest extends Activity {

2.   Handler handler = new Handler(){

3.   @Override

4.   public void handleMessage( Message msg ){

5.   if( msg.what == 0 ){

6.   msg.getData();

7.   //update ui                  

8.   }

9.   }

10.  };

在第2~10行,定了一个handler的消息处理函数,该handler直接绑定到主线程的消息循环上。当其他线程通过handler的sendMessage发送消息给主线程后,主线程的消息循环会派发消息给handleMessage函数处理消息,我们就在此处根据消息msg传来的数据进行相应的UI操作等动作。

11.  public void onCreate(Bundle savedInstanceState) {

12.  super.onCreate(savedInstanceState);

13.  ...

14.  t = new myThread();

15.  t .start();

16.  }

第14~15行是在Activity里实例化myThread类并运行。

17.  class myThread extends Thread{

18.  public void run() {

19.  ...

20.  Message msg = new Message();

21.  msg.what = 0;

22.  Bundle data=new Bundle();

23.  ...

24.  message.setData(data);                  

25.  handler.sendMessage(msg);

26.  }}}

第17~25行,我们的myThread继承自Thread,并实现了run()函数,在run()里进行相应的操作,例如去网上下载图片、MP3等。当完成任务后,我们通过构造一个新消息msg,把运行结果等数据放入msg,并通过上面的handler把消息发送给主线程。至此线程完成功能。

这个例子是个逻辑示例,在第2~10行,定了一个handler的消息处理函数,该handler直接绑定到主线程的消息循环上。当其他线程通过handler的sendMessage发送消息给主线程后,主线程的消息循环会派发消息给handleMessage函数处理消息,我们就在此处根据消息msg传来的数据进行相应的UI操作等动作。

第17~25行,我们的myThread继承自Thread,并实现了run()函数,在run()里进行相应的操作,例如去网上下载图片、MP3等。当完成任务后,我们通过构造一个新消息msg,把运行结果等数据放入msg,并通过上面的handler把消息发送给主线程。至此线程完成功能。

第14~15行是在Activity里实例化myThread类并运行。

11.3.2  AsyncTask

AsyncTask也是实现多线程的一种常用方式,它封装了一些方法方便我们维护线程,并可以解决一些线程安全问题。通过继承AsyncTask类来进行多线程编程,将使得UI thread编程变得非常简单。它不需要借助Handler即可实现UI更新。

其基本步骤如下。

(1)继承AsyncTask生成子类。

(2)实现AsyncTask中定义的下面一个或几个方法。

onPreExecute():该方法将在执行实际的后台操作前被主线程调用,我们可以在该方法中做一些准备工作。 

doInBackground(Params...):将在onPreExecute方法执行后马上执行,该方法运行在后台线程中。这里将主要负责执行那些很耗时的后台计算工作。可以调用publishProgress方法来更新实时的任务进度。该方法是子类必须实现的。 

onProgressUpdate(Progress...):在publishProgress方法被调用后,主线程将调用这个方法从而在界面上展示任务的进展情况。

onPostExecute(Result):在doInBackground 执行完成后。onPostExecute 方法将被主线程调用,后台的计算结果将通过该方法传递到主线程。

这4个方法都不能手动调用,而且除了doInBackground(Params...)方法,其余3个方法都是被主线程所调用的,所以要求AsyncTask的实例必须在主线程中创建,AsyncTask.execute方法必须在主线程中调用。

下面是一个自定义AsyncTask类的示例。

1.   class MyAsyncTask extends AsyncTask {

2.   public MyAsyncTask(Activity mActivity) {

3.   super();

4.   //初始化工作;

5.   }

第2~5行是类的构造函数,我们可以通过此函数传递上下文等资源。

6.   @Override

7.   protected void onPreExecute() {

8.   //准备工作,主线程中执行

9.   super.onPreExecute();

10.  }

第7~10行onPreExecute函数,进行准备工作。

11.  @Override

12.  protected Object doInBackground(Object... params) {

13.  //执行后台操作,即另外的线程中执行

14.  return new Object();

15.  }

第11~15行doInBackground是后台线程部分,具体执行我们所需要做的工作代码。

16.  @Override

17.  protected void onPostExecute(Object result) {

18.  //doInBackground执行完进入该方法中,此时又回到主线程中

19.  }

第16~19行onPostExecute是执行完成后数据反馈部分。

20.  }

第2~5行是类的构造函数,我们可以通过此函数传递上下文等资源。

第7~10行onPreExecute函数,进行准备工作。

第11~15行doInBackground是后台线程部分,具体执行我们所需要做的工作代码。

第16~19行onPostExecute是执行完成后数据反馈部分。

转载于:https://www.cnblogs.com/zhoujn/p/4312739.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值