同时进行即为异步
1.目的:方便后台线程中操作后更新UI
2.实现:用Thread和Handler进行了封装
3.实质:Handler异步消息处理机制
泛型参数<Params,Progress,Result>
UI操作onPreExecute onPostExecute
后台线程操作doInBackground
输入输出Params,Result
进度显示 onProgressUpdate
package com.example.asynctaskproject;
import androidx.appcompat.app.AppCompatActivity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DownloadAsyncTask downloadAsyncTask=new DownloadAsyncTask();
downloadAsyncTask.execute("imooc","good");
}
public class DownloadAsyncTask extends AsyncTask<String ,Integer,Boolean>{
/**
* 在异步任务前,主线程中
* */
@Override
protected void onPreExecute() {
super.onPreExecute();
//可操作UI
}
/**
* 在另外一个线程处理事件
* String... strings就是入参
* return 结果
* */
@Override
protected Boolean doInBackground(String... strings) {
for (int i = 0; i < 100; i++) {
Log.i(TAG,"DownloadAsyncTask"+strings[0]+strings[1]);
//抛出进度
publishProgress(i);
}
return true;
}
//
@Override
protected void onPostExecute(Boolean aBoolean) {
super.onPostExecute(aBoolean);
//主线程中 执行结果 处理
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
//收到进度然后处理也是在UI线程
}
@Override
protected void onCancelled() {
super.onCancelled();
//取消
}
@Override
protected void onCancelled(Boolean aBoolean) {
super.onCancelled(aBoolean);//结果参数
//取消
}
}
}
主要方法有四个
onPreExecute()操作前的准备工作
doOnBackground()耗时操作(唯一的异步线程)
onProgressUpdate()收到进度然后处理也是在UI线程
onPostExecute()执行结果更新Ui显示
下载demo
package com.example.asynctaskproject;
import androidx.appcompat.app.AppCompatActivity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private Button button;
private TextView textView;
private ProgressBar mProgressBar;
private int INIT_PROGRESS =0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//初始化视图
initView();
//设置监听
setListener();
//初始化UI数据
setData();
}
private void setData() {
mProgressBar.setProgress(INIT_PROGRESS );
button.setText("点击下载");
textView.setText("准备下载");
}
private void setListener() {
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//下载的事情
}
});
}
/**
初始化视图
*/
private void initView() {
button = findViewById(R.id.button2);
textView = findViewById(R.id.textView2);
}
public class DownloadAsyncTask extends AsyncTask<String ,Integer,Boolean>{
private boolean result;
private String mFilePath;
/**
* 在异步任务前,主线程中
* */
@Override
protected void onPreExecute() {
super.onPreExecute();
//可操作UI
}
/**
* 在另外一个线程处理事件
* String... strings就是入参
* return 结果
* */
@Override
protected Boolean doInBackground(String... strings) {
for (int i = 0; i < 100; i++) {
Log.i(TAG,"DownloadAsyncTask"+strings[0]+strings[1]);
//抛出进度
publishProgress(i);
try {
URL url=new URL("lianjie");
//构造连接,并打开
URLConnection urlConnection=url.openConnection();
InputStream inputStream=urlConnection.getInputStream();
//获得文件总长度用于更新进度条
int contentLength=urlConnection.getContentLength();
//下载地址准备
mFilePath = Environment.getExternalStorageDirectory()+ File.separator+"imooc.apk";
//对下载地址处理
File apkFile=new File(mFilePath);
if (apkFile.exists()){
result = apkFile.delete();
if (!result){
return false;
}
}
//已下载的大小
int downSize=0;
int length;
byte []bytes=new byte[1024];
//创建输出流
OutputStream outputStream=new FileOutputStream(mFilePath);
while ((length=inputStream.read(bytes))!=-1){
//数据放到文件管道里
outputStream.write(bytes,0,length);
downSize+=length;
//发送进度
publishProgress(downSize*100/contentLength);
}
inputStream.close();
outputStream.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
return true;
}
//
@Override
protected void onPostExecute(Boolean aBoolean) {
super.onPostExecute(aBoolean);
//主线程中 执行结果 处理
textView.setText("下载完成");
textView.setText(result?"下载完成":mFilePath+"下载失败");
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
//收到进度然后处理也是在UI线程
if (values!=null&&values.length>0)
mProgressBar.setProgress(values[0]);
}
@Override
protected void onCancelled() {
super.onCancelled();
//取消
}
@Override
protected void onCancelled(Boolean aBoolean) {
super.onCancelled(aBoolean);//结果参数
//取消
}
}
}
封装思想
package com.example.asynctaskproject;
import android.os.AsyncTask;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
/**
* 1. download方法 url localPath listener
* 2. listener: start, success fail progress.
* 3. 用asynctask封装的
* Created by renkangke on 16/12/19.
*/
public class DownHelper {
public static void download(String url, String localPath, OnDownloadListener listener){
DownloadAsyncTask task = new DownloadAsyncTask(url, localPath, listener);
task.execute();
}
public static class DownloadAsyncTask extends AsyncTask<String, Integer, Boolean> {
String mUrl;
String mFilePath;
OnDownloadListener mListener;
public DownloadAsyncTask(String url, String filePath, OnDownloadListener listener) {
mUrl = url;
mFilePath = filePath;
mListener = listener;
}
/**
* 在异步任务之前,在主线程中
*/
@Override
protected void onPreExecute() {
super.onPreExecute();
// 可操作UI 类似淘米,之前的准备工作
if(mListener != null){
mListener.onStart();
}
}
/**
* 在另外一个线程中处理事件
*
* @param params 入参 煮米
* @return 结果
*/
@Override
protected Boolean doInBackground(String... params) {
String apkUrl = mUrl;
try {
// 构造URL
URL url = new URL(apkUrl);
// 构造连接,并打开
URLConnection urlConnection = url.openConnection();
InputStream inputStream = urlConnection.getInputStream();
// 获取了下载内容的总长度
int contentLength = urlConnection.getContentLength();
// 对下载地址进行处理
File apkFile = new File(mFilePath);
if(apkFile.exists()){
boolean result = apkFile.delete();
if(!result){
if(mListener != null){
mListener.onFail(-1, apkFile, "文件删除失败");
}
return false;
}
}
// 已下载的大小
int downloadSize = 0;
// byte数组
byte[] bytes = new byte[1024];
int length;
// 创建一个输入管道
OutputStream outputStream = new FileOutputStream(mFilePath);
// 不断的一车一车挖土,走到挖不到为止
while ((length = inputStream.read(bytes)) != -1){
// 挖到的放到我们的文件管道里
outputStream.write(bytes, 0, length);
// 累加我们的大小
downloadSize += length;
// 发送进度
publishProgress(downloadSize * 100/contentLength);
}
inputStream.close();
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
if(mListener != null){
mListener.onFail(-2, new File(mFilePath), e.getMessage());
}
return false;
}
if(mListener != null){
mListener.onSuccess(0, new File(mFilePath));
}
return true;
}
@Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
// 也是在主线程中 ,执行结果 处理
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
// 收到进度,然后处理: 也是在UI线程中。
if (values != null && values.length > 0) {
if(mListener != null){
mListener.onProgress(values[0]);
}
}
}
}
public interface OnDownloadListener{
void onStart();
void onSuccess(int code, File file);
void onFail(int code , File file, String message);
void onProgress(int progress);
abstract class SimpleDownloadListener implements OnDownloadListener{
@Override
public void onStart() {
}
@Override
public void onProgress(int progress) {
}
}
}
}
使用封装
DownHelper.download(APK_URL, "lujing", new DownHelper.OnDownloadListener.SimpleDownloadListener() {
@Override
public void onSuccess(int code, File file) {
}
@Override
public void onFail(int code, File file, String message) {
}
@Override
public void onStart() {
super.onStart();
}
@Override
public void onProgress(int progress) {
super.onProgress(progress);
}
});