android 自定义 loader实现

来源:互联网 发布:汤姆叔叔 javascript 编辑:程序博客网 时间:2024/05/23 02:03

android 的loader是android 3.0后的一种异步数据加载机制。
使用起来也颇为方便。
以下这块摘抄这里写链接内容这位同学的博客

在Android中任何耗时的操作都不能放在UI主线程中,所以耗时的操作都需要使用异步实现。同样的,在ContentProvider中也可能存在耗时操作,这时也该使用异步操作,而3.0之后最推荐的异步操作就是Loader。它可以方便我们在Activity和Fragment中异步加载数据,而不是用线程或AsyncTask,他的优点如下: 1.提供异步加载数据机制; 2.对数据源变化进行监听,实时更新数据; 3.在Activity配置发生变化(如横竖屏切换)时不用重复加载数据; 4.适用于任何Activity和Fragment;

这位同学基本介绍了很多东西,以及源码分析,我就不重复造轮子了,我就主要写一下,自定义loader的实现:
首先我建立一个数据源类(数据源可以是本地数据库,可以是网络获取,可以是任何)
TestData:

public class TestData {    private List<People> peopleList = new ArrayList<>();    interface Change{        void onChange();    }    public void save (People people,Change change){        peopleList.add(people);        if(change!=null){            change.onChange();        }    }    public List<People> getPeopleList (){        return peopleList;    }}

为了清晰的理解loader的自定义用法,我对代码进行了极大的精简:
这个数据源简单的不能再简单了:
我建立了一个接口:

interface Change{        void onChange();    }

这个主要是为了loader可以调用,对数据进行更新。
save主要是对数据进行更新。
有了数据源,我们就可以建立自定义loader了:
MyTestLoader:

public class MyTestLoader extends AsyncTaskLoader<List<People>> implements TestData.Change {    public MyTestLoader(Context context) {        super(context);    }    TestData testData ;    public MyTestLoader(Context context,TestData testData) {        super(context);        this.testData = testData;    }    @Override    public List<People> loadInBackground() {        List<People> data = testData.getPeopleList();        List<People> data2 = new ArrayList<>();        data2.addAll(data);        return data2;    }    @Override    protected void onReset() {        onStopLoading();    }    @Override    protected void onStartLoading() {        super.onStartLoading();        deliverResult(testData.getPeopleList());        if (takeContentChanged()) {            forceLoad();        }    }    @Override    protected void onStopLoading() {        super.onStopLoading();        cancelLoad();    }    @Override    public void deliverResult(List<People> data) {        if (isReset()) {            return;        }        if (isStarted()) {            super.deliverResult(data);        }    }    @Override    public void onChange() {        if (isStarted()) {            forceLoad();        }    }}

首先构造函数中添加数据源的引用。其次重写如下方法
loadInBackground:主要是进行异步加载数据的,在其中,我将数据源的数据return出来了。
以下为一对。
onStartLoading:生命周期,在创建时成立。
onStopLoading:生命周期,在结束时调用。
onChange:就是数据源里的接口,当调用时候,进行forceLoad
deliverResult:则是真正的返回数据。

自定义的loader基本就是这样了,我们进行对这个自定义loader运用。

建立一个activity,实现如下接口LoaderManager.LoaderCallbacks

public class MActivity extends BaseActivity implements LoaderManager.LoaderCallbacks<List<People>>

修改如下方法:

        testData = new TestData();        testLoader = new MyTestLoader(this,testData);                getSupportLoaderManager().initLoader(0, null, this);@Override    public Loader<List<People>> onCreateLoader(int id, Bundle args) {        return testLoader;    }    @Override    public void onLoadFinished(Loader<List<People>> loader, List<People> data) {        if (data != null) {            Logger.i("数据为"+data.toString());        } else {            Logger.i("数据为null");        }    }    @Override    public void onLoaderReset(Loader<List<People>> loader) {    }

再建立一个点击事件,进行调用

fab.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                People p = new People();                p.setName("wanger");                testData.save(p,testLoader);            }        });

接下来就是见证奇迹的时刻了,
日志里便打印出了详细的数据:
log如下:

数据为[People{name='wanger'}, People{name='wanger'}, People{name='wanger'}, People{name='wanger'}, People{name='wanger'}, People{name='wanger'}]

如上便是自定义loader的实现:谢谢观看,小弟才疏学浅,如有错误,帮我指出。

0 0
原创粉丝点击