今天学到了这个Loader,浅谈一下自己的看法:

1.定义

Loader是一个加载器,可以用来它访问数据,可以看做访问数据的机器(好比挖掘机)。装再器从android3.0开始引进,它使得在activity或fragment中异步加载数据变得简单。

具有如下特别:

1)它们对每个Activity和Fragment都有效

2)它们提供了异步加载数据的能力

3)它拥有一个数据改变通知机制,当数据源做出改变是会及时通知。当Cursor发生变化时,会自动加载数据,因此不需要重新进行数据查询

解释一下为什么会有异步加载数据的能力:

final class LoadTask extends ModernAsyncTask<Void, Void, D> implements Runnable {
private final CountDownLatch mDone = new CountDownLatch(1); // Set to true to indicate that the task has been posted to a handler for
// execution at a later time. Used to throttle updates.
boolean waiting; /* Runs on a worker thread */
@Override
protected D doInBackground(Void... params) {
if (DEBUG) Log.v(TAG, this + " >>> doInBackground");
try {
D data = AsyncTaskLoader.this.onLoadInBackground();
if (DEBUG) Log.v(TAG, this + " <<< doInBackground");
return data;
} catch (OperationCanceledException ex) {
if (!isCancelled()) {
// onLoadInBackground threw a canceled exception spuriously.
// This is problematic because it means that the LoaderManager did not
// cancel the Loader itself and still expects to receive a result.
// Additionally, the Loader's own state will not have been updated to
// reflect the fact that the task was being canceled.
// So we treat this case as an unhandled exception.
throw ex;
}
if (DEBUG) Log.v(TAG, this + " <<< doInBackground (was canceled)", ex);
return null;
}
}
protected D onLoadInBackground() {
return loadInBackground();
}
public abstract D loadInBackground();
这是AsyncTaskLoader底层代码实现。可以看出,在AsyncTaskLoader中创建一个final修饰的内部类,实现异步任务。封装了一个抽象方法loadInBackground(),在子类继承时,实现各自的实现方式。

2.作用

用来加载数据,访问数据库(系统自带的数据库,自定义数据库)。当然访问数据库,我们可以使用ContentResolver通过query()访问数据库,得到一个Cursor对象,遍历这个对象就可以拿到我们想要的数据。但Loader的作用比ContentResolver更简便更快捷。

3.用法(使用装载器时设计到的类和方法)

LoaderManager:本身是一个抽象类。关联到每一个Activity或Fragment,管理一个或多个装载器的实例。这帮助一个应用管理那些与Activity或Fragment的声明周期相关的长时间运行的操作。最常见的方式是与一个CursorLoader一起使用,然而应用是可以随便写它们自己的加载器从而加载其他类型的数据。

LoaderManager.LoaderCallBack<D>:本身是一个接口。一个用于客户端与LoaderManager交互的回调接口。如:你可以使用onCreateLoader()创建一个Loader加载器

Loader:本身是一个抽象类。一个执行异步数据加载的抽象类。它是加载器的基类,你可以使用典型的CursorLoader,但是你也可以使用自定义的Loader(创建一个类extends AsyncTaskLoader),它们将监试它们的数据源并且在数据改变是发送新的结果。

AsyncTaskLoader:本身是一个抽象类,提供一个AsyncTask来执行异步加载工作(工作在子线程,进行耗时操作)。

CursorLoader:AsyncTaskLoader的实现类。

4.我自己写的一个demo访问手机联系人

package com.yz.searchcontacts;

import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.AsyncTaskLoader;
import android.support.v4.content.Loader;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.SearchView;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter; public class MainActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor> { private ListView lv_contacts;
private SearchView msv_name;
private static ContentResolver mResolver;
private SimpleCursorAdapter mAdapter;
private LoaderManager manager; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//获取控件
msv_name = (SearchView) findViewById(R.id.sv_name);
lv_contacts = (ListView) findViewById(R.id.list_item);
//创建适配器
mAdapter = new SimpleCursorAdapter(this, R.layout.list_item,null,new String[]{"_id","display_name"},new int[]{R.id.tv_id,R.id.tv_name},SimpleCursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
lv_contacts.setAdapter(mAdapter);
//创建loader加载器,并初始化
manager = getSupportLoaderManager();
manager.initLoader(1,null,this);
//获取ContentResolver
mResolver = getContentResolver();
} @Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) { return new MyLoader(this,args);
} @Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) { mAdapter.swapCursor(data);
//为SearchView设置监听
msv_name.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
} @Override
public boolean onQueryTextChange(String newText) {
Bundle args = new Bundle();
args.putString("name",newText);
manager.restartLoader(1,args,MainActivity.this);
return true;
}
});
} @Override
public void onLoaderReset(Loader<Cursor> loader) {
mAdapter.swapCursor(null);
}
//自定义Loader
static class MyLoader extends AsyncTaskLoader<Cursor>
{
private Bundle args;
public MyLoader(Context context,Bundle args) {
super(context);
this.args = args;
} @Override
protected void onStartLoading() {
super.onStartLoading();
//强制加载
forceLoad();
} @Override
public Cursor loadInBackground() {
//进行耗时操作
Uri uri = ContactsContract.RawContacts.CONTENT_URI;
if (args != null) { Cursor cursor = mResolver.query(uri, new String[]{"_id", "display_name"}, "display_name like ?", new String[]{"%" + args.getString("name") + "%"}, null);
return cursor;
}else
{
Cursor cursor = mResolver.query(uri, new String[]{"_id", "display_name"}, null, null, null);
return cursor;
}
}
}
}在这个简单的小程序里有几个我犯的小问题,提醒一下:
1)包的一致性
2)
 protected void onStartLoading() {
super.onStartLoading();
//强制加载
forceLoad();
}

