AsyncTask异步任务【AsyncTask下载Demo】

AsyncTask异步任务概述

异步任务:可理解为同时进行的事情,相当于有多个线程。【边看电视边吃饭】

实质:Handler异步消息处理机制

AsyncTask was intended to enable proper and easy use of the UI thread. AsyncTask旨在启用和轻松使用UI线程。

多线程

ANR (Application Not Responding): 应用程序无响应

UI线程被卡住,比如你在做请求网络、下载音乐等,会引起ANR,这是就要新建一个线程里处理这些耗时的操作。

AsyncTask中常用方法

onPreExecute(): 执行前

/**
 * 在异步任务之前,在主线程中:可操作UI
 * */
@Override
protected void onPreExecute() {
    super.onPreExecute();
    //可操作UI
}

doInBackground(): 执行中

/**
 * 在另一个线程中处理事件,耗时操作
 * @param strings 入参
 * @return  结果
 * */
@Override
protected Boolean doInBackground(String... strings) {

    return null;
}

onPostExecute(): 执行后

//会将doInBackground()的结果返回给onPostExecute(),然后对该结果进行处理
//在主线程中,处理执行结果
@Override
protected void onPostExecute(Boolean aBoolean) {
    super.onPostExecute(aBoolean);


}

onProgressUpdate(): 进度变化

//进度在变化的时候  会执行这个方法
//参数为泛型中的第二个Integer
//在doInBackground()可调用 publishProgress()方法来抛出进度
@Override
protected void onProgressUpdate(Integer... values) {
    super.onProgressUpdate(values);
    //处理收到的进度,在UI线程,主线程中
}

onCancelled(): 取消操作

//带参数的取消方法参数为 doInBackground()中的result
@Override
protected void onCancelled(Boolean aBoolean) {
    super.onCancelled(aBoolean);
}

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

AsyncTask实例——下载任务

Step 1 网络请求数据:申请网络权限,读写存储权限

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

Step 2 创建布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".DownloadHandlerActivity">

    <ProgressBar
        android:id="@+id/progressBar_async"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:max="100"
        tools:layout_editor_absoluteX="208dp"
        tools:layout_editor_absoluteY="201dp" />

    <Button
        android:id="@+id/button_async"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="点击下载"
        android:layout_marginBottom="10dp"
        tools:layout_editor_absoluteX="179dp"
        tools:layout_editor_absoluteY="96dp" />

    <TextView
        android:id="@+id/textView_async"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="26sp"
        />



</LinearLayout>

Step 3 准备事件:初始化数据

public static final int INIT_PROGRESS = 0;
private Button mDownloadButton ;
private TextView mResultTextView;
private ProgressBar mProgressBar;

private static final String TAG = "AsyncActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_async);
    
    //初始化视图
    initViews();
    //设置监听器
    setListeners();

    //初始化UI数据
    setData();


}

/**
 * 初始化视图
 * */
private void initViews() {

  mDownloadButton = findViewById(R.id.button_async);
  mProgressBar = findViewById(R.id.progressBar_async);
  mResultTextView = findViewById(R.id.textView_async);
}

/**
 * 设置监听器
 * */
private void setListeners() {
    mDownloadButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // TODO: 2020/5/17 下载任务

        }
    });
}

/**
 * 初始化UI数据
 * */
private void setData() {
    mProgressBar.setProgress(INIT_PROGRESS);
    mDownloadButton.setText(R.string.click_download_btn);
    mResultTextView.setText(R.string.prepare_download_txt);

}
...
    
    
}

Step 4 下载之前要做的事情【UI线程 主线程】

/**
 * 在异步任务之前,在主线程中:可操作UI
 * */
@Override
protected void onPreExecute() {
    super.onPreExecute();
    //可操作UI, 类似淘米,准备工作
    mDownloadButton.setText(R.string.downloading);
    mResultTextView.setText(R.string.downloading);
    mProgressBar.setProgress(INIT_PROGRESS);
    
}

Step 5 下载中要做的事情 【子线程 处理耗时任务】

/**
 * 在另一个线程中处理事件,耗时操作
 * @param strings 入参 煮米
 *                String...表示可变的String,  可以有1个String 2个String ...多个String
 * @return  结果
 * */
@Override
protected Boolean doInBackground(String... strings) {

    // TODO: 2020/5/17 下载过程

    if(strings!=null && strings.length > 0){
        String apkUrl = strings[0];
        try {
            //构造URL
            URL  url = new URL(apkUrl);
            //构造链接
            URLConnection  urlConnection = url.openConnection();
            //创建输入流
            InputStream inputStream = urlConnection.getInputStream();
            //获取文件的总长度
            int contentLength = urlConnection.getContentLength();
            //下载地址准备   File.separator表示 : /
             downloadFileName = getExternalFilesDir(null)
                    + File.separator + "imooc" +File.separator+ FILE_NAME ;

            Log.d(TAG,downloadFileName);
            //对下载地址进行处理
            File  apkFile = new File(downloadFileName);
            if(!apkFile.exists()){

                boolean result = apkFile.delete();
                if(!result){
                    return  false;
                }
             //   file.mkdir();
            }

            //获取下载时的长度
            int downloadSize = 0;

            //创建字节数组
            byte[] bytes = new byte[1024];
            int length = 0;
            //创建输出流:一个输出管道
            OutputStream outputStream = new FileOutputStream(downloadFileName);

            //不断地一车一车挖土,直到挖不到为止
            while (( length = inputStream.read(bytes))!= -1){
                //挖到地放到我们的文件管道里
                outputStream.write(bytes,0,length);
                //累加下载时的大小
                downloadSize += length;

                // TODO: 2020/5/17 抛出进度
                publishProgress(downloadSize*100 /contentLength);

            }

            inputStream.close();
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
            return  false;
        }
    }else {
        return  false;
    }
    return true;
}

Step 6 下载后以及进度条的处理

@Override
protected void onPostExecute(Boolean result) {
    super.onPostExecute(result);
    // TODO: 2020/5/17 下载后的处理
    mDownloadButton.setText(result?getString(R.string.download_success):getString(R.string.download_fail));
    mResultTextView.setText(result? getString(R.string.download_success)+ ":" +downloadFileName :getString(R.string.download_fail));


}

//进度在变化的时候  会执行这个方法
//参数为泛型中的第二个Integer
//在doInBackground()可调用 publishProgress()方法来抛出进度
@Override
protected void onProgressUpdate(Integer... values) {
    super.onProgressUpdate(values);
    //处理收到的进度,在UI线程,主线程中
    if(values!=null && values.length>0){
        mProgressBar.setProgress(values[0]);

    }
}

结果展示

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值