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 ...
随机推荐
- 四、BLE(中)
1.1 GATT Manager GATT MGR模块管理所有的GATT服务,同时也是连接GATT模块与GATT ServiceS模块的桥梁. 1.1.1 主要功能模块 先来看一张该 ...
- iOS开发的一些奇巧淫技
TableView不显示没内容的Cell怎么办? 类似这种,我不想让下面那些空的显示. 很简单. self.tableView.tableFooterView = [[UIView alloc] in ...
- angularJS配合bootstrap动态加载弹出提示内容
1.bootstrp的弹出提示 bootstrap已经帮我们封装了非常好用的弹出提示Popover. http://v3.bootcss.com/javascript/#popovers 2.自定义p ...
- MVC之前的那点事儿系列(7):WebActivator的实现原理详解
文章内容 上篇文章,我们分析如何动态注册HttpModule的实现,本篇我们来分析一下通过上篇代码原理实现的WebActivator类库,WebActivator提供了3种功能,允许我们分别在Http ...
- Tigase XMPP Server的安装
Tigase和OpenFire都是基于XMPP(Extensible Messaging and Presence Protocol, 可扩展通讯和表示协议)的,主要功能是实现消息的即时通信.Goog ...
- Android退出时关闭所有Activity的方法
Android退出时,有的Activity可能没有被关闭.为了在Android退出时关闭所有的Activity,设计了以下的类: //关闭Activity的类 public class CloseAc ...
- android FragmentActivity+FragmentTabHost+Fragment框架布局
这周比较闲,计划系统的学习一下android开发,我本是一名IOS程序员,对手机开发还是有自己的一套思路的, 固这套思路用到我当前学android上了,先选择从Main页面的tabbar部分代码入手, ...
- Scalaz(33)- Free :算式-Monadic Programming
在任何模式的编程过程中都无法避免副作用的产生.我们可以用F[A]这种类型模拟FP的运算指令:A是可能产生副作用的运算,F[_]是个代数数据类型ADT(Algebraic Data Type),可以实现 ...
- C语言关键字、标识符和注释
一.关键字 C语言提供的有特殊含义的符号,共32个. 在Xcode中关键字全部高亮显示,关键字全部都为小写.如return.int等. 二.标识符 定义:标识符是程序员在程序中自定义的一些符号和名称. ...
- Python自动化测试工具Splinter简介和使用实例
Splinter 快速介绍 官方网站:http://splinter.cobrateam.info/ 官方介绍: Splinter is an open source tool for testing ...