一 为什么异步任务
1.android 的单线程模型
2.耗时操作放在非主线程中操作
二 AsyncTask 为何而生
1.在子现成中更新UI
2.封装 简化异步操作
三 构造AsyncTask 子类参数
首先看下AsyncTask 的基本用法, 由于AsyncTask <Params, Progress, Result>是一个抽象的类,使用它必须构建一个子类去继承它。继承它需要指定它的三个泛型参数
1.Params 在执行AsyncTask时候需要传入的参数 可用于后台任务中使用。
2. Progress 后台任务执行时候,需要在界面上显示当前进度,则使用这里指定的泛型作为进度单位。
3.Result 后台任务执行完后返回结果的类型。
四 构造 AsyncTask 子类回调的方法
一个完整的AsyncTask 包括以下四个方法:
1. onPreExcute()
这个方法会在后台任务开始执行前调用,用于进行一些界面上的初始化操作,比如显示已个进度条对话框等。
2. doInBackground (Params ...)
这个必须重写, 这个方法中的所有代码都会在子线程中执行,在这里面我们处理耗时任务, 任务一旦完成就可以通过return 语句将任务执行的结果返回,如果AsyncTask 的第三个参数是Void ,就可以不返回执行结果。注意的是,在这个方法中不可以进行UI操作,如果需要更新UI元素,则需要调用publishProgress(Progress...) 方法来完成。
3. onProgressUpdate(Progress...)
当在后台中 调用了publishProgress(Progress...) 方法后,这个方法就很快会被调用,方法携带的参数就是在后台任务中传递过来的。在这个方法中可以对UI进行操作。利用参数中的数值就可以对界面元素进行相应的更新。
4. onPostExecute(Result)
后台任务执行完毕并通过return 返回时,这个方法很快就被调用。 返回的数据会作为参数传递此方法中,利用返回的数据进行UI的操作。
下面具体代码来演示
AsyncTask 的操作
加载一张网络图片 在异步中下载图像 在UI中设置图像
创建工程 activity_main.xml中布局代码为
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:id="@+id/but"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="but" />
</LinearLayout>
MainActivity.Java中代码为
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity implements OnClickListener {
private Button but;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
but = (Button) findViewById(R.id.but);
but.setOnClickListener(this) ;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public void onClick(View arg0) {
switch (arg0.getId()) {
case R.id.but:
startActivity(new Intent(MainActivity.this, asynctask.class));
break;
}
}
}
创建异步任务的布局文件 asynctask.xml
<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=".MainActivity" >
<ImageView
android:id="@+id/imageView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
/>
<ProgressBar
android:id="@+id/progressBar1"
android:visibility="gone"
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/imageView1"
android:layout_alignTop="@+id/imageView1"
android:layout_marginLeft="90dp"
android:layout_marginTop="160dp" />
</RelativeLayout>
异步任务的asynctask.java 代码
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
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 asynctask extends Activity {
private ImageView imageView;
private ProgressBar progressBar;
final String url = "http://www.uestc.edu.cn/public/2015/10/2015_10_08_02_25_18_1451.png"; //网络图片的网址
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.asynctask);
imageView = (ImageView) findViewById(R.id.imageView1);
progressBar = (ProgressBar) findViewById(R.id.progressBar1);
new myAsynctask().execute(url);
}
class myAsynctask extends AsyncTask<String, Void, Bitmap> { //第一个参数是网址 第三个参数返回的是图片所以是BitMap 类型
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
progressBar.setVisibility(View.VISIBLE);//显示进度条
}
@Override
protected void onPostExecute(Bitmap result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
progressBar.setVisibility(View.GONE);//隐藏进度条
imageView.setImageBitmap(result);//操作UI进行图像设置 这里的result 就是doInBackground 返回的BitMap
}
@Override
protected Bitmap doInBackground(String... arg0) {
String url = arg0[0]; //传进来的参数只有一个 所以只需要获得第一个参数就获取URL
Bitmap bitmap = null;
URLConnection connection;
InputStream is;
try {
connection = new URL(url).openConnection(); //获取网络连接对象
is = connection.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
<strong>Thread.sleep(3000);//如果网速太给力则看不到进度条 所以加一个延时函数</strong>
//通过 decodeStream解析输入流转化成BitMap
bitmap = BitmapFactory.decodeStream(bis);
is.close();
bis.close();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return bitmap; //最后返回
}
}
}
记得在 AndroidManifest.xml 中加入网络访问权限 和对
asynctask 注册
<uses-permission android:name="android.permission.INTERNET" />
<activity android:name="com.example.httpurl1.asynctask" >
</activity>