AsyncTask 实例简介
  HvTJUzsxOBtS 2023年11月25日 20 0



文章目录

  • 1、简介
  • 2、示例模板
  • 3、实例讲解
  • 1) AsncTask 生命周期
  • 2) 内存泄漏 静态内部类 + 弱引用
  • 3)多个AsyncTask 实例 同步还是异步进行
  • 4)线程任务执行结果 丢失
  • 5)优缺点


1、简介

作用同 Thread + handler 类似,用于开启线程做一些耗时操作,同时有接口实现ui更新。
但是效率,比我们自己使用thread + handler 要高。Aysnctsk,内部封装了一个线程池,用来执行线程操作。一个进程中 AsyncTask 对象公用同一个线程池。

2、示例模板

我们模拟 网络下载 ,同时更新下载进度的 ,下载完成通知这一个基本框架。

AsyncTask 实例简介_android


主功能代码:

package myapplication.lum.com.myasynctask;

import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    private String  TAG = "MainActivity: ";
    private TextView tv_text;
    private Button button;
    MyAsyncTask task ;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv_text = (TextView) findViewById(R.id.tv_text_id);
        button = (Button) findViewById(R.id.bt_id);

        task = new  MyAsyncTask();
    }


    public void onClick(View view) {
        switch (view.getId()){
            case R.id.bt_id:
                //执行
                task.execute("www.baidu.com");
                Log.i(TAG,"点击下载");
                break;
            case R.id.bt_can_id:
                task.cancel(true);
                Log.i(TAG,"取消按钮");
                break;
        }

    }

    class MyAsyncTask extends AsyncTask<String,Integer, String> {
        /**
         * 被主线程执行,在doInBackground函数前执行
         * */
        @Override
        protected void onPreExecute() {
            // 弹加载对话框
            Log.d(TAG, "onPreExecute ");
        }

        /**
         * 被子线程执行,用来处理耗时行为
         * */
        @Override
        protected String doInBackground(String... params) {
            Log.d(TAG, "doInBackground: "+ params[0]);
            for(int i=1;i<=10;i++){
                try {
                    Thread.sleep(1000);
                    //推送当前的进度
                    publishProgress(i);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
            return "下载完成";
        }


        @Override
        protected void onProgressUpdate(Integer... values) {
            //更新UI上的进度
            tv_text.setText(values[0]+"");
        }
        /**
         * 被主线程执行,在doInBackground函数后执行
         * */
        @Override
        protected void onPostExecute(String result) {
            Log.d(TAG, "onPostExecute");
            // 更UI数据
            tv_text.setText(result);
        }
       // onCancelled()
        // 作用:将异步任务设置为:取消状态
        @Override
        protected void onCancelled() {
        Log.i(TAG,"onCancelled task");
        tv_text.setText("下载已经取消");
        }
    }
}
3、实例讲解
1) AsncTask 生命周期

AsncTask 不与任何组件绑定生命周期,在Activity 、Fragment中使用的时候,最好在 onDestory() 中主动调用 myTask.cancel(true);

2) 内存泄漏 静态内部类 + 弱引用

若 AsyncTask 被声明为 Activity的非静态内部类,当activity需销毁的时候,会因为AsyncTask 保留对Activity的引用而导致Activity无法被回收,最终引起内存泄漏。建议 AsyncTask应被声明为Activity的静态内部类。

采用弱引用示例

package myapplication.lum.com.myasynctask;

import android.app.Activity;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import java.lang.ref.WeakReference;

public class MainActivity extends AppCompatActivity {

    private String  TAG = "MainActivity: ";
    private TextView tv_text;
    private Button button;
    MyAsyncTask task ;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv_text = (TextView) findViewById(R.id.tv_text_id);
        button = (Button) findViewById(R.id.bt_id);

        task = new  MyAsyncTask(this);
    }


    public void onClick(View view) {
        switch (view.getId()){
            case R.id.bt_id:
                //执行
                task.execute("www.baidu.com");
                Log.i(TAG,"点击下载");
                break;
            case R.id.bt_can_id:
                task.cancel(true);
                Log.i(TAG,"取消按钮");
                break;
        }

    }


     static class MyAsyncTask extends AsyncTask<String,Integer, String> {
         private WeakReference<Activity> weakAty;
         private String  TAG = "MyAsyncTask: ";

         public MyAsyncTask(Activity activity){
             weakAty = new WeakReference<Activity>(activity);
         }
        /**
         * 被主线程执行,在doInBackground函数前执行
         * */
        @Override
        protected void onPreExecute() {
            // 弹加载对话框
            Log.d(TAG, "onPreExecute ");
        }

        /**
         * 被子线程执行,用来处理耗时行为
         * */
        @Override
        protected String doInBackground(String... params) {
            Log.d(TAG, "doInBackground: "+ params[0]);
            for(int i=1;i<=10;i++){
                try {
                    Thread.sleep(1000);
                    //推送当前的进度
                    publishProgress(i);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
            return "下载完成";
        }


        // onCancelled()
        // 作用:将异步任务设置为:取消状态
        @Override
        protected void onCancelled() {
        Log.i(TAG,"onCancelled task");
            MainActivity mainActivity ;
            if((mainActivity = (MainActivity) weakAty.get())!=null){
                // 更UI数据
                mainActivity.tv_text.setText("下载已经取消");
            }
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            //更新UI上的进度
            MainActivity mainActivity ;
            if((mainActivity = (MainActivity) weakAty.get())!=null){
                // 更UI数据
                mainActivity.tv_text.setText(values[0]+"");
            }
        }
        /**
         * 被主线程执行,在doInBackground函数后执行
         * */
        @Override
        protected void onPostExecute(String result) {
            Log.d(TAG, "onPostExecute");
            MainActivity mainActivity ;
            if((mainActivity = (MainActivity) weakAty.get())!=null){
                // 更UI数据
                mainActivity.tv_text.setText(result);
            }

        }
    }
}
3)多个AsyncTask 实例 同步还是异步进行

两个实例
task_one
task_two

(1)

task_one.execute(urls);//第一个实例执行
task_two.execute(urls);//第二个实例执行

这种执行方法 ,那么 task_one ,task_two 是同步执行的,会在线程先执行 task_one ,然后结束后再执行 task_two

(2)

task_one.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,urls);//第一个实例执行
task_two.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,urls);//第二个实例执行

第一个参数是一个Executor线程池对象,为了让AsyncTask并行处理任务。通常情况下我们此处传入AsyncTask.THREAD_POOL_EXECUTOR即可。
第二个参数params表示的是要执行的任务的参数。

这种方法是同时开启两个线程并行执行的。

4)线程任务执行结果 丢失

当Activity重新创建时(屏幕旋转 / Activity被意外销毁时后恢复),之前运行的AsyncTask(非静态的内部类)持有的之前Activity引用已无效,故复写的onPostExecute()将不生效,即无法更新UI操作。

在Activity恢复时的对应方法 重启 任务线程。

5)优缺点

优点:
简单,快捷
过程可控
使用的缺点:
对只需要几秒内的线程操作方便

缺点:
在使用多个异步操作和并需要进行Ui变更时,就变得复杂起来.


【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月25日 0

暂无评论

推荐阅读
  anLrwkgbyYZS   2023年12月30日   32   0   0 ideciciMaxideMax
HvTJUzsxOBtS