搜索
您的当前位置:首页正文

AsyncTask异步任务

来源:易榕旅网

android中实现异步机制的方法有两种,Handler和AsyncTask。

Handler在使用时,需要新开辟一个线程,在任务完成以后,通过sendmessage()等方法通知UI线程进行界面更新。

相比起Handler,AsyncTask显得更加简单,内部封装了线程池、线程和Handler。

我们通常是继承AsyncTask并重写其中的方法:

public abstract class AsyncTask<Params, Progress, Result> {

三种泛型类型分别代表“启动任务执行的输入参数”、“后台任务执行的进度”、“后台计算结果的类型”。

分别是在:

    @WorkerThread
    protected abstract Result doInBackground(Params... params);
    @MainThread
    protected void onProgressUpdate(Progress... values) {

中用到了Params和progress,Result则是用作返回值。

相关方法和执行过程:

继承AsyncTask,必须重写doInBackground()方法;

在使用AsyncTask时要注意以下事项:

  1. 任务实例必须在UI线程中创建。
  2. execute(Params... params)方法必须在UI线程中调用。
  3. 不要手动调用onPreExecute(),doInBackground(Params... params),onProgressUpdate(Progress... values),onPostExecute(Result result)这几个方法。
  4. 不能在doInBackground(Params... params)中更改UI组件的信息。
  5. 一个任务实例只能执行一次,如果执行第二次将会抛出异常。
  6. 调用cancel(true)并不能停止线程,只是给task一个取消的状态,具体的取消操作需要在doInBackground方法中用isCancelled()方法进行判断处理 

下面写一个例子以免以后忘记,例子用于打印一段话的长度,在DoInBackground中调用Thread.sleep(),模拟耗时操作:

<string name="async_task_text_1">一个简单小例子,主要功能是,统计本段话的所有字符的长度。
        为了模拟耗时操作,在doInBackground方法里让Thread睡一会。</string>
public class AsyncTaskActivity extends AppCompatActivity implements View.OnClickListener {

    private TextView mTextView1;
    private ProgressBar mProgressBar;
    private TextView mTextView2;
    private Button mButton;
    private Button mButton2;

    private MyTask mMyTask;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_async_task);
        initView();
        initData();
    }

    private void initView() {
        mTextView1 = findViewById(R.id.textView1);
        mTextView2 = findViewById(R.id.textView2);
        mProgressBar = findViewById(R.id.progressBar);
        mButton = findViewById(R.id.button);
        mButton2 = findViewById(R.id.button2);

        mButton.setOnClickListener(this);
        mButton2.setOnClickListener(this);
    }

    private void initData() {

    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.button:
                mMyTask = new MyTask(this);
                mMyTask.execute(getResources().getString(R.string.async_task_text_1));
                break;
            case R.id.button2:
                if (mMyTask != null) {
                    mMyTask.cancel(true);
                    mMyTask = null;
                }
                break;
            default:
                break;
        }
    }

    static class MyTask extends AsyncTask<String, Float, Long> {

        WeakReference<AsyncTaskActivity> mWeakReference;
        int length;

        public MyTask(AsyncTaskActivity activity) {
            mWeakReference = new WeakReference<>(activity);
        }

        /**
         * 执行线程任务前的操作
         */
        @Override
        protected void onPreExecute() {
            AsyncTaskActivity activity = mWeakReference.get();
            length = activity.getApplicationContext().getResources().getString(R.string.async_task_text_1).length();
            activity.mTextView1.setText(activity.getApplicationContext().getResources().getString(R.string.async_task_text_1));
            activity.mProgressBar.setMax(length);
        }

        @Override
        protected Long doInBackground(String... strings) {
            for (int i = 0; i < length; i++) {
                if (!isCancelled()) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                } else {
                    break;
                }
                publishProgress((float) i);
            }
            return (long) length;
        }

        @Override
        protected void onProgressUpdate(Float... values) {
            AsyncTaskActivity activity = mWeakReference.get();
            if (activity == null || activity.isFinishing()) {
                return;
            }
            activity.mProgressBar.setProgress(Math.round(values[0]));
            activity.mTextView2.setText("onProgress = " + values[0] * 1.0f / length);
        }

        @Override
        protected void onPostExecute(Long aLong) {
            AsyncTaskActivity activity = mWeakReference.get();
            if (activity == null || activity.isFinishing()) {
                return;
            }
            activity.mProgressBar.setProgress(activity.mProgressBar.getMax());
            activity.mTextView2.setText("完成了,这段话一共有 " + aLong + " 个字。");
        }

        @Override
        protected void onCancelled(Long aLong) {
            AsyncTaskActivity activity = mWeakReference.get();
            if (activity == null || activity.isFinishing()) {
                return;
            }
            activity.mTextView2.setText("已取消");
        }

        @Override
        protected void onCancelled() {
            super.onCancelled();
        }
    }
}

这里使用静态内部类+外部类的弱引用方式避免内存泄漏。

因篇幅问题不能全部显示,请点此查看更多更全内容

Top