先new一个class继承AsyncTask类,AsyncTask要求提供三个泛型参数(Params 、Progress 、Result )其中,Params 为启动任务执行的输入参数,比如HTTP请求的URL;Progress 为后台任务执行的百分比;Result 后台执行任务最终返回的结果,比如String;然后AsyncTask的几个方法重写onPreExecute()、doInBackground()、onPostExecute()、onProgressUpdate(),其中doInBackground()为必须重写的;
例如:
class MyAsyncTask extends AsyncTask<Void, Void, Void>{
//第一个调用的方法可以用来初始化一些数据
@Override
protected void onPreExecute() {
super.onPreExecute();
Log.i("info", "onPreExecute");
}
//用于异步处理的方法,此方法不在主线程中运行
@Override
protected Void doInBackground(Void... params) {
publishProgress();
Log.i("info", "doInBackground");
return null;
}
//doInBackground方法结束时调用
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
Log.i("info", "onPostExecute");
}
//只有doInBackground方法中调用了publishProgress()时才会执行
@Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
Log.i("info", "onProgressUpdate");
}
}
值得注意的是这四个方法中只有doInBackground()方法不在主线程中运行,所以所有耗时操作我们将在doInBackground() 方法中进行,其他的三个方法都可以改变UI
下面来一个加载网上图片的案例:
布局文件:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.asynctaskdemo.ImageTestActivity" >
<ProgressBar
android:id="@+id/pb_bar"
style="?android:attr/progressBarStyleLarge"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:visibility="gone" />
<ImageView
android:id="@+id/iv_img"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true" />
</RelativeLayout>
Java文件:
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.widget.ImageView;
import android.widget.ProgressBar;
public class ImageTestActivity extends ActionBarActivity {
private static final String URL = "https://www.baidu.com/img/bdlogo.png";
private ImageView iv_img;
private ProgressBar pb_bar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_image_test);
iv_img = (ImageView) findViewById(R.id.iv_img);
pb_bar = (ProgressBar) findViewById(R.id.pb_bar);
MyscyncTask mTask = new MyscyncTask();
mTask.execute(URL);
}
class MyscyncTask extends AsyncTask<String, Void, Bitmap> {
@Override
protected void onPreExecute() {
super.onPreExecute();
pb_bar.setVisibility(View.VISIBLE);
}
@Override
protected Bitmap doInBackground(String... params) {
String url = params[0];
HttpURLConnection conn = null;
Bitmap bitmap = null;
try {
//线程休眠1秒,方便看进度条
Thread.sleep(1000);
conn = (HttpURLConnection) new URL(url).openConnection();
InputStream is = conn.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
bitmap = BitmapFactory.decodeStream(bis);
bis.close();
is.close();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
return bitmap;
}
@Override
protected void onPostExecute(Bitmap result) {
super.onPostExecute(result);
pb_bar.setVisibility(View.GONE);
iv_img.setImageBitmap(result);
}
}
}
为了方便查看代码所以我将AsyncTask写成了内部类
由于图片资源较小,所以我用了一个线程休眠1秒,方便查看进度条
再来一个模拟进度条的案例
布局文件:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.asynctaskdemo.ProgressBarTestActivity" >
<ProgressBar
android:id="@+id/progressBar1"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true" />
</RelativeLayout>
Java文件:
import android.os.AsyncTask;
import android.os.AsyncTask.Status;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.widget.ProgressBar;
public class ProgressBarTestActivity extends ActionBarActivity {
private ProgressBar progressBar1;
private MyAsyncTask mTask;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_progress_bar_test);
progressBar1 = (ProgressBar) findViewById(R.id.progressBar1);
mTask = new MyAsyncTask();
mTask.execute();
}
//将AsyncTask的生命周期与Activity进行绑定
@Override
protected void onPause() {
super.onPause();
if(mTask != null && mTask.getStatus() == Status.RUNNING){
mTask.cancel(true);
}
}
class MyAsyncTask extends AsyncTask<Void, Integer, Void>{
@Override
protected Void doInBackground(Void... params) {
for (int i = 0; i < 100; i++) {
if(isCancelled()){
break;
}
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
publishProgress(i);
}
return null;
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
if(isCancelled())
return;
progressBar1.setProgress(values[0]);
}
}
}
注意:由于AsyncTask底层是通过线程池进行作用的所以只有一个AsyncTask线程运行结束后另一个AsyncTask线程才可以运行,为了解决这一个为题,我们可以将AsyncTask的生命周期与Activity的生命周期进行绑定
时间: 2024-10-09 22:35:53