前言:
首先明确Android之所以有Handler和AsyncTask,都是为了不阻塞主线程(UI线程),且UI的更新只能在主线程中完成,因此异步处理是不可避免的。
AsyncTask简介:
AsyncTask 的优势体现在:
1、线程的开销较大,如果每个任务都要创建一个线程,那么应用程 序的效率要低很多;
2、线程无法管理,匿名线程创建并启动后就不受程序的控制了,如果有很多个请求发送,那么就会启动非常多的线程,系统将不堪重负。
3、另外,前面已经看到,在新线程中更新UI还必须要引入handler,这让代码看上去非常臃肿。
AsyncTask定义了三种泛型类型 Params,Progress和Result。
1、Params 启动任务执行的输入参数,比如HTTP请求的URL。
2、Progress 后台任务执行的百分比。
3、Result 后台执行任务最终返回的结果,比如String。
AsyncTask的执行分为四个步骤:
onPreExecute(), 该方法将在执行实际的后台操作前被UI thread调用。可以在该方法中做一些准备工作,如在界面上显示一个进度条。
doInBackground(Params...), 将在onPreExecute 方法执行后马上执行,该方法运行在后台线程中。这里将主要负责执行那些很耗时的后台计算工作。可以调用 publishProgress方法来更新实时的任务进度。该方法是抽象方法,子类必须实现。
onProgressUpdate(Progress...),在publishProgress方法被调用后,UI thread将调用这个方法从而在界面上展示任务的进展情况,例如通过一个进度条进行展示。
onPostExecute(Result), 在doInBackground 执行完成后,onPostExecute 方法将被UI thread调用,后台的计算结果将通过该方法传递到UI thread.
另外注意:
使用AsyncTask类,以下是几条必须遵守的准则:
1) Task的实例必须在UI thread中创建
2) execute方法必须在UI thread中调用
3) 不要手动的调用onPreExecute(), onPostExecute(Result),doInBackground(Params...), onProgressUpdate(Progress...)这几个方法
4) 该task只能被执行一次,否则多次调用时将会出现异常
示例:使用异步AsyncTask下载网络图片和进度条加载
MainActivity代码如下:
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
//下载网络图片
public void Loadimage(View view){
startActivity(new Intent(this, imagetest.class));
}
//进度条加载
public void Loading(View view){
startActivity(new Intent(this, progressbar.class));
}
}
下载网络图片AsyncTask代码如下:
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URLConnection;
import java.net.*;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.ProgressBar;
public class imagetest extends Activity {
private ImageView mimageview;
private ProgressBar mprogressbar;
//自定义一个网络图片URL;
private static String URL="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1500011575&di=031987ff6f15b3f13ff7ffbce37c7425&imgtype=jpg&er=1&src=http%3A%2F%2Fimg4.duitang.com%2Fuploads%2Fitem%2F201510%2F07%2F20151007215248_yikZv.jpeg ";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.image);
mimageview=(ImageView) findViewById(R.id.imageView1);
mprogressbar=(ProgressBar) findViewById(R.id.progressBar1);
new myasynctask().execute(URL);
}
class myasynctask extends AsyncTask<String, Void, Bitmap>{
@Override
protected void onPreExecute() {
mprogressbar.setVisibility(View.VISIBLE);
super.onPreExecute();
}
@Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
mprogressbar.setVisibility(View.GONE);
mimageview.setImageBitmap(bitmap);
}
@Override
protected void onProgressUpdate(Void... values) {
// TODO Auto-generated method stub
super.onProgressUpdate(values);
}
@Override
protected Bitmap doInBackground(String... params) {
String url=params[0];
Bitmap bitmap=null;
URLConnection connection;
InputStream is;
try {
connection=new URL(url).openConnection();
is=connection.getInputStream();
BufferedInputStream bis=new BufferedInputStream(is);
bitmap=BitmapFactory.decodeStream(bis);
Thread.sleep(3000);
is.close();
bis.close();
} catch (Exception e) {
e.printStackTrace();
}
return bitmap;
}
}
}
进度条加载代码如下:
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.ProgressBar;
public class progressbar extends Activity{
private ProgressBar pb;
private myasynctask my;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.progress);
pb=(ProgressBar)findViewById(R.id.pb);
my=new myasynctask();
my.execute();
}
@Override
protected void onPause() {
super.onPause();
if(my!=null&&my.getStatus()==AsyncTask.Status.RUNNING)
{
my.cancel(true);
}
}
class myasynctask extends AsyncTask<Void, Integer, Void>{
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
//取出进度值
pb.setProgress(values[0]);
}
@Override
protected Void doInBackground(Void... params) {
//更新进度值,模拟进度栏分析
for(int i=0;i<100;i++){
if(my.isCancelled())
{
break;
}
publishProgress(i);
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return null;
}
}
}