Android3.0 开始提出Loader和LoaderManager的概念,通过LoaderManager类可以很轻松的从Fragment或Activity 中进行异步加载数据。
这和AsyncTask很类似,但是AsyncTask没有LoaderManager的统一管理,并且不方便实现MVC的开发模式,对于和UI相关的数据加载就不要使用AsyncTask使用Loader最佳!
官方示例:
http://developer.android.com/reference/android/app/LoaderManager.html
http://developer.android.com/reference/android/content/AsyncTaskLoader.html
当然我们实际开发中,需要自己去实现一个更加酷的Loader,来满足我们的开发需要。
BaseDataLoader.java -- 一个基础Loader,提取于AsyncTaskLoader.html的示例代码,并做了自己的处理。
package cn.gavinliu.loader;
import android.content.AsyncTaskLoader;
import android.content.Context;
/**
* 这是一个基础的数据加载Loader
*
* @author Gavinliu
* @param <T>
*
*/
public abstract class BaseDataLoader<T> extends AsyncTaskLoader<T> {
private T mData;
public BaseDataLoader(Context context) {
super(context);
}
/**
* Handles a request to start the Loader.
*/
@Override
protected void onStartLoading() {
if (mData != null) {
// If we currently have a result available, deliver it
// immediately.
deliverResult(mData);
}
registerObserver();
if (takeContentChanged() || mData == null || isConfigChanged()) {
// If the data has changed since the last time it was loaded
// or is not currently available, start a load.
forceLoad();
}
}
/**
* Called when there is new data to deliver to the client. The super class
* will take care of delivering it; the implementation here just adds a
* little more logic.
*/
@Override
public void deliverResult(T data) {
if (isReset()) {
// An async query came in while the loader is stopped. We
// don't need the result.
if (mData != null) {
onReleaseResources(mData);
}
}
T oldApps = mData;
mData = data;
if (isStarted()) {
// If the Loader is currently started, we can immediately
// deliver its results.
super.deliverResult(data);
}
// At this point we can release the resources associated with
// 'oldApps' if needed; now that the new result is delivered we
// know that it is no longer in use.
if (oldApps != null) {
onReleaseResources(oldApps);
}
}
/**
* Handles a request to stop the Loader.
*/
@Override
protected void onStopLoading() {
// Attempt to cancel the current load task if possible.
cancelLoad();
}
/**
* Handles a request to cancel a load.
*/
@Override
public void onCanceled(T data) {
super.onCanceled(data);
// At this point we can release the resources associated with 'apps'
// if needed.
onReleaseResources(data);
}
/**
* Handles a request to completely reset the Loader.
*/
@Override
protected void onReset() {
super.onReset();
// Ensure the loader is stopped
onStopLoading();
// At this point we can release the resources associated with 'apps'
// if needed.
if (mData != null) {
onReleaseResources(mData);
mData = null;
}
unregisterObserver();
}
protected boolean isConfigChanged() {
return false;
}
protected void registerObserver() {
}
protected void unregisterObserver() {
}
protected void onReleaseResources(T mData) {
}
}
MainActivity.java -- 使用示例
package cn.gavinliu.loader;
import android.app.Activity;
import android.app.LoaderManager.LoaderCallbacks;
import android.content.Context;
import android.content.Loader;
import android.os.Bundle;
public class MainActivity extends Activity implements LoaderCallbacks<String> {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getLoaderManager().initLoader(0, null, this);
}
@Override
public Loader<String> onCreateLoader(int id, Bundle args) {
System.out.println("onCreateLoader");
mLoader = new MyLoader(getApplicationContext());
return mLoader;
}
@Override
public void onLoadFinished(Loader<String> loader, String data) {
System.out.println("onLoadFinished");
System.out.println("----->" + data);
}
@Override
public void onLoaderReset(Loader<String> loader) {
System.out.println("onLoaderReset");
}
private MyLoader mLoader;
static class MyLoader extends BaseDataLoader<String> {
String mData;
public MyLoader(Context context) {
super(context);
}
@Override
public String loadInBackground() {
System.out.println("LoadInBackground");
return "Load Success";
}
}
}