使用异步任务,将耗时的操作移到后台,并在操作完成后同步更新UI,这是一种最佳实践模式。它有助于将时间处理程序与GUI线程进行同步。
注意:当Activity重新启动时,异步任务对其造成的更改在重新创建时会被取消。
对于声明周期较长的后台操作,使用后台Service是更好的选择。
如果直接在主线程里面运行访问网络的程序就会出现android.os.NetworkOnMainThreadException的错误,这种访问网络的行为必须用异步任务来实现。
下面实现一个简单的例子,从网络上获取图片。
1.Main中添加一个ImageView以及Button
2.在清单文件中进行网络授权。
<uses-permission android:name="android.permission.INTERNET"/>
3.实现一个AsyncTask的子类,并实现三个方法,
这里AsyncTask的三个泛型参数,第一个表示传入的参数类型,第二个表示进度的刻度,第三个表示返回结果的类型
三个函数中,onPreExecute预先处理一些事情,doInBackground做后台的主要任务,onPostExecute用于更新UI。
public class MyTask extends AsyncTask<String, Void, Bitmap>{
//表示任务执行之前的操作
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
dialog.show();
super.onPreExecute();
}
//主要是完成耗时操作
@Override
protected Bitmap doInBackground(String... params) {
// TODO Auto-generated method stub
//使用网络连接类 HttpClient完成对网络数据的提取
HttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(params[0]);
Bitmap bitmap = null;
try {
HttpResponse httpResponse = httpClient.execute(httpGet);
if (httpResponse.getStatusLine().getStatusCode() == 200){
HttpEntity httpEntity = httpResponse.getEntity();
byte[] data = EntityUtils.toByteArray(httpEntity);
bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
}
} catch (Exception e) {
// TODO: handle exception
}
return bitmap;
}
//更新UI操作
@Override
protected void onPostExecute(Bitmap result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
imageView.setImageBitmap(result);
dialog.dismiss();
}
}
@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;
}
4.在主线程的某个回调函数中调用
new MyTask().execute(image_path);