异步任务AsyncTask的使用率在android开发中非常广,是thread和handler的包装类。本人也是在学习android的路上,今天学习了AsyncTask,想写个小例子来记住今天学习的内容。
先来看看AsynTask类的泛型,泛型里面有3个参数,第一个传入数据的数据类型,第二个是更新数据的数据类型,第三个是异步线程传出数据的数据类型。
AsynTask类必须要重写的方法是doInBackground()方法,执行异步线程,耗时操作就在里面完成.
还有一些主要用到的方法:
1.onPreExecute()方法:耗时操作进行前执行的方法,在主线程中进行,用于UI界面的更新。
2.onPostExecute()方法:耗时任务完成后执行的方法,在主线程中进行,用于UI界面的更新。
3.publishProgress()方法:用于耗时操作中,更新数据的传出。
4.onProgressUpdate()方法:用于更新数据,接收从publishProgress()方法传来的数据,在主线程中进行,通知UI界面 进行更新。
5.cancel()方法:用于结束耗时操作。
以下载APP为例,实现异步任务,并实时更新数据。
首先简单的下载布局
<?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:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.administrator.five_two_three.Main2Activity">
<ProgressBar
style="?android:attr/progressBarStyleHorizontal"
android:id="@+id/progressbar"
android:layout_marginTop="20dp"
android:layout_width="match_parent"
android:layout_height="15dp"
android:progress="0"
android:background="#3366ff"
/>
<Button
android:id="@+id/btn_download"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="下载"/>
<TextView
android:id="@+id/content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="准备下载"/>
<Button
android:id="@+id/btn_"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
布局内容
实现异步下载的代码
package com.example.administrator.five_two_three;
import android.Manifest;
import android.os.AsyncTask;
import android.os.Environment;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import java.io.ByteArrayOutputStream;
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 Main2Activity extends AppCompatActivity {
protected ProgressBar progressBar;
protected Button btn;
protected TextView textView;
protected Masynctask masynctask;
public static final String URL_HTTP="https://www.imooc.com/mobile/mukewang.apk";
public static final String DOWNLOADPROCESS="下载中";
public static final String APK_NAME="MOOC.apk";
private String stroge;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
initview();
setPermission();
setListern();
}
private void initview() {
progressBar=findViewById(R.id.progressbar);
btn=findViewById(R.id.btn_download);
textView=findViewById(R.id.content);
}
private void setListern() {
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
masynctask=new Masynctask( );
masynctask.execute(URL_HTTP);
}
});
}
public class Masynctask extends AsyncTask<String,Integer,Boolean>
{
@Override
protected void onPreExecute() {
super.onPreExecute();
textView.setText(DOWNLOADPROCESS);
progressBar.setProgress(0);
btn.setText(DOWNLOADPROCESS);
}
@Override
protected Boolean doInBackground(String... strings) {
if(strings!=null&&strings.length>0)
{
try {
URL url=new URL(strings[0]);
URLConnection urlConnection=url.openConnection();
InputStream inputStream=urlConnection.getInputStream();
int total_length=urlConnection.getContentLength();
stroge= Environment.getExternalStorageDirectory()+File.separator+APK_NAME;
File file=new File(stroge);
if(file.exists())
{
Boolean result=file.delete();
if(!result)
return false;
}
int lengthsize=0;
int current_length=0;
byte[] bytes=new byte[1024];
OutputStream outputStream=new FileOutputStream(file);
while((lengthsize=inputStream.read(bytes))!=-1)
{ outputStream.write(bytes,0,lengthsize);
current_length=current_length+lengthsize;
publishProgress(current_length * 100/total_length);
}
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);
if(aBoolean==true)
{
btn.setText("下载完成!");
textView.setText("下载完成 路径为:"+stroge);
}
}
@Override
protected void onProgressUpdate(Integer... values) {
if(values!=null&&values.length>0)
{
progressBar.setProgress(values[0]);
}
else
super.onProgressUpdate(values);
}
}
/**
*
* 使用动态申请权限
*/
private void setPermission() {
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
}
}
在doinbackground的方法中,利用HttpUrlConnection对象获取链接对象,之后在通过获取数据流,获得网页上的APP数据,绑定文件对象在输出流中,通过输入了的read方法,将获取的数据放在文件中,通过pulishProgress()方法传递实时数据,在onProgressUpdate()方法中实时更新进度条,最后完成在onPostprogress()方法中通知用户下载成功!
还需要注意的是android6.0以后就需要动态申请权限,访问sd卡,读写内容,读取通讯录都属于危险权限,在Manifest文件中加入权限后,在代码界面也要自己实现ActivityCompat.requestPermissions(Context context,String 数组,请求码)方法,数组里面就是放权限的内容.
最后实现的效果就是这样:
AsyncTask 使用非常广泛,只要是有与服务端接触,都需要它来实现操作。
作者:谭健
原文地址:[点击这里] (https://blog.csdn.net/weixin_39028072/article/details/80569910)