android AsyncTask

AsyncTask 使用

参考:

AsyncTaskhttps://developer.android.com/reference/android/os/AsyncTask.html


AsyncTask 是一个轻量级的线程框架,封装了 ThreadHandler 的执行细节,方便使用。


AsyncTask 是一个抽象类,需要继承使用

AsyncTask 有3个泛型类型参数:ParamsProgressResult,以及四个基本的步骤:onPreExecutedoInBackgroundonProgressUpdateonPostExecute

其子类必须 重载至少一个方法doInBackground(Params...) - 这个是抽象方法 ),通常也会重载另一个方法(onPostExecute(Result))。


下面介绍一下3个泛型参数的含义:

  1. Params:发送给后台执行任务的参数类型(the type of the parameters sent to the task upon execution);
  2. Progress:后台计算过程中的进度单位类型(the type of the progress units published during the background computation);
  3. Result:后台计算结果类型(the type of the result of the background computation)。

注:如果不使用参数,可以用 void 代替,比如:

private class MyTask extends AsyncTask<Void, Void, Void> {...}

以及四个基本步骤(其执行顺序从上到下):

  1. onPreExecute():在任务被执行时在 UI线程 调用。这个方法通常用于任务执行前的一些工作,比如显示一个进度条;
  2. doInBackground(Params...):当 onPreExecute() 结束后调用,运行在 后台线程 中,计算的任务应该放在这个方法中运行。参数 Params 会被输入到这个方法中,同时,该方法计算得出的结果将会作为参数 Result 输入到 OnPostExecute(Result) 中 。如果在这个方法中调用 publishProgress(Progress...) 方法,则会同步调用函数 onProgressUpdate(Progress...)
  3. onProgressUpdate(Progress...):在 UI线程 中执行,当 onInBackground(Params...) 中调用了函数 publishProgress(Progress...) ,才会同步调用这个函数,可以用于显示后台线程的计算进度;
  4. onPostExecute(Result):在 UI线程 中调用,当后台任务结束后执行。后台任务计算的结果会作为参数输入到这个。

主要内容:

  1. 实现四个基本方法
  2. 如何取消任务
  3. 运行规则
  4. 多线程的执行顺序(同步或异步)

实现四个基本方法

简单工程:显示方法的执行顺序

MyTask.java 代码:

package com.uniview.asynctasktest;

import android.os.AsyncTask;
import android.util.Log;

import java.util.Arrays;

/**
 * Created by Lenovo on 2017/3/1.
 */

public class MyTask extends AsyncTask<Void, Integer, Void> {

    private static final String TAG = MyTask.class.getSimpleName();

    @Override
    protected void onPreExecute() {
        super.onPreExecute();

        Log.e(TAG, "onPreExecute: ");
    }

    @Override
    protected Void doInBackground(Void... params) {
        Log.e(TAG, "doInBackground: ");

        int values[] = new int[]{1, 2, 3, 4, 5};
        for (int i = 0; i < values.length; i++) {
            Integer[] temp = new Integer[5];
            temp[i] = Integer.valueOf(values[i]);

            publishProgress(temp);
        }

        return null;
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        Log.e(TAG, "onProgressUpdate: ");
        super.onProgressUpdate(values);

        Log.e(TAG, "onProgressUpdate: values = " + Arrays.toString(values));
    }

    @Override
    protected void onPostExecute(Void aVoid) {
        super.onPostExecute(aVoid);

        Log.e(TAG, "onPostExecute: ");
    }
}

MainActivity.java 代码:

package com.example.asynctasktest;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        new Task().execute();
    }
}

运行结果如下:


如何取消任务

使用函数 task.cancel(true); 可以取消该任务

如果使用此函数,task 将结束 doInbackground 函数,然后调用 onCancelled() 函数

想要查询是否任务已取消,可以使用方法 isCancelled()


运行规则

  • AsyncTask 类必须在 UI 线程内加载;
  • 任务实例必须在 UI 线程内创建;
  • 必须在 UI 线程内执行任务;
  • 不需要手动调用 onPreExecute(), onPostExecute(Result), doInBackground(Params...), onProgressUpdate(Progress...)
  • 一个任务实例仅能被执行一次,如果再次执行,将会抛出异常。

多线程的执行顺序

When first introduced, AsyncTasks were executed serially on a single background thread. Starting with DONUT, this was changed to a pool of threads allowing multiple tasks to operate in parallel. Starting with HONEYCOMB, tasks are executed on a single thread to avoid common application errors caused by parallel execution.

最开始的多个 AsyncTask 将会按顺序执行; 从 android 1.6 开始,多线程池将会并行运行,但这可能会造成一些错误;从 android 3.0 开始,多个 AsyncTask 任务将重新按顺序执行,以防止应用错误。

If you truly want parallel execution, you can invoke executeOnExecutor(java.util.concurrent.Executor, Object[]) with THREAD_POOL_EXECUTOR.

如果你想要并行执行,可以调用函数 executeOnExecutor

修改 MyTask.java:

package com.uniview.asynctasktest;

import android.os.AsyncTask;
import android.util.Log;

import java.util.Arrays;

/**
 * Created by Lenovo on 2017/3/1.
 */

public class MyTask extends AsyncTask<Void, Integer, Void> {

    private static final String TAG = MyTask.class.getSimpleName();

    @Override
    protected Void doInBackground(Void... params) {
        Log.e(TAG, "doInBackground: ");

        int values[] = new int[]{1, 2, 3};
        for (int i = 0; i < values.length; i++) {
            Integer[] temp = new Integer[3];
            temp[i] = Integer.valueOf(values[i]);

            publishProgress(temp);

            try {
                Thread.sleep(i * 1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        return null;
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        Log.e(TAG, "onProgressUpdate: ");
        super.onProgressUpdate(values);

        Log.e(TAG, "onProgressUpdate: values = " + Arrays.toString(values));
    }

    @Override
    protected void onPostExecute(Void aVoid) {
        super.onPostExecute(aVoid);

        Log.e(TAG, "onPostExecute: ");
    }
}

修改 MainActivity.java按顺序执行 线程:

package com.uniview.asynctasktest;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

import static android.os.AsyncTask.THREAD_POOL_EXECUTOR;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        MyTask task = new MyTask();
        MyTask task2 = new MyTask();

        task.execute();
        task2.execute();

//        task.executeOnExecutor(THREAD_POOL_EXECUTOR);
//        task2.executeOnExecutor(THREAD_POOL_EXECUTOR);
    }
}

运行结果:

修改 MainActivity.java同步执行 线程:

        ...
//        task.execute();
//        task2.execute();

        task.executeOnExecutor(THREAD_POOL_EXECUTOR);
        task2.executeOnExecutor(THREAD_POOL_EXECUTOR);
        ...

运行结果:

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值