欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

如何高效的后台加载数据-LoaderManager

程序员文章站 2022-03-10 16:02:08
...

LoaderManager概述

LoaderManager是Android提供的一个用于管理数据加载的类,它与Loader这个类相互配合。可以这么理解,Loader是实施者负责加载数据,LoaderManager是管理者负责指挥Loader。开发中,常常会有这样的场景:启动一个Activity,然后从数据库读取数据,最后将数据展示在页面上。如果不使用LoaderManager,常规的做法一般是开启一个线程读取数据库,最后通过Handler将数据传递到主线程,最终显示出来。LoaderManager正是为这样的场景量身制作的, 使用LoaderManager,你无需开启线程,无需处理子线程与主线程的数据交互,甚至无需关心资源的释放。

一个例子

下面通过一个小例子,展示LoaderManager的基本使用方法:

1、初始化LoaderManager

mLoaderManager = getLoaderManager();
        LoaderManager.LoaderCallbacks<People> callbacks = new LoaderManager.LoaderCallbacks<People>() {
            @Override
            public Loader<People> onCreateLoader(int id, Bundle args) {
                return new MyLoader(MainActivity.this);
            }

            @Override
            public void onLoadFinished(Loader<People> loader, People data) {
                Log.d(TAG, "onLoadFinished: " + data.name + ":" + data.age);
            }

            @Override
            public void onLoaderReset(Loader<People> loader) {
                Log.d(TAG, "onLoaderReset: ");
            }
        };
        mLoaderManager.initLoader(1, null, callbacks);

首先通过getLoaderManager方法获得LoaderManager的一个实例,然后调用initLoader方法进行初始化。initLoader有三个参数:第一个是id值,唯一标识一个Loader。第二个是bundle,传入null即可。第三个是一个回调接口,接口有三个方法:

1)onCreateLoader

调用initLoader时指定的id对应的Loader不存在时,回调这个方法获取一个Loader实例

2)onLoadFinished

数据加载完成后,回调这个方法。这个方法运行在主线程,所以可以做一些更新UI的操作。

3)onLoaderReset

LoaderManager重置时,回调这个方法

2、自定义Loader加载数据

class MyLoader extends AsyncTaskLoader<People> {
    private static final String TAG = "MainActivity123";
    public MyLoader(Context context) {
        super(context);
    }

    @Override
    public People loadInBackground() {
        Log.d(TAG, "loadInBackground: ");
        return new People();
    }

    @Override
    protected void onStartLoading() {
        Log.d(TAG, "onStartLoading: ");
        super.onStartLoading();
        forceLoad();
    }

    @Override
    protected void onStopLoading() {
        Log.d(TAG, "onStopLoading: ");
        super.onStopLoading();
    }
}

自定义Loader一般继承自AsyncTaskLoader抽象类,AsyncTaskLoader类中封装了一个AsyncTask,可以后台加载数据。重写loadInBackground方法,这个方法里面写后台加载数据的逻辑,运行在子线程。onStartLoading方法会在initLoader方法调用之后回调,在这里要调用forceLoad方法开启后台任务,也就是执行loadInBackground方法。

3、完整代码

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity123";

    private LoaderManager mLoaderManager;
    private People mPeople;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mLoaderManager = getLoaderManager();
        LoaderManager.LoaderCallbacks<People> callbacks = new LoaderManager.LoaderCallbacks<People>() {
            @Override
            public Loader<People> onCreateLoader(int id, Bundle args) {
                return new MyLoader(MainActivity.this);
            }

            @Override
            public void onLoadFinished(Loader<People> loader, People data) {
                Log.d(TAG, "onLoadFinished: " + data.name + ":" + data.age);
            }

            @Override
            public void onLoaderReset(Loader<People> loader) {
                Log.d(TAG, "onLoaderReset: ");
            }
        };
        mLoaderManager.initLoader(1, null, callbacks);

    }
}

class People {
    public int age = 12;
    public String name = "张三";
}

class MyLoader extends AsyncTaskLoader<People> {
    private static final String TAG = "MainActivity123";
    public MyLoader(Context context) {
        super(context);
    }

    @Override
    public People loadInBackground() {
        Log.d(TAG, "loadInBackground: ");
        return new People();
    }

    @Override
    protected void onStartLoading() {
        Log.d(TAG, "onStartLoading: ");
        super.onStartLoading();
        forceLoad();
    }

    @Override
    protected void onStopLoading() {
        Log.d(TAG, "onStopLoading: ");
        super.onStopLoading();
    }
}

总结

这里仅仅是介绍了LoaderManager的一些基本用法,另外,LoaderManager是能感知到宿主Activity的生命周期的,当Activity的状态变为Pause、Stop、Restart时,LoaderManager也会回调相应的方法。更多情况下LoaderManager是与CursorLoader配合使用的,用于后台加载数据库,感兴趣的话可以自己去了解一下。