美文网首页
Android-AsyncTask异步任务、

Android-AsyncTask异步任务、

作者: 晴天ccc | 来源:发表于2022-04-04 10:20 被阅读0次

Android 为什么要引入异步任务

  • Android程序刚启动时,会同时启动一个对应的主线程(Main Thread),这个主线程主要负责处理 与UI相关的事件!有时我们也把他称作UI线程!
  • 假如我们在非UI线程中,比如在主线程中new Thread()另外开辟一个线程,然后直接在里面修改UI控件的值; 此时会抛出下述异常: android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views
  • 如果我们把耗时的操作都放在UI线程中的话,如果UI线程超过5s没有响应用于请求,那么 这个时候会引发ANR(Application Not Responding)异常,就是应用无响应。

一、为什么要用AsyncTask?

  • 官方给我们提供了AsyncTask这个封装好的轻量级异步类,通过几十行的代码就可以完成 我们的异步操作,而且进度可控。
  • 实际异步用的最多的地方就是网络操作,图片加载,数据传输等。

注意事项

  • Task的实例必须在UI thread中创建。
  • execute方法必须在UI thread中调用。
  • 不要手动的调用onPreExecute, onProgressUpdate,doInBackground,onPostExecute这几个方法。
  • 该Task只能被执行一次,否则多次调用时将会出现异尝。

二、AsyncTask方法讲解:

新建一个类TestAsyncTask继承AsyncTask,需要指定三个泛型参数。

public class TestAsyncTask extends AsyncTask<Void, Integer, String>{
}

第一个参数Params: 开始异步任务执行时传入的参数类型,对应excute()中传递的参数。
第二个参数Progress: 异步任务执行过程中,返回下载进度值的类型。
第三个参数Result: 异步任务执行完成后,返回的结果类型,与doInBackground()的返回值类型保持一致。

/**
 * 第一个参数Parma: 执行异步任务时传入的参数,即doInBackground方法参数类型。
 * 第二个参数Progress: 显示异步任务的进度,选择Integer类型,即onProgressUpdate方法参数类型。
 * 第三个参数Result: 异步任务执行完成后,返回的结果类型。即onPostExecute方法的参数类型与doInBackground()的返回值类型保持一致。
 * 执行顺序:  onPreExecute --> doInBackground --> onProgressUpdate --> onPostExecute
 */
public class TestAsyncTask extends AsyncTask<Void, Integer, String> {

    /**
     * 通常用于一些初始化操作
     */
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        // 在主线程(UI线程)
        // 进行各种初始化
    }

    /**
     * 核心方法,负责执行很耗时的异步任务工作。
     */
    @Override
    protected String doInBackground(Void... voids) {
        // 在子线程
        // 在onPreExecute方法执行后马上执行

        // 可调用publishProgress() 方法触发onProgressUpdate对UI进行操作
        // 比如传递后台任务的进度值,倒计时,下载进度....等
        publishProgress(10);

        return "String";
    }

    /**
     * 负责回主线程进行UI交互,比如实时刷新显示进度条数据等
     * 在doInBackground方法中调用publishProgress方法则触发该方法
     */
    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);
        // 在主线程(UI线程)
        // 在这里处理UI更新等
    }

    /**
     * 接收线程任务的执行结果,将执行结果进行回调到主线程
     */
    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);
        // 在主线程(UI线程)
        // 异步任务doInBackground执行完毕会自动执行该方法
        // 这里onPostExecute方法的参数,和doInBackground的返回值类型必须保持一致

    }

    /**
     * 取消异步任务时触发该方法
     */
    @Override
    protected void onCancelled(String s) {
        super.onCancelled(s);
        // 在主线程(UI线程)
        // 取消异步任务时触发该方法

    }
}

三、如何使用

1、在doInBackground方法中实现异步任务。
2、建AsyncTask子类的实例对象
3、手动调用execute( )从而执行异步线程任务。

  • Task的实例必须在主线程中创建;
  • execute()方法必须在主线程中调用;
  • 不要手动的调用onPreExecute()、onPostExecute(Result)、doInBackground(Param…)、onProgressUpdate(Progress…)这几个方法;
  • 每个实例Task只能被执行一次,否则多次调用时将会出现异常。所以要进行判断。

四、AsyncTask使用示例(延时线程来模拟文件下载的过程):

布局文件:activity.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    xmlns:tools="http://schemas.android.com/tools"  
    android:layout_width="match_parent"  
    android:layout_height="match_parent"  
    android:orientation="vertical"  
    tools:context=".MyActivity">  
    <TextView  
        android:id="@+id/txttitle"  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content" />  
    <!--设置一个进度条,并且设置为水平方向-->  
    <ProgressBar  
        android:layout_width="fill_parent"  
        android:layout_height="wrap_content"  
        android:id="@+id/pgbar"  
        style="?android:attr/progressBarStyleHorizontal"/>  
    <Button  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        android:id="@+id/btnupdate"  
        android:text="更新progressBar"/>  
