Loader加载器
今天学到了这个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加载器的更多相关文章
- webpack loader加载器
配置loader,通过加载器处理文件,例如css sass less等,告诉webpack每一种文件都需要使用什么来加载器来处理. 1.node.js安装好之后也会自动默认安装好npm,所以cmd c ...
- 使用webpack loader加载器
了解webpack请移步webpack初识! 什么是loader loaders 用于转换应用程序的资源文件,他们是运行在nodejs下的函数 使用参数来获取一个资源的来源并且返回一个新的来源(资源的 ...
- 恶意软件开发——编写第一个Loader加载器
一.什么是shellcode loader? 上一篇文章说了,我们说到了什么是shellcode,为了使我们的shellcode加载到内存并执行,我们需要shellcode加载器,也就是我们的shel ...
- webpack配置常用loader加载器
webapck中使用loader的方法有三种 使用loader之前必须运行安装 : npm install --save-dev xxx-loader (1)通过CLI : 命令行中运行 webpac ...
- AMD加载器实现笔记(三)
上一篇文章中我们为config添加了baseUrl和packages的支持,那么这篇文章中将会看到对shim与paths的支持. 要添加shim与paths,第一要务当然是了解他们的语义与用法.先来看 ...
- Webpack 常见静态资源处理 - 模块加载器(Loaders)+ExtractTextPlugin插件
Webpack 常见静态资源处理 - 模块加载器(Loaders)+ExtractTextPlugin插件 webpack系列目录 webpack 系列 一:模块系统的演进 webpack 系列 二: ...
- CI框架 -- 核心文件 之 Loader.php(加载器)
顾名思义,装载器就是加载元素的,使用CI时,经常加载的有: 加载类库文件:$this->load->library() 加载视图文件:$this->load->view() ...
- 操作系统的 (program)loader(程序加载器)
在计算机科学中,加载器(也叫程序加载器)属于操作系统的一部分,用于加载程序(programs)和库(libraries).加载器是执行程序和代码必不可少的组件,正是它负责将程序送入内存,为程序的运行提 ...
- SuperSocket命令加载器 (Command Loader)
在某些情况下,你可能希望通过直接的方式来加载命令,而不是通过自动的反射. 如果是这样,你可以实现你自己的命令加载器 (Command Loader): public interface IComman ...
随机推荐
- 【原创】Kakfa cluster包源代码分析
kafka.cluster包定义了Kafka的基本逻辑概念:broker.cluster.partition和replica——这些是最基本的概念.只有弄懂了这些概念,你才真正地使用kakfa来帮助完 ...
- C#去掉HTML标记
该方法亲测可行,下面直接粘贴代码. public string RemoveHTMLTags(string htmlStream) { if (htmlStream == null) { throw ...
- 使用DevExpress官方汉化文件对界面进行汉化的过程
在较早期的Dev开发中,基本上都是在使用一个DLL包的汉化文件,如基于13.1的汉化包文件Dxper.LocalizationCHS.Win.v13.1.5.dll,这个汉化包也比较方便,大多数时候复 ...
- [水煮 ASP.NET Web API2 方法论](3-7)默认 Action 请求方式以及 NonActionAttribute
问题 在 Controller 中有一个 public 的方法,但是又不想将这个 publlic 方法暴露成为一个 API. 解决方案 ASP.NET Web API 中,正常是通过 HTTP 谓词来 ...
- html5学习笔记(2)
效果图 以下为源码 <!DOCTYPE html> <html> <head lang="en"> <meta charset=" ...
- SQL查询中in、exists、not in、not exists的用法与区别
1.in和exists in是把外表和内表作hash(字典集合)连接,而exists是对外表作循环,每次循环再对内表进行查询.一直以来认为exists比in效率高的说法是不准确的,如果查询的两个表大小 ...
- LeetCode121:Best Time to Buy and Sell Stock
题目: Say you have an array for which the ith element is the price of a given stock on day i. If you w ...
- 【Java每日一题】20161118
package Nov2016; public class Ques1118 { public static final int NUM = 10000000; public static void ...
- MUI(1)
今天小编用HBuilder+MUI开发移动APP,不用Android原生也不用IOS原生,仅仅用HTML5+MUI.小编也是初学者所以如有不准确的地方望大家指出帮助小编改正,同时也可以促进大家的深入学 ...
- 对Java并发编程的几点思考
1. Threads 和 Runnables 所有的现代操作系统都通过进程和线程来支持并发.进程是通常彼此独立运行的程序的实例,比如,如果你启动了一个Java程序,操作系统产生一个新的进程,与其他程序 ...