zoukankan      html  css  js  c++  java
  • 【转】 Pro Android学习笔记(九三):AsyncTask(2):小例子

    目录(?)[-]

    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 + " "); 
            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开发相关文章

  • 相关阅读:
    Redhat MysqlReport安装配置详解
    asp.net中服务器端控件和客户端控件的交互问题
    关于弹出对话框返回值的分析
    关于父子窗口的参数传递(引用的高手的)
    呵呵!刚刚申请!
    Loadrunner教程
    性能测试常见用语
    如何删除电脑垃圾文件
    内连接和外连接
    酒桌上的规矩
  • 原文地址:https://www.cnblogs.com/blongfree/p/5048101.html
Copyright © 2011-2022 走看看