文章转载只能用于非商业性质,且不能带有虚拟货币、积分、注册等附加条件。转载须注明出处:http://blog.csdn.net/flowingflying/编程
小例子app
经过简单的菜单,触发一个用sleep模拟的任务。Test Async One 1将调用1个AsyncTask任务,咱们在Test Ansync One 2中同时执行两个task,看看运行的状况。Test Async Two中互动会更为复杂,task不只在主线程写TextView,还开启一个ProgessDialog。ide
咱们先经过Test Async One 1来学习AsyncTask。首先实现继承AsyncTask。函数
public class MyLongTask extends AsyncTask<String,Integer,Integer>{
private IReportBack report = null;
private String tag = null;
//【步骤1】:构造函数,IReportBack定义主线程Activity处理task UI操做的回调函数,做为良好编程风格,无需将Activity对象直接传递过来。
public MyLongTask(IReportBack inr, String inTag){
report = inr;
tag = inTag;
}
@Override //【步骤2】:重写onPreExecute(),这是运行在主线程中(准确来将是运行在建立对象所在线程),进行后台线程运行先的初始化等处理。因为运行在主线程,所以可在此进行UI操做。
protected void onPreExecute() {
Log.v(tag, "onPresExecute():" + Utils.getThreadSignature());
report.reportTransient(tag, "In progress ...... "); //调用接口中的UI处理函数。
}
@Override //【步骤4】从程序员的视图,在worker线程中运行的doInBackground(),经过publishProgress()触发在主线程运行的的onProgressUpdate(),当中的机制是handler。在此,咱们进行在其余线程运行时须要触发的UI处理。
protected void onProgressUpdate(Integer... values) {
Log.v(tag, "onProgressUpdate():" + Utils.getThreadSignature());
Integer i = values[0];
report.reportBack(tag, "Progress: i = " + i);//调用接口中的UI处理函数。
}
@Override //【步骤5】当后台线程运行完,经过handler将最后结果通知给线程,将在主线程触发onPostExcute(),在此进行后台处理结束触发相关的UI处理。参数result为doInbackground()的返回值。
protected void onPostExecute(Integer result) {
Log.v(tag, "onPostExecute():" + Utils.getThreadSignature());
report.reportBack(tag, "result: i = " + result);
}
@Override //【步骤3】当调用task.execute()时,将在worker线程中执行doInBackground(),因为不在主线程中执行,不能再此进行UI操做,若是但愿触发相关的UI操做,经过publishProgress(),利用隐藏的handler在主线程队列加入message进行处理。主线程处理message,触发handler的handleMessage(),这些隐藏的步骤经过AsyncTask的封装,呈现为触发onProgressUpdate()。
protected Integer doInBackground(String... params) {
Log.v(tag,"doInBackground():" + Utils.getThreadSignature());
for(int i = 0; i < params.length;i ++){
Utils.sleepForSecs(2); //休眠2秒
publishProgress(i);
}
return params.length;
}
}学习
AsyncTask封装得很是好,提升task运行前、运行中、运行后的回调函数,在此咱们进行相关的UI处理。这些代码都放在对AsyncTask继承类中。处理UI就离不开Activity的View,最直接的方式是将Activity对象经过构造函数传递到AsyncTask中,然而在真正的项目开发,这样作会使一个特定的任务能够任意调用Activity的功能,二者的界面不清晰,代码可读性、可维护性,检查错误方面都不太好。所以,一般会将task涉及到的UI处理放入到接口中。this
public interface IReportBack {
public void reportBack(String tag,String message);
public void reportTransient(String tag,String message);
}.net
咱们将在主线程中建立AsyncTask对象,下面是activity的相关代码线程
public class MainActivity extends Activity implements IReportBack{
private static TextView tv = null;
… …
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.testOne1){
testMyLongTask();
}
return super.onOptionsItemSelected(item);
}
private void testMyLongTask(){
MyLongTask task = new MyLongTask(this, "TestOne"); //建立AsyncTask对象,经过这个对象,咱们能够经过调用task.cancel()来中止worker线程,这时会触发onCanceled(Object)回调函数。
task.execute("Hello","my","friend"); //经过execute() 来触发后台线程执行,顺序在主线程运行onPreExecute(),而后开线程运行doInBackground()的代码,doInBackground运行结束后,触发在主线程运行的onPostExecute()。
}
@Override //接口实现
public void reportBack(String tag, String message) {
tv.append(tag + " : " + message + "\n");
Log.v(tag,message);
}
@Override //接口实现
public void reportTransient(String tag, String message) {
Toast.makeText(this, tag + " : " + message, Toast.LENGTH_SHORT).show();
reportBack(tag,message);
}
} 对象
相关小例子源代码可在Pro Android学习:AsyncTask小例子中下载。
相关连接: 个人Android开发相关文章