• 实现多线程的方式


    在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是执行完成后数据反馈部分。

  • 相关阅读:
    Visual Studio自带的的Developer Command Prompt对话框
    利用VS(Visual Studio)自带的工具查看DLL文件的信息
    谷歌面试官反馈级别
    Inno Setup中多语言时,使用占位符填充
    SQL*Plus命令
    Oracle 所有字典
    彻底完全卸载 SQL Server 2005 的图文教程
    win7(windows 7)系统下安装SQL2005(SQL Server 2005)图文教程
    创建表空间、新增用户、给用户赋予DBA权限 、删除用户下的上有数据表
    ORA-01012: not logged on
  • 原文地址:https://www.cnblogs.com/zhoujn/p/4312739.html
Copyright © 2020-2023  润新知