Android Loaders(一)概述
转载请注明:http://blog.csdn.net/liaoqianchuan00/article/details/24094575
参考翻译自:https://docs.google.com/presentation/d/1_5puFz6kUK1cSYvTmJbvQFYpgj8LXZECBrn65w62UKk/edit#slide=id.p
final Handler handler = new Handler(newHandler.Callback() {
@Override
public booleanhandleMessage(Message msg) {
switch(msg.what) {
case RESULT_WHAT:
handleResult((Result)msg.obj);
return true;
}
return false;
}
});
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
Result result = doStuff();
if (isResumed()) {
handler.sendMessage(handler.obtainMessage(RESULT_WHAT,result));
}
}
});
thread.start();
不方便:
1. 需要你自己将结果post到UI线程。
2. 必须自己手动处理Cancellation
3. 想要用线程池?你需要自己去实现。
1. 帮你处理了线程间的切换(即将结果post到主线程,你只需要实现他得回调)。
2. 帮你处理了cancellation:如果你调用的cancel(),那么onPostExecute不会执行(当还没有到这一步的时候就不会执行了)。
3. 可以更新进度条
final Handler handler = new Handler(newHandler.Callback() {
@Override
public booleanhandleMessage(Message msg) {
switch(msg.what) {
case RESULT_WHAT:
handleResult((Result)msg.obj);
return true;
}
return false;
}
});
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
Result result = doStuff();
if (isResumed()) {
handler.sendMessage(handler.obtainMessage(RESULT_WHAT,result));
}
}
});
thread.start();
问题:
1. 你需要保持一个对Activity的引用,然后再你的Activity的被销毁的时候来cancel这个任务。
2. 内存泄露:只要AsyncTask在运行,他就保持了一个对外部Activity的引用,虽然这个时候Activity已经销毁了(我们之前介绍过可以用静态内部类和WeakReference来解决,还可以用一个没有界面的Fragment来作AsyncTask的事情)。
3. 当Activity已经被重新创建后(比如旋转屏幕),之前AsyncTask取得的数据已经不在了。
需要知道的重点:
1. 在1.6之前,所有的AsyncTask在一个单独的线程中有序的执行。
2. 从1.6到2.3,这些AsyncTask在一个线程池中执行,但是有上限。
3. 从3.0开始,又使用最早的方案!他们在一个单独的线程中有序的执行,除非你调用executeOnExecutor,并且传入一个ThreadPoolExecutor。
解决方法:
publicclass ConcurrentAsyncTask {
public static void execute(AsyncTask as) {
if (Build.VERSION.SDK_INT <Build.VERSION_CODES.HONEYCOMB) {
as.execute();
} else {
as.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
}
}
特性:
1. 允许一个Activity或者Fragment连接到Activity或者Loader被重新创建之前的Loader,并且重新取出里面的result。
2. 如果result在Loader从Activity/Fragmentdisconnected之后才得到,那么它会被保存在cache中,并且在Activity/Fragemtneon被重新创建之后传送回来。
3. Loader可以监控他得数据源,在数据源数据变化后将新的数据deliver出来。
4. Loader处理了result相关的资源的allocation/disallocation(比如Cursors)。
如果你想在一个Activity或者Fragment里面进行异步数据的加载,不要再使用AsyncTask了。
也不要认为Loader只是用来做数据库相关的事情(CursorLoaders),他可以做很多事情。