Loader加载器的更多相关文章

  1. webpack loader加载器

    配置loader,通过加载器处理文件,例如css sass less等,告诉webpack每一种文件都需要使用什么来加载器来处理. 1.node.js安装好之后也会自动默认安装好npm,所以cmd c ...

  2. 使用webpack loader加载器

    了解webpack请移步webpack初识! 什么是loader loaders 用于转换应用程序的资源文件,他们是运行在nodejs下的函数 使用参数来获取一个资源的来源并且返回一个新的来源(资源的 ...

  3. 恶意软件开发——编写第一个Loader加载器

    一.什么是shellcode loader? 上一篇文章说了,我们说到了什么是shellcode,为了使我们的shellcode加载到内存并执行,我们需要shellcode加载器,也就是我们的shel ...

  4. webpack配置常用loader加载器

    webapck中使用loader的方法有三种 使用loader之前必须运行安装 : npm install --save-dev xxx-loader (1)通过CLI : 命令行中运行 webpac ...

  5. AMD加载器实现笔记(三)

    上一篇文章中我们为config添加了baseUrl和packages的支持,那么这篇文章中将会看到对shim与paths的支持. 要添加shim与paths,第一要务当然是了解他们的语义与用法.先来看 ...

  6. Webpack 常见静态资源处理 - 模块加载器(Loaders)+ExtractTextPlugin插件

    Webpack 常见静态资源处理 - 模块加载器(Loaders)+ExtractTextPlugin插件 webpack系列目录 webpack 系列 一:模块系统的演进 webpack 系列 二: ...

  7. CI框架 -- 核心文件 之 Loader.php(加载器)

    顾名思义,装载器就是加载元素的,使用CI时,经常加载的有: 加载类库文件:$this->load->library()   加载视图文件:$this->load->view() ...

  8. 操作系统的 (program)loader(程序加载器)

    在计算机科学中,加载器(也叫程序加载器)属于操作系统的一部分,用于加载程序(programs)和库(libraries).加载器是执行程序和代码必不可少的组件,正是它负责将程序送入内存,为程序的运行提 ...

  9. SuperSocket命令加载器 (Command Loader)

    在某些情况下,你可能希望通过直接的方式来加载命令,而不是通过自动的反射. 如果是这样,你可以实现你自己的命令加载器 (Command Loader): public interface IComman ...

随机推荐

  1. Tornado框架

    Tornado介绍 Tornado 是 FriendFeed 使用的可扩展的异步非阻塞式 web 服务器及其相关工具的开源版本.这个 Web 框架看起来有些像web.py(豆瓣用这个写的) 或者 Go ...

  2. call、apply、bind的区别

    me.setname.call(me,"dpd","dpd12");      通过call执行say方法 ,第一个参数为作用对象,后边的一些列参数作为实参传入 ...

  3. SEO技巧汇集

    每个人都喜欢好用的技巧,对吗?这里有55个用于搜索引擎优化的小技巧,甚至你的老妈用起来都易如反掌.哦,不是我的老妈,但你明白我的意思.这意味着网页设计师和SEO新手中大部分人都能迅速上手,没有任何困难 ...

  4. Junit很少出现的一个问题 No tests found matching ...

    java.lang.Exception: No tests found matching [{ExactMatcher:fDisplayName=test2], {ExactMatcher:fDisp ...

  5. springmvc(1)DispatcherServlet源码简单解析

    springmvc的简单配置 1.首先需要在web.xml中配置DispatcherServlet,这个类是springmvc的核心类,所以的操作都是由这里开始,并且大部分都是在这里面实现的,比如各种 ...

  6. mysql学习笔记 第五天

    使用分区数据表: 分区数据表和merge数据表具有相似的作用,但是分区数据表确确实实是一个数据表 ,不像merge是列出数据表的逻辑关系,并且分区数据表可以包括像myisam以外的 的数据表.创建分区 ...

  7. iOS AFNetworking 打印从服务器返回的错误提示信息

    每次做项目的时候都会在网络请求时候测试接口的时候会出现一些不同的错误,而控制台打印的错误提示信息都是data类型,看不出提示的错误的信息是什么.后面经过一些查阅发现其实是可以把这个转变为string的 ...

  8. jquery学习笔记:获取下拉框的值和下拉框的txt

    <div class="form-group"> <select class="form-control" id="iv_level ...

  9. struts工程建立配置细节

    ActionForm ActionForm是用于存放表单提交的数据. 1.一个action是否必须配置一个actionForm,可以没有2.一个action是否可以配置多个表单?不可以,最多一个 在j ...

  10. java内存模型-锁

    锁的释放-获取建立的 happens before 关系 锁是 java 并发编程中最重要的同步机制.锁除了让临界区互斥执行外,还可以让释放锁的线程向获取同一个锁的线程发送消息.下面是锁释放-获取的示 ...