</LinearLayout> 

定义一个延时操作,用于模拟下载:

public class DelayOperator {  
    //延时操作,用来模拟下载  
    public void delay()  
    {  
        try {  
            Thread.sleep(1000);  
        }catch (InterruptedException e){  
            e.printStackTrace();;  
        }  
    }  
}

自定义AsyncTask:

public class MyAsyncTask extends AsyncTask<Integer,Integer,String>  {  
    private TextView txt;  
    private ProgressBar pgbar;  
  
    public MyAsyncTask(TextView txt,ProgressBar pgbar)  {  
        super();  
        this.txt = txt;  
        this.pgbar = pgbar;  
    }  

    //该方法运行在UI线程中,可对UI控件进行设置  
    @Override  
    protected void onPreExecute() {  
        txt.setText("开始执行异步线程~");  
    }  
  
    //该方法不运行在UI线程中,主要用于异步操作,通过调用publishProgress()方法  
    //触发onProgressUpdate对UI进行操作  
    @Override  
    protected String doInBackground(Integer... params) {  
        DelayOperator dop = new DelayOperator();  
        int i = 0;  
        for (i = 10;i <= 100;i+=10)    {  
            dop.delay();  
            publishProgress(i);  
        }  
        return  i + params[0].intValue() + "";  
    }  

    //在doBackground方法中,每次调用publishProgress方法都会触发该方法  
    //运行在UI线程中,可对UI控件进行操作  
    @Override  
    protected void onProgressUpdate(Integer... values) {  
        int value = values[0];  
        pgbar.setProgress(value);  
    }  
    /**
     * 取消异步任务时触发该方法
     */
    @Override
    protected void onCancelled(String s) {
        super.onCancelled(s);
        // 在主线程(UI线程)
        // 取消异步任务时触发该方法

    }
}

MainActivity.java:

public class MyActivity extends ActionBarActivity {  
  
    private TextView txttitle;  
    private ProgressBar pgbar;  
    private Button btnupdate;  
  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  
        txttitle = (TextView)findViewById(R.id.txttitle);  
        pgbar = (ProgressBar)findViewById(R.id.pgbar);  
        btnupdate = (Button)findViewById(R.id.btnupdate);  
        btnupdate.setOnClickListener(new View.OnClickListener() {  
            @Override  
            public void onClick(View v) {  
                MyAsyncTask myTask = new MyAsyncTask(txttitle,pgbar);  
                myTask.execute(1000);  
            }  
        });  
    }  
} 

相关文章

  • Android-AsyncTask异步任务

    AsyncTask介绍Android的AsyncTask比Handler更轻量级一些,适用于简单的异步处理。首先明...

  • Android-AsyncTask[异步任务]

    AsyncTask是android提供的一个执行异步耗时工作并将结果返回主线程的类,内部通过线程池管理开启的子线程...

  • Android回顾--(八) 异步任务、Handler通信

    异步任务: 什么是异步任务?一切使用多线程完成的任务均可以称为异步任务-->使用线程来完成任务。 异步任务的优缺点...

  • 一次性能调优总结

    批量任务和异步任务,批量任务采用分发方式,批量任务生产异步任务。总的情况是批量任务的生产速度大于异步任务的消耗速度...

  • 异步任务

    需求: 同样的任务,启动多次,多个异步任务(比如3个)按照顺序(A,B,C)分别启动,只保留最后一个任务的结果。 ...

  • springboot之异步方法

    异步任务 Configuration配置: 需要@EnableAsync注解开启异步功能。spring异步任务是通...

  • java多线程(核心篇)第九章

    第九章 Java异步编程 9.1 同步计算与异步计算 以异步方式执行的任务,称之为异步任务,其任务的发起与任务的执...

  • js执行顺序总结

    流程图 首先执行同步任务,异步任务会插入到异步队列中。同步任务执行完毕,查询是否有异步任务,回到主任务执行。 微任...

  • 异步

    同步任务 && 异步任务 程序里面所有的任务,可以分成两类:同步任务(synchronous)和异步任务(asyn...

  • Android之异步、消息、通知、菜单

    异步、消息、通知、菜单 异步任务---AsyncTask 为什么要异步任务 Android单线程模型 耗时操作放在...

网友评论

      本文标题:Android-AsyncTask异步任务、

      本文链接:https://www.haomeiwen.com/subject/jmlquhtx.html