目录(?)[-]

  1. 继承AsyncTask
  2. UI操作接口
  3. 使用AsyncTask

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

小例子

通过简单的菜单,触发一个用sleep模拟的任务。Test Async One 1将调用1个AsyncTask任务,我们在Test Ansync One 2中同时执行两个task,看看运行的情况。Test Async Two中互动会更为复杂,task不仅在主线程写TextView,还开启一个ProgessDialog。

继承AsyncTask

我们先通过Test Async One 1来学习AsyncTask。首先实现继承AsyncTask。

public class MyLongTask extends AsyncTask<String,Integer,Integer>
    private IReportBack report = null; 
    private String tag = null; 
    //【步骤1】:构造函数,IReportBack定义主线程Activity处理task UI操作的回调函数,作为良好编程风格,无需将Activity对象直接传递过来。
    public MyLongTask(IReportBack inr, String inTag){ 
        report = inr; 
        tag = inTag; 
    } 
    
    @Override //【步骤2】:重写onPreExecute(),这是运行在主线程中(准确来将是运行在创建对象所在线程),进行后台线程运行先的初始化等处理。由于运行在主线程,因此可在此进行UI操作。
    protected void onPreExecute()
 {  
        Log.v(tag, "onPresExecute():" + Utils.getThreadSignature());
        report.reportTransient(tag, "In progress ...... ");  //调用接口中的UI处理函数。       
    }

@Override //【步骤4】从程序员的视图,在worker线程中运行的doInBackground(),通过publishProgress()触发在主线程运行的的onProgressUpdate(),当中的机制是handler。在此,我们进行在其他线程运行时需要触发的UI处理。
    protected void onProgressUpdate(Integer... values)
 {  
        Log.v(tag, "onProgressUpdate():" + Utils.getThreadSignature());                 
        Integer i = values[0]; 
        report.reportBack(tag, "Progress: i = " + i);//调用接口中的UI处理函数。
    }

@Override //【步骤5】当后台线程运行完,通过handler将最后结果通知给线程,将在主线程触发onPostExcute(),在此进行后台处理结束触发相关的UI处理。参数result为doInbackground()的返回值。
    protected void onPostExecute(Integer result)
 {  
        Log.v(tag, "onPostExecute():" + Utils.getThreadSignature()); 
        report.reportBack(tag, "result: i = " + result);         
    }      
     
    @Override //【步骤3】当调用task.execute()时,将在worker线程中执行doInBackground(),由于不在主线程中执行,不能再此进行UI操作,如果希望触发相关的UI操作,通过publishProgress(),利用隐藏的handler在主线程队列加入message进行处理。主线程处理message,触发handler的handleMessage(),这些隐藏的步骤通过AsyncTask的封装,呈现为触发onProgressUpdate()。
    protected Integer doInBackground(String... params)
 {  
        Log.v(tag,"doInBackground():" + Utils.getThreadSignature());
       for(int i = 0; i < params.length;i ++){ 
            Utils.sleepForSecs(2); //休眠2秒 
            publishProgress(i); 
        }        
        return params.length; 
    } 
}

UI操作接口

AsyncTask封装得非常好,提高task运行前、运行中、运行后的回调函数,在此我们进行相关的UI处理。这些代码都放在对AsyncTask继承类中。处理UI就离不开Activity的View,最直接的方式是将Activity对象通过构造函数传递到AsyncTask中,然而在真正的项目开发,这样做会使一个特定的任务可以任意调用Activity的功能,两者的界面不清晰,代码可读性、可维护性,检查错误方面都不太好。因此,通常会将task涉及到的UI处理放入到接口中。

public interface IReportBack { 
    public void reportBack(String tag,String message); 
    public void reportTransient(String tag,String message); 
}

使用AsyncTask

我们将在主线程中创建AsyncTask对象,下面是activity的相关代码

public class MainActivity extends Activity implements IReportBack{
    private static TextView tv = null; 
    … …

@Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
        int id = item.getItemId(); 
        if (id == R.id.testOne1){ 
            testMyLongTask(); 
        } 
        return super.onOptionsItemSelected(item); 
    } 
    
    private void testMyLongTask(){ 
        MyLongTask task = new MyLongTask(this,  "TestOne");  //创建AsyncTask对象,通过这个对象,我们可以通过调用task.cancel()来停止worker线程,这时会触发onCanceled(Object)回调函数。 
        task.execute("Hello","my","friend");    //通过execute() 来触发后台线程执行,顺序在主线程运行onPreExecute(),然后开线程运行doInBackground()的代码,doInBackground运行结束后,触发在主线程运行的onPostExecute()。
    } 
      
    @Override //接口实现
    public void reportBack(String tag, String message) {  
        tv.append(tag + " : " + message + "\n"); 
        Log.v(tag,message); 
    }

