异步任务AsyncTask
什么是异步任务?
逻辑上:以多线程的方式完成功能的需求
API上:指AsyncTask类
AsyncTask的理解:
在没有AsyncTask之前,我们用Handler+Thread就可以实现异步任务的功能需求
AsyncTask是对Handler和Thread的封装,使用它编码更加简洁,更高效(就类似于问答题和填空题的区别)
AsyncTask封装了ThreadPool,比直接使用Thread效率更高
相关API
AsyncTask:简化Handler处理多线程通信的问题
AsyncTask<Params,Progress,Result>
Params启动任务执行的输入参数,比如HTTP请求的URL
Progress后台任务执行的百分比
Result后台执行任务最终返回的结果,比如String
execute(Params...params)
启动任务,开始任务的执行流程
void onPreExecute()
在分线程工作开始之前在UIThread中执行,一般用来显示提示视图
Result doInBackground(Params...params)
在workerThread中执行,完成任务的主要工作,通常需要较长的时间
void onPostExecute(Result result)
在doInBackground()执行完后在UIThread中执行,一般用来更新界面
publicProgress(Progress...values):在分线程中,发布当前进度
void onProgressUpdate(Progress...values):在主线程中更新进度
//第二个参数是报告进度的,第三个参数是报告结果的。
static class InsertAsyncTask extends AsyncTask<Word,Void,Void>{
/**
* 在工作线程(后台)上进行操作
* @param words 根据上面写的第一个参数,系统自动帮你生成
*/
@Override
protected Void doInBackground(Word... words) {
}
/**
* 在任务完成的时候执行。一般是用于将结果带回主线程
* @param aVoid
*/
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
}
/**
* 当进度发生更新时执行。
* @param values
*/
@Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
/**
* 在后台任务执行之前执行
*/
@Override
protected void onPreExecute() {
super.onPreExecute();
}
}
案例:
从本地服务器中下载一个APK
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
private ProgressDialog pd;
private File apkFile;
public void downloadAPK(View view){
new AsyncTask<Void,Integer,Void>(){
//主线程显示视图
@Override
protected void onPreExecute() {
pd=new ProgressDialog(MainActivity.this);
pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pd.show();
apkFile=new File(getExternalFilesDir(null),"update.apk");
}
//分线程,联网请求
@Override
protected Void doInBackground(Void... voids) {
HttpURLConnection connection= null;
try {
String path="http://192.168.137.1:8080/cookie_war_exploded/123.apk";
URL url=new URL(path);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
int responseCode = connection.getResponseCode();
if(responseCode==200){
pd.setMax(connection.getContentLength());
InputStream is=connection.getInputStream();
FileOutputStream fos=new FileOutputStream(apkFile);
byte[] buffer=new byte[1024];
int len;
while((len=is.read(buffer))!=-1){
fos.write(buffer,0,len);
//显示进度,这里看上去是在分线程中执行,但是内部是使用了Handler更新界面(这里假设不能在分线程执行,所以注释掉)
//pd.incrementProgressBy(len);
//发布进度,则会执行下面的onProgressUpdate方法。这两个是一起的
publishProgress(len);
}
is.close();
fos.close();
}
connection.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
//主线程,更新界面
@Override
protected void onPostExecute(Void aVoid) {
pd.dismiss();
//installAPK();
}
@Override
protected void onProgressUpdate(Integer... values) {
pd.incrementProgressBy(values[0]);
}
}.execute();
}
//下载完后,进入安装应用界面,频繁报错,不知道为什么(进行这步需要权限,错误原因以后再探究)
// private void installAPK(){
// Intent intent=new Intent("android.intent.INSTALL_PACKAGE");
// intent.setDataAndType(Uri.fromFile(apkFile),"application/vnd.android.package-archive");
// startActivity(intent);
// }
}