目录(?)[-]

  1. worker线程小例子
  2. 小例子代码worker线程通过handler实现与主线程的通信
  3. 小例子代码继承Handler代码
  4. 小例子代码子线程的Runnable

文章转载只能用于非商业性质,且不能带有虚拟货币、积分、注册等附加条件。转载须注明出处:http://blog.csdn.net/flowingflying/

对于时间较长处理一般不放在UI线程(即主线程)中,避免出现ANR的现象,我们会另启一个线程,利用handler进行子线程和主线程之间的通信,实现子线程触发UI操作。这种类型的子线程通常称为worker thread。具体实现步骤如下:

1、在主线程创建Handler对象;

2、创建一个线程(即worker线程),将Handler对象传递给该线程;

3、运行线程,如果需要进行UI的操作,通过handler将message加入到主线程的队列中。message实际成为worker线程和主线程的通信桥梁;

4、主线程处理message。

worker线程小例子

小例子很简单,如图。点击菜单,触发处理(1、UI提示开始,2、sleep 10秒,3、UI提示结束),由于处理时间很长,为了避免ANR的情况,该处理将在线程中运行。

小例子代码:worker线程通过handler实现与主线程的通信

根据对象编程从上之下的设计思想,我们看看主线程中如何启动子线程,并将handler的对象传递到线程中。后面在补上相关的Handler集成和子线程的执行Runnable的实现。

public class MainActivity extends Activity { 
    ... ... 
    @Override //点击菜单触发子线程
    public boolean onOptionsItemSelected(MenuItem item) { 
        int id = item.getItemId(); 
        if( id == R.id.menu_worker_thread){ 
            testWorkerThread(); 
            return true; 
        } 
        return super.onOptionsItemSelected(item); 
    } 
    
    private Handler reportHandler = null; 
    private Thread workerThread = null; 
    private void testWorkerThread(){ 
       //【1】在主线程创建Handler对象 
        if(reportHandler == null){ 
            reportHandler = new ReportStatusHandler(this); 
        } 
        //将handler传递至创建的线程,并开启线程 
        if(workerThread!= null && workerThread.getState() != Thread.State.TERMINATED){
            showinfo("Thread is new or alive, but not terminated"); //在Logcat和textview中显示信息
        }else{ 
            showinfo("Old thread existed and terminated, create an new one");
            workerThread = new Thread( new WorkerThreadRunnable(reportHandler) );
            workerThread.start(); 
       } 
    }  
    ... ... 
}

小例子代码:继承Handler代码

ReportStatusHandler集成Handler,根据message的内容进行相应的UI处理,和之前的学习没有什么差别。

public class ReportStatusHandler extends Handler
    private MainActivity parentActivity = null; 
    public static final String DATA_MESSAGE="cn.flowingflying.proandroid.testhandler.message";
    
    public ReportStatusHandler(MainActivity activity){ 
        parentActivity = activity; 
    } 
    @Override //【4】根据message的内容进行相应的UI处理,UI处理将在UI线程,即主线程中进行,因此ReportStatusHandler对象也应在主线程中创建。
    public void handleMessage(Message msg) {  
        Bundle b = msg.getData(); 
        String s = b.getString(DATA_MESSAGE);  
        // 在此进行UI操作,包括textview的和Toast的处理  
        …… UI处理        
    } 
}

小例子代码:子线程的Runnable

/* Runnable这是java中对线程执行内容的具体实现 */
public class WorkerThreadRunnable implements Runnable
    Handler handler = null;  //记录在主线程创建的handler参考 
    //【2】在构建函数中将主线程的handler传递过来
    public WorkerThreadRunnable(Handler h){ 
        handler = h; 
    } 
    
    @Override //子线程的执行内容,本例用sleep来进行模拟,在sleep的开始和结束子线程需要与UI线程互动,实际上我们还可以每sleep一秒就触发一次互动。 
    public void run() {  
        informUi("WorkerThread is start running..."); 
        for(int i = 0; i < 10; i ++){ 
            try{ 
                Thread.sleep(1000); 
                 … … // Tell Ui thread to do something here ,for example informUi(…….);
            }catch(Exception e){ 
                Log.e("WorkerThreadRunnable",e.toString()); 
            } 
        } 
        informUi("WorkerThread is finished..."); 
    } 
   //【3】通过handler消息将message放入主线程的队列,实现子线程和主线程的通信
   private void informUi(String s){
 
        Message msg = handler.obtainMessage(); 
        Bundle b = new Bundle(); 
        b.putString(ReportStatusHandler.DATA_MESSAGE, s); 
        msg.setData(b); 
        handler.sendMessage(msg); 
    } 
}

相关小例子源代码可在Pro Android学习:了解Handler小例子中下载。

相关链接: 我的Android开发相关文章

【转】 Pro Android学习笔记(九十):了解Handler(4):Worker线程的更多相关文章

  1. Pro Android学习笔记 ActionBar(1):Home图标区

     Pro Android学习笔记(四八):ActionBar(1):Home图标区 2013年03月10日 ⁄ 综合 ⁄ 共 3256字 ⁄ 字号 小 中 大 ⁄ 评论关闭 ActionBar在A ...

  2. 【转】 Pro Android学习笔记(九二):AsyncTask(1):AsyncTask类

    文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.csdn.net/flowingflying/ 在Handler的学习系列中,学习了如何h ...

  3. 【转】 Pro Android学习笔记(八二):了解Package(1):包和进程

    文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.csdn.net/flowingflying/ 在之前,我们已经学习了如何签发apk,见P ...

  4. 【转】 Pro Android学习笔记(七四):HTTP服务(8):使用后台线程AsyncTask

    目录(?)[-] 5秒超时异常 AsyncTask 实现AsyncTask抽象类 对AsyncTask的调用 在哪里运行 其他重要method 文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注 ...

  5. 【转】 Pro Android学习笔记(六七):HTTP服务(1):HTTP GET

    目录(?)[-] HTTP GET小例子 简单小例子 出现异常NetworkOnMainThreadException 通过StrictMode进行处理 URL带键值对 Andriod应用可利用ser ...

  6. 【转】 Pro Android学习笔记(五五):调试和分析(3):adb命令、模拟器控制台和StrictMode

    目录(?)[-] adb命令 模拟器Console StrictMode adb命令 我们在学习SQLite的使用,介绍过部分adb命令的使用,见Pro Android学习笔记(五):了解Conten ...

  7. 【转】 Pro Android学习笔记(五六):配置变化

    目录(?)[-] Activity的destorycreate过程 Fragment的destorycreate过程 onSaveInstanceState saveFragmentInstanceS ...

  8. 【转】 Pro Android学习笔记(五二):ActionBar(5):list模式

    可以在action bar中加入spinner的下来菜单,有关spinner,可以参考Pro Android学习笔记(二十):用户界面和控制(8):GridView和Spinner. list的样式和 ...

  9. 【转】 Pro Android学习笔记(四二):Fragment(7):切换效果

    目录(?)[-] 利用setTransition 利用setCustomAnimations 通过ObjectAnimator自定义动态效果 程序代码的编写 利用fragment transactio ...

  10. 【转】 Pro Android学习笔记(四十):Fragment(5):适应不同屏幕或排版

    目录(?)[-] 设置横排和竖排的不同排版风格 改写代码 对于fragment,经常涉及不同屏幕尺寸和不同的排版风格.我们在基础小例子上做一下改动,在横排的时候,仍是现实左右两个fragment,在竖 ...

随机推荐

  1. VIM操作基础命令

    VIM操作基础命令 1 文件操作 1.1 打开文件 VIM 使用 –o 或 –O 选项打开多个文件,其中 –o 表示垂直并排,例如 vim -o lesson4 lesson5 lesson6.大O表 ...

  2. Java socket - 使用代理服务器

    为什么使用代理服务器不需要多说了. 使用Proxy Java提供了Proxy类实现使用代理进行通信. Proxy类的构造器Proxy(Proxy.Type type, SocketAddress sa ...

  3. MailUtils 测试邮件是否发送

    import java.util.Properties; import javax.mail.Message; import javax.mail.Session; import javax.mail ...

  4. hdu 5978 To begin or not to begin(概率,找规律)

    To begin or not to begin Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java ...

  5. oracle内存分析

    oracle时间内存=SGA+PGA SGA(System Global Area):由所有服务进程和后台进程共享: PGA(Program Global Area):由每个服务进程.后台进程专有:每 ...

  6. 25-THREE.JS 绘制线框样式几何图形的材质 线材质

    <!DOCTYPE html> <html> <head> <title></title> <script src="htt ...

  7. 【spark】分区

    RDD是弹性分布式数据集,通常RDD很大,会被分成多个分区,保存在不同节点上. 那么分区有什么好处呢? 分区能减少节点之间的通信开销,正确的分区能大大加快程序的执行速度. 我们看个例子 首先我们要了解 ...

  8. react table dropdown

    <DropdownButton type="primary" trigger={['click']} onClick={() => this.detail(item)} ...

  9. 【git】不同协议的路径

    https https://github.com/yesuuu/ganLearn.git ssh git@github.com:yesuuu/ganLearn.git git@idc:ganLearn ...

  10. C++复制构造函数的实现

    复制构造函数是一种特殊的构造函数,有一般构造函数的特性.它的功能是用一个已知的对象来初始化一个被创建的同类对象.复制构造函数的参数传递方式必须按引用来进行传递,请看实例: #include <i ...