@Override //接口实现
    public void reportTransient(String tag, String message) {  
        Toast.makeText(this, tag + " : " + message, Toast.LENGTH_SHORT).show();
        reportBack(tag,message); 
    }

}

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

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

【转】 Pro Android学习笔记(九三):AsyncTask(2):小例子的更多相关文章

  1. 【转】Pro Android学习笔记(三十):Menu(1):了解Menu

    目录(?)[-] 创建Menu MenuItem的属性itemId MenuItem的属性groupId MenuItem的属性orderId MenuItem的属性可选属性 Menu触发 onOpt ...

  2. 【转】Pro Android学习笔记(三):了解Android资源(上)

    在Android开发中,资源包括文件或者值,它们和执行应用捆绑,无需在源代码中写死,因此我们可以改变或替换他们,而无需对应用重新编译. 了解资源构成 参考阅读Android学习笔记(三八):资源res ...

  3. 【转】 Pro Android学习笔记(三二):Menu(3):Context菜单

    目录(?)[-] 什么是Context menu 注册View带有Context menu 填Context菜单内容 Context菜单点击触发 什么是Context menu 在桌面电脑,我们都很熟 ...

  4. 【转】 Pro Android学习笔记(三三):Menu(4):Alternative菜单

    目录(?)[-] 什么是Alternative menu替代菜单 小例子说明 Alternative menu代码 关于Category和规范代码写法 关于flags 多个匹配的itemId等参数 什 ...

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

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

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

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

  7. 【转】 Pro Android学习笔记(二九):用户界面和控制(17):include和merge

    目录(?)[-] xml控件代码重用include xml控件代码重用merge 横屏和竖屏landsacpe portrait xml控件代码重用:include 如果我们定义一个控件,需要在不同的 ...

  8. 【转】 Pro Android学习笔记(十九):用户界面和控制(7):ListView

    目录(?)[-] 点击List的item触发 添加其他控件以及获取item数据 ListView控件以垂直布局方式显示子view.系统的android.app.ListActivity已经实现了一个只 ...

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

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

  10. 【转】Pro Android学习笔记(二五):用户界面和控制(13):LinearLayout和TableLayout

    目录(?)[-] 布局Layout 线性布局LinearLayout 表格布局TableLayout 布局Layout Layout是容器,用于对所包含的view进行布局.layout是view的子类 ...

随机推荐

  1. python 之Tornado

    一.Tomado Tornado 是 FriendFeed 使用的可扩展的非阻塞式 web 服务器及其相关工具的开源版本.这个 Web 框架看起来有些像web.py 或者 Google 的 webap ...

  2. coredata 数据库升级

    在真实开发中,因为需求是不断变化的,说不定什么时候就需要往模型里添加新的字段,添加新的模型,甚至是大规模的重构:所以数据的迁移就显得尤为重要了. CoreData 中,数据迁移本质就是把旧的 SQLi ...

  3. bower 安装

    安装Yeomannpm install --global yo搭建一个web应用脚手架,你将需要安装generator-webapp生成器:npm install -g generator-webap ...

  4. Java8_02_lambda表达式

    一.前言 这一节我们来了解下lambda表达式,主要关注以下几点: 行为参数化 匿名类 Lambda 表达式 方法 引用 二.行为参数化 1.概念 行为参数化(behavior parameteriz ...

  5. LeetCode OJ:Remove Element(移除元素)

    Given an array and a value, remove all instances of that value in place and return the new length. T ...

  6. Template pattern模板方法模式

    1>模板模式定义了算法的步骤,把这些步骤的实现延续到子类 2>模板模式为我们提供了一个代码复用的技巧 3>模板抽象类中可以定义具体方法.抽象方法和钩子方法 4>为了防止子类改变 ...

  7. OC-通知+Block

    =================================== 一.通知(NSNotification) NSNotification 通知类,这个类中有 NSNotificationCent ...

  8. Electron 使用 Webpack2 预编译 Electron 和 Browser targets

    Electron 使用 Webpack2 预编译 Electron 和 Browser targets 前一篇文章说了说怎样使用 Webpack2 预编译 Electron 应用,但是有时候我们希望使 ...

  9. 题目一:给出一个n,代表有从1到n的数字[1,2,3,··· n],问可以构成多少种二叉搜索树?

    题目一:给出一个n,代表有从1到n的数字[1,2,3,··· n],问可以构成多少种二叉搜索树? 一开始的想法是直接递归构造,时间复杂度是指数上升:后来想法是找规律:先看例子: n = 1, 有一个元 ...

  10. 你所不知道的,Java 中操作符的秘密?

    在 Java 编程的过程中,我们对数据的处理,都是通过操作符来实现的.例如,用于赋值的赋值操作符.用于运算的运算操作符等.用于比较的比较操作符,还包括逻辑操作符.按位操作符.移位操作符.三元操作符等等 ...