AsyncTask异步加载
Android默认约定当UI线程阻塞超过5秒将会引发ANR(Application Not Responding)异常。所以在UI线程中不要执行耗时操作。
AsyncTask后台运行有五个状态:
1、 准备状态
2、 正在运行状态
3、 进度更新
4、 完成后台任务
5、 取消任务
对应五个状态有五个回调函数:
1、 准备状态:onPreExecute(),该方法将在执行后台耗时操作前被调用。通常该方法用于完成一些初始化的准备工作,比如在界面上显示进度条等。
2、 正在执行:doInBackground(Params…);重写该方法就是后台线程将要完成的任务,其结果必须由该函数返回,并被传递到onPostExecute()中。该方法可以调用publishProgress()方法更新任务的执行进度,而进度值将在onProgressUpdate(Progress …)中被发布到UI线程。
3、 进度更新:onProgressUpdate(Progress…) 该函数由UI线程在publishProgress(Progress …)
调用完成后被调用。用于动态显示一个进度条
4、 完成后台任务:onPostExecute(Result),当后台任务完成后调用,并将doInBackground()方法的返回值传给该方法。
5、 取消任务:onCancelled(),在调用AsyncTask的cancel()方法时调用
AsyncTask是一个抽象类,通常用于被继承,继承AsyncTask时需要指定三个参数类型
AsyncTask更轻量级一些,适用于简单的异步处理,不需要借助线程和Handler即可实现。
AsyncTask<Params, Progress, Result>
è Params:启动任务执行的输入参数类型。
è Progress,后台任务完成的进度值类型
è Result,后台任务完成后返回结果的类型
AsyncTask并不总是需要使用上面的全部3种类型。标识不使用的类型很简单,只需要使用Void类型即可。
public classMainActivity extends ActionBarActivity {
public TextViewtvShow;
@Override
protected void onCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvShow = (TextView)findViewById(R.id.tvShow);
}
public void download(View source) throws MalformedURLException {
DownTasktask = newDownTask(this);
task.execute(new URL(
"http://news.china.com.cn/2013-07/31/content_29586107.htm"));
}
class DownTaskextends AsyncTask<URL,Integer, String> {
private ContextmContext;
// 定义记录已经读取行的数量
int hasRead = 0;
// 可变长的输入参数,与AsyncTack.execute()对应;
private ProgressDialogpDialog;
public DownTask(ContextpContext) {
mContext = pContext;
}
@Override
protected StringdoInBackground(URL... params) {
StringBuildersb = newStringBuilder();
try {
URLConnectionconn = params[0].openConnection();
BufferedReaderbr = newBufferedReader(newInputStreamReader(
conn.getInputStream(),"utr-8"));
StringlineString = null;
while ((lineString =br.readLine()) !=null) {
sb.append(lineString+ "\n");
hasRead++;
publishProgress(hasRead);//更新任务的执行进度
}
return sb.toString();
}catch(Exception e) {
// TODO: handle exception
}
return null;
}
@Override
protected void onPostExecute(Stringresult) {
// 返回HTML页面内容
tvShow.setText(result);
pDialog.dismiss();
}
@Override
protected void onPreExecute() {
pDialog = new ProgressDialog(mContext);
pDialog.setTitle("任务正在执行中...");
pDialog.setMessage("任务正在执行中,敬请等待...");
pDialog.setCancelable(false);//设置对话框不能用“取消"按钮关闭
pDialog.setMax(202);
pDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pDialog.setIndeterminate(false);//设置对话框的进度条是否显示进度
pDialog.show();
}
@Override
protected voidonProgressUpdate(Integer... values) {
tvShow.setText("已经读取了【" + values[0] +"】行!");
pDialog.setProgress(values[0]);
}
}
}