美文网首页Android学习日记
Android日记之AsyncTask的基本使用

Android日记之AsyncTask的基本使用

作者: 居居居居居居x | 来源:发表于2019-05-10 12:56 被阅读0次

前言

第一次写文章,记录下自己新手Android路上的开发点滴,之前学过AsyncTask基本使用,记录一下,要不然老是忘记。如有发现不对的地方也请多多指教。

正文

AsyncTask是什么?

AsyncTask就是异步处理的任务,它是Handler加上线程池的封装类,线程池可以维护数量,主要是可以避免不必要的创建和开销,AsyncTask必须要在实例的主线程中创建,它的回调方法,Android也会自动的去调用,注意的是,一个AsyncTask的实例,只能调用一次的excute方法。

AsyncTask的基本使用

首先AsyncTask是一个抽象类,用于被继承,而且要指定3个泛型参数,也可以3个都指定为空。

public class MyAsyncTask extends AsyncTask<Params,Progress,Result> {

    @Override
    protected Void doInBackground(Void... voids) {
        return null;
    }
}
//Parm:启动任务时输入参数的类型
//Progress:后台任务执行中返回的进度值
//Result:后台执行完成后返回结果的类型

构建 AsyncTaskd子类的回调方法。

  • doInBackground():必须重写,异步执行后台线程将要完成的任务。
  • onPreExecute():执行后台耗时操作前被调用,一般用来完成用户一些初始化操作。
  • onPostExecute():当doInBackground方法完成后,系统会自动调用,并且会将doInBackground返回的值传递给该方法。
  • onProgressUpdate():在doInBackground方法调用publishProgress方法后,更新任务的执行进度后,就会触发该方法。

代码如下:

package com.ju.synctask;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ImageView;
import android.widget.ProgressBar;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.net.URL;
import java.io.InputStream;
import java.net.URLConnection;

/**
 * 项目名: SyncTask
 * 包名 com.ju.synctask
 * 文件名: ImageTest
 * 创建日期:2019/4/1
 * 描述:图片加载测试类
 */
public class ImageTest extends AppCompatActivity {

    private static final String URL = "https://bmob-cdn-23214.b0.upaiyun.com/2019/03/30/9b72512c409fc6bd806acb50a7e7c748.jpg";
    private ImageView iv;
    private ProgressBar bar;


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

        iv = findViewById(R.id.iv);
        bar = findViewById(R.id.pro);

        MyAsyncTask myAsyncTask = new MyAsyncTask();
        myAsyncTask.execute(URL);
    }


    private class MyAsyncTask extends AsyncTask<String, Void, Bitmap> {


        @Override
        protected Bitmap doInBackground(String... strings) {
            //取出相应的参数值

            String url = strings[0];
            Bitmap bitmap = null;
            URLConnection connection;
            InputStream is;
            try {
                connection = new URL(url).openConnection();
                is = connection.getInputStream();//获取输入流
                BufferedInputStream bis = new BufferedInputStream(is);
                bitmap = BitmapFactory.decodeStream(bis);//将输入流解析成bitmap
                bis.close();
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

            return bitmap;
        }


        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            //初始化
            bar.setVisibility(View.VISIBLE);

        }

        @Override
        protected void onPostExecute(Bitmap bitmap) {
            super.onPostExecute(bitmap);
            //获取doInBackground的返回值,最后进行处理
            iv.setImageBitmap(bitmap);
            bar.setVisibility(View.GONE);
        }
    }

}

图片加载测试结果.png

模拟进度条测试

package com.ju.synctask;

import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ProgressBar;

public class PBActivity extends AppCompatActivity {


    private ProgressBar bar;
    PAsyncTask pAsyncTask;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_pbactiviity);
        bar = findViewById(R.id.progress);
        pAsyncTask = new PAsyncTask();
        pAsyncTask.execute();

    }



    private class PAsyncTask extends AsyncTask<Void, Integer, Void> {

        @Override
        protected Void doInBackground(Void... voids) {
            
            //通过for循环模拟进度条进度
            for (int i = 0; i < 100; i++) {
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                publishProgress(i);
            }
            return null;
        }


        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);
            bar.setProgress(values[0]);
        }
    }
}

进度条测试结果

但是你这样做发现了一个问题,如果点击返回的话然后再次进入会发现进度条不动了,这其实是因为上一次的进度条任务没有完成,AsyncTask的任务要进行排队,那要怎么解决了,很简单,可以让AsyncTask和Activity的生命周期保持一次。

在Activity的声明周期添加上这个

   @Override
    protected void onPause() {
        super.onPause();
        if (pAsyncTask != null && pAsyncTask.getStatus() == AsyncTask.Status.RUNNING) {
            pAsyncTask.cancel(true);
        }
    }

再一次跑起来,发现没什么卵用啊。其实,我们通过调用cancel调用的时候,并没有吧AsyncTask的线程给停止掉,我们只是给这个AsyncTask发送了一个cancel的请求,标记为cancel的状态而已。并不是真正的取消线程执行。我们需要在doInBackground()onProgressUpdate()添加一个isCancelled()判断,来进行停止AsyncTask,这样就可以停止掉了。

@Override
protected void onProgressUpdate(Integer... values) {
    super.onProgressUpdate(values);
    if (isCancelled()) {
        return;
    }
    bar.setProgress(values[0]);
}

总结

AsyncTask的基本使用方法就到此为止了,需要注意的一点是AsyncTask必须要在UI线程也就是主线程中进行创建,也必须在UI线程中调用excute方法,重写的那四个方法是自动调用的。每个AsyncTask只能被执行一次,多次调用有可能会出现异常。也不能在doInBackground()方法里面更新UI,一定要在onProgressUpdate里进行更新才行。

相关文章

网友评论

    本文标题:Android日记之AsyncTask的基本使用

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