zoukankan      html  css  js  c++  java
  • AsyncTast 详解

    android提供了一套专门用于异步处理的类。即:AynsTask类。使用这个类可以为耗时程序开辟一个新线程进行处理,处理完时返回。

    其实,AsynTask类就是对Thread类的一个封装,并且加入了一些新的方法。编程时,两者都可以实现同样的功能。本文后面将对AsynTask和Thread进行比较。 

    1、AsynTask类结构

    asysTask类主要用到的几个内部回调函数有:

    doInBackGround()

    onPreExecute()

    onPostExecute()

    onProgressUpdate()

    正是这几个回调函数构成了AsynTask类的使用逻辑结构。

    注意:每个AsynTask子类必须至少复写doInBackGround()方法。

    2、回调逻辑关系

    调用关系如下图:

    1>主线程调用AsynTask子类实例的execute()方法后,首先会调用onPreExecute()方法。onPreExecute()在主线程中运行,可以用来写一些开始提示代码。

    2>之后启动新线程,调用doInBackground()方法,进行异步数据处理。

    3>处理完毕之后异步线程结束,在主线程中调用onPostExecute()方法。onPostExecute()可以进行一些结束提示处理。

    补充:在doInBackground()方法异步处理的时候,如果希望通知主线程一些数据(如:处理进度)。这时,可以调用publishProgress()方法。这时,主线程会调用AsynTask子类的onProgressUpdate()方法进行处理。

    3、各个函数间数据的传递

    通过上面的调用关系,我们就可以大概看出一些数据传递关系。如下:

      execute()向doInBackground()传递。

      doInBackground()的返回值会传递给onPostExecute()。

      publishProgress()向progressUpdate()传递。

    要点:为了调用关系明确及安全,AsynTask类在继承时要传入3个泛型。第一个泛型对应execute()向doInBackground()的传递类型。第二个泛型对应doInBackground()的返回类型和传递给onPostExecute()的类型。第三个泛型对应publishProgress()向progressUpdate()传递的类型。

    传递的数据都是对应类型的数组,数组都是可变长的哦。可以根据具体情况使用。

    4、实例:

    看了上面的内容,应该对asynTask类的使用逻辑有了了解。下面写一个简单的例子。

    例子功能很简单:activity中有1个textView和botton。当点击botton时,异步改变textView的值,并且在相应的回调函数执行时,用System.out.println()输出值。

    布局:

    <?xml version="1.0" encoding="utf-8"?>

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

        android:layout_width="fill_parent"

        android:layout_height="fill_parent"

        android:orientation="vertical" >

        <TextView

            android:id="@+id/text"

            android:layout_width="fill_parent"

            android:layout_height="wrap_content"

            android:text="@string/hello" />

        <Button 

            android:id="@+id/button"

            android:layout_width="fill_parent"

            android:layout_height="wrap_content"

            android:text="change"

            />

    </LinearLayout>


    java代码:

    import android.app.Activity;

    import android.os.AsyncTask;

    import android.os.Bundle;

    import android.view.View;

    import android.view.View.OnClickListener;

    import android.widget.Button;

    import android.widget.TextView;

    public class AnsyTestActivity extends Activity {

        

        

        TextView text =null;

        Button button=null;

        String str=null;

        AnsyTry anys=null;

        double result=0;

        

        @Override

        public void onCreate(Bundle savedInstanceState) {

            super.onCreate(savedInstanceState);

            setContentView(R.layout.main);

            text=(TextView) findViewById(R.id.text);

            button=(Button) findViewById(R.id.button);

            str="wei";

            button.setOnClickListener(new OnClickListener() {

                

                @Override

                public void onClick(View v) {

                    // TODO Auto-generated method stub
                    anys=new AnsyTry(text);

                    anys.execute(str);

                    

                }

            });

        }

        

        

        class AnsyTry extends AsyncTask<String, TextView, Double>{

            

            TextView te=null;

            

            public AnsyTry(TextView te) {

                super();

                this.te = te;

            }

            @Override

            protected Double doInBackground(String... params) {

                // TODO Auto-generated method stub
                double dou=0;

                if(params[0].equals("wei")){

                    System.out.println(Thread.currentThread().getName()+"  recive wei");

                    dou=100;

                }

                publishProgress(te);

                return dou;

            }

            @Override

            protected void onPostExecute(Double result) {

                // TODO Auto-generated method stub
                super.onPostExecute(result);

                System.out.println("postExecute---double---"+result);

            }

            @Override

            protected void onPreExecute() {

                // TODO Auto-generated method stub
                System.out.println("pretExecute------");

                super.onPreExecute();

            }

            @Override

            protected void onProgressUpdate(TextView... values) {

                // TODO Auto-generated method stub
                values[0].setText(values[0].getText()+"1");

                super.onProgressUpdate(values);

            }

            

        }

    }

    5、总结

    初次看到这个异步调用关系可能觉得很复杂,但其实熟悉了之后会发现这种结构很好用。这种结构将所有的线程通信都封装成回调函数,调用逻辑容易书写。尤其是在异步处理结束之后,有回调函数进行收尾处理。如果是使用Thread的run()方法,run()结束之后没有返回值。所以必须要自己建立通信机制。但是,其实使用Handler+Thread机制其实完全可以替代AsynTask的这种调用机制。只要将Handler对象传给Thread,就可以进行方便的异步处理。且这种MVC模式结构更加明显,方便管理。所以我觉得,使用asynTask还是Handler+Thread结构,个人喜好吧。但是有一点可以明显能感觉到得是,Handler+Thread适合进行大框架的异步处理,而asynTask适用于小型简单的异步处理。以上都是个人观点+理解。有新观点请指出。

  • 相关阅读:
    PAT (Advanced Level) Practice 1100 Mars Numbers (20分)
    PAT (Advanced Level) Practice 1107 Social Clusters (30分) (并查集)
    PAT (Advanced Level) Practice 1105 Spiral Matrix (25分)
    PAT (Advanced Level) Practice 1104 Sum of Number Segments (20分)
    PAT (Advanced Level) Practice 1111 Online Map (30分) (两次迪杰斯特拉混合)
    PAT (Advanced Level) Practice 1110 Complete Binary Tree (25分) (完全二叉树的判断+分享致命婴幼儿错误)
    PAT (Advanced Level) Practice 1109 Group Photo (25分)
    PAT (Advanced Level) Practice 1108 Finding Average (20分)
    P6225 [eJOI2019]异或橙子 树状数组 异或 位运算
    P4124 [CQOI2016]手机号码 数位DP
  • 原文地址:https://www.cnblogs.com/kuaileyuyi/p/3853763.html
Copyright © 2011-2022 走看看