AsyncTask的简单使用
为了更加方便对UI的操作,Android提供了AsyncTask,借助AsyncTask可以简单的从子线程切换到
主线程。
- 参数解释:
1、Params:这是一个任务参数,一般我们会定义成String类型的,例如要获取网络资源的URL地址
2、Progress:任务执行的刻度,一般我们会定义成Integer类型
3、Result:返回结果类型,本例为Integer - 需要实现的方法
1、onPreExecute:这是一个预处理方法,在任务开始的时候执行,我们可以在这里进行一些控件的实例化,设置属性等。
2、doInBackground:这是一个任务操作方法,也是最重要的一个方法,所有的耗时操作都应该在这里执行。不能再次方法中进行UI操作
3、onProgressUpdate:这是一个进度即时更新方法,在这里我们可以即时更新任务滚动条的进度, 当在doInBackground里调用publishProgress时触发。
4、onPostExecute:这是一个任务结果处理方法,在doInBackground里执行完任务,会将结果通知给这个类,在这类中我们可以对UI进行更新操作。 - 以上方法的执行顺序
onPreExecute–>doInBackground–>onProgressUpdate–>onPostExecute
- 样例:
布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
>
<Button
android:id="@+id/download"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="下载"
/>
</LinearLayout>
- MyAsyncTask继承AsyncTask
package com.example.downloading;
import android.app.ProgressDialog;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Environment;
import android.widget.ImageView;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class MyAsyncTask extends AsyncTask<String,Integer, Integer> {
private ProgressDialog progressDialog;
public MyAsyncTask(ProgressDialog progressDialog){
this.progressDialog = progressDialog;
}
// 进行界面的初始化操作,如进度条的显示
@Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog.setTitle("当前任务");
progressDialog.setMessage("正在下载图片,请稍等....");
// 设置进度条进度
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.show();
}
// 在这里处理耗时任务,任务完成后通过return语句返回任务执行的结果
@Override
protected Integer doInBackground(String... strings) {
InputStream is = null;
FileOutputStream outputStream = null;
try{
String downloadUrl = strings[0];
String name = downloadUrl.substring(downloadUrl.lastIndexOf("/"));
String fileName = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath();
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url(downloadUrl).build();
Response response = client.newCall(request).execute();
long filesize = response.body().contentLength();
is = response.body().byteStream();
byte[] arr = new byte[1024];
int len;
int total = 0;
outputStream = new FileOutputStream(fileName + name);
//可以在手机内存中的DownLoad文件下找到下载的东西
while((len = is.read(arr)) != -1) {
outputStream.write(arr, 0, len);
total += len;
int values = (int) ((total / (float) filesize) * 100);
publishProgress(values); //调用此方法将下载进度传进来,这样就会调用onProgressUpdate()方法,进行UI操作
}
response.body().close();
}catch (Exception e){
e.printStackTrace();
}finally {
try {
if(outputStream != null){
outputStream.close();
}
if(is != null){
is.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
return 1;
}
// 实时UI更新操作,被UI线程所调用 在这里可以即时更新(如进度条进度)
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
progressDialog.setProgress(values[0]);
}
//在这里会返回doInBackground的操作结果,被UI线程调用,更新最后UI结果,执行任务的收尾工作
@Override
protected void onPostExecute(Integer integer) {
super.onPostExecute(integer);
progressDialog.dismiss();
}
}
MainActivity
package com.example.downloading;
import androidx.appcompat.app.AppCompatActivity;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
public class MainActivity extends AppCompatActivity {
ProgressDialog progressDialog;
ImageView imageView;
Button download;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
download = findViewById(R.id.download);
progressDialog = new ProgressDialog(this);
//这里的path随自己的需求而改变,这里放的是一张图片的地址
final String path = "http://y.gtimg.cn/music/photo_new/T002R180x180M000003c616O2Zlswm.jpg";
download.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
MyAsyncTask myAsyncTask = new MyAsyncTask(progressDialog);
myAsyncTask.execute(path);
}
});
}
}
- 注意,在我自己手机上运行时需要添加:
android:usesCleartextTraffic="true"
添加权限:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
还需要自己手动在手机的设置上面开启存储权限