异步任务是Android中进行网络数据操作的一个重要模块,如果在主线程中进行耗时操作会报ANR异常,所以,在进行网络数据下载时,必须用到异步任务,当开始执行异步任务时,会自动开启一个子线程
在子线程中进行耗时操作,完成后把结果交给主线程处理即可;
当我们使用异步任务时,一般继承AsyncTask即可,AsyncTask有5个重要方法:
execute(String path):调用此方法,传入路径开始执行异步任务,如:new MyAsynctask.execute(path);
doInBackGround(String...params):当execute()方法调用后,会把path传给此方法,从而在子线程执行异步操作;
onPostExecute( ? result):当doInBackGround()执行完毕,会把结果传给此方法,此方法在主线程中执行;
onPreExecute():在DoInBackGround()执行之前执行,可做一些初始工作;
onProgressUpdate():更新进度条时用到,当调用publishProgress()时调用;
在定义AsyncTask时,有三个泛型:
第一个:传入DoInBackGround()的值,一般指路径,String型即可;
第二个:表示进度条的值,若无进度条,传Void即可;
第三个:DoInBackGround()返回给onPostExecute()的结果的类型;
例:
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:gravity="center_horizontal">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:text="下载" />
<ImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/ic_launcher"
android:layout_below="@id/button"/>
</RelativeLayout>
Java代码:
在MainActivity中:
public class MainActivity extends Activity {
private Button button;
private ImageView imageView;
private static final String PATH="https://www.baidu.com/img/bd_logo1.png";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
button=(Button) findViewById(R.id.button);
imageView=(ImageView) findViewById(R.id.imageView);
}public MainActivity() {
// TODO Auto-generated constructor stub
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
new MyAsynctask(imageView).execute(PATH);
}
});
}
}
定义AsyncTask:
public class MyAsynctask extends AsyncTask<String, Void, Bitmap> {
private ImageView imageView;
public MyAsynctask(ImageView imageView){
this.imageView=imageView;
}
/**
* 自动开启一个子线程,执行耗时操作
*/
@Override
protected Bitmap doInBackground(String... params) {
String path=null;
if(params!=null){
path=params[0];
}
byte[] buffer=HttpUtil.getBytes(path);//进行网络操作,见下面的HttpUtil;
Bitmap bitmap=null;
if(buffer!=null){
bitmap=BitmapFactory.decodeByteArray(buffer, 0, buffer.length);
return bitmap;
}
return null;
}
@Override
protected void onPostExecute(Bitmap result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
imageView.setImageBitmap(result);
}
@Override
protected void onPreExecute() {
Log.i("TAG", "onPrexecute()");
super.onPreExecute();
}
@Override
protected void onProgressUpdate(Void... values) {
Log.i("TAG", "onProgressUpdate");
super.onProgressUpdate(values);
}
}
HttpUtil:是封装的一个工具类,进行网络操作:
public class HttpUtil {
private static ByteArrayOutputStream baos;
public static byte[] getBytes(String path){
try {
//通过路径得到URL对象
URL url=new URL(path);
//通过URL得到HttpURLConnection对象
HttpURLConnection conn=(HttpURLConnection) url.openConnection();
//设置5秒为超时操作
conn.setReadTimeout(5000);
//设置请求方式为get 默认为get
conn.setRequestMethod("GET");
//与资源进行连接
conn.connect();
BufferedReader reader;
if(conn.getResponseCode()==200){
InputStream is=conn.getInputStream();
reader=new BufferedReader(new InputStreamReader(is));
baos=new ByteArrayOutputStream();
String line=null;
byte[] buffer=new byte[1024];
while((line=reader.readLine())!=null){
baos.write(buffer, 0, buffer.length);
}
//关闭流资源
reader.close();
baos.close();
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return baos.toByteArray();
}
}
注意:当执行网络操作时,必须在manifest中加入网络权限:
<uses-permission android:name="android.permission.INTERNET"/>
运行效果: