平时我们喜欢用各种框架和异步任务handler来更新UI,但是从来没明白为什么,只是不停的抄袭,今天我就来深刻的理解一下什么叫异步任务,什么叫Handler,以及用了N次的AsyncDataLoader的用法。
-
一、异步任务(AsyncTask 【ps:换行加>代表涂灰段落】)
-
异步任务源码解释(ps:一个冒号加一个中文空格区分小标题)
public class TestActivity extends ActionBarActivity {
private TextView test;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);setContentView(R.layout.activity_test); test=(TextView)findViewById(R.id.mytext); Map<String,String> map = new HashMap<String,String>(); map.put("grant_type","client_credential"); map.put("appid","wx9103cb43ba8c9001"); map.put("secret","052ee3aceae62507bb4bbe2bd5c55a75"); new ZyAsyncTask(test).execute(map);
}
师父说,异步任务的本质是一个线程池,然后异步任务中可以更新UI的onPostExecute方法其内部调用的handler去更新的UI,也就是说,异步任务并不是更新UI的方式,它也只是调用了别人的方法也就是handler来更新UI,也就是说更新UI的方式是Handler和runOnUiThread。
// Map<String,String>代表doInBackground方法的参数类,
,Integer代表刷新进度条的类型
//String代表耗时操作返回的类型或者说是耗时结束得到的数据类型onPostExecute,就像这里请求服务端返回的是String类型一样
class ZyAsyncTask extends AsyncTask<Map<String,String> , Integer, String>{
String url="https://api.weixin.qq.com/cgi-bin/token";
// TextView test;
//t为要更新的UI对象,貌似可以不用传过来
ZyAsyncTask( TextView t){
// test=t;
Log.e("测试", "ZyAsyncTask( TextView t)");
}
//执行费时操作
@Override
protected String doInBackground(Map<String,String>... Xparams) {
Log.e("测试","doInBackground(Map<String,String>... Xparams)");
HttpPost http=new HttpPost(url);
List<NameValuePair> mparams = new ArrayList<NameValuePair>();
mparams.clear();
Set<String> set = Xparams[0].keySet() ;
for(String strset : set) {
mparams.add(new BasicNameValuePair(strset, Xparams[0].get(strset)));
}
try{
http.setEntity(new UrlEncodedFormEntity(mparams, HTTP.UTF_8));
HttpResponse httpResponse = new DefaultHttpClient().execute(http);
if (httpResponse.getStatusLine().getStatusCode() == 200) {
String result = EntityUtils.toString(httpResponse.getEntity());
System.out.println(result);
return result ;
}
}catch (Exception e){
e.printStackTrace();
}
return null;
}
//刚启动准备阶段
@Override
protected void onPreExecute() {
Log.e("测试","onPreExecute()");
test.setText("准备阶段");
}
//耗时操作完成后做UI更新在这里
@Override
protected void onPostExecute(String result) {
Log.e("测试","onPostExecute(String result)");
test.setText(result);
}
//更新进度条
@Override
protected void onProgressUpdate(Integer[] values) {
Log.e("测试","onProgressUpdate(Integer[] values)");
test.setText(values[0]+"");
}
//取消异步任务
@Override
protected void onCancelled(String result) {
Log.e("测试","onCancelled(String result)");
test.setText(result);
}
}
}
: 以上方法中打印依次顺序为 ZyAsyncTask( TextView t)---> onPreExecute()---> doInBackground(Map<String,String>... Xparams)--->
onPostExecute(String result),要是平时的使用就是这样子的了,可是师父说它更新ui的方法调用了handler,接下来看源码:
然而依然看不出调用了handler
*平时从来不看源码的,以至于各种抄袭然后啥也不知道,希望这次修行能有所获。第一次认真看源码,翻译文在这里,由于原文太庞大了,就另写了一篇文章。地址:
http://blog.csdn.net/u013200864/article/details/46801887
-
上面的源码翻译很乱,但用心看不难发现异步任务就是个一个子线程,n内部使用了线程池,并不能更新UI,只是它内部调用了handler,因而可以在onPostExecute和onPreExecute方法中刷新UI,下面介绍handler.
二、Handler(子线程刷新UI的方式)
-
Handler
用法如下: -
runOnUiThread
三、AsyncDataLoader工具类
public class AsyncDataLoader extends AsyncTask<Void, Long, Object> {
private Callback mCallback;
public AsyncDataLoader(Callback callback) {
setCallback(callback);
}
protected Object doInBackground(Void... voids) {
if (mCallback != null) {
mCallback.onStart();
}
return null;
}
protected void onPostExecute(Object result) {
super.onPostExecute(result);
if (mCallback != null) {
mCallback.onFinish();
}
}
protected void onPreExecute() {
super.onPreExecute();
if (mCallback != null) {
mCallback.onPrepare();
}
}
public void setCallback(Callback callback) {
this.mCallback = callback;
}
public interface Callback {
public void onPrepare();
public void onStart();
public void onFinish();
}
}