Loader装载器详解
2016-09-19 21:50
155 查看
1.装载器从android3.0开始引进。它使得在activity或fragment中异步加载数据变得简单。当成批显示数据的时候,为了使用户体验更好,需要进行异步装载。也就是说,让未显示数据的ListView等UI组件或控件先显示,避免出现白屏的尴尬现象,同时在后台下载数据,等下载完成后再更新ListView组件。这样尽管用户不会立刻看到数据,但是也不至于网络速度缓慢或服务器响应不及时而造成假死现象。
2.官方API介绍装载器具有如下特性:
它们对每个Activity和Fragment都有效;
他们提供了异步加载数据的能力;
它拥有一个数据改变通知机制,当数据源做出改变时会及时通知。
也就是可以监听数据源,一旦数据源发生变化,Loader会感知这些变化;
当Cursor 发生变化时,会自动加载数据,因此并不需要再重新进行数据查询。
android设计Loader的初衷是想让大家像CursorLoader的做法一样,通过loader去维护数据,每次启动loader时先检查有没有旧的数据并把旧的数据先deliver给用户,然后再考虑要不要重新加载新的数据。
3.在使用装载器时,会涉及很多类和接口,在下表中对它们总结一下:
4.类目录结构:
①API11中开始加入Loader:
java.lang.Object
↳ android.content.Loader<D>
↳ android.content.AsyncTaskLoader<D>
子类:
java.lang.Object
↳ android.content.Loader<D>
↳ android.content.AsyncTaskLoader<D>
↳ android.content.CursorLoader
②为了兼容1.6以下版本:
java.lang.Object
↳ android.support.v4.content.Loader<D>
↳ android.support.v4.content.AsyncTaskLoader<D>
子类:
java.lang.Object
↳ android.support.v4.content.Loader<D>
↳ android.support.v4.content.AsyncTaskLoader<D>
↳ android.support.v4.content.CursorLoader
5. CursorLoader实现数据加载的步骤:
①创建LoaderManager对象:通过getLoaderManager()或getSupportLoaderManager()方法来实现。如果是继承于FragmentActivity类,则使用getSupportLoaderManager()方法来创建LoaderManger对象,否则使用前者创建即可;
②初始化LoaderManager对象:调用initLoader()方法来初始化;
initLoader()方法有以下参数:
一个唯一ID来标志装载器
可选的参数,用于装载器初始化时
一个LoaderManager.LoaderCallbacks的实现。被LoaderManager调用以报告装载器的事件。一般窗体都实现了这个接口,所以传的是它自己:this;
initLoader()保证一个装载器被初始化并激活.它具有两种可能的结果:
如果ID所指的装载器已经存在,那么这个装载器将被重用;
如果装载器不存在,initLoader()就触发LoaderManager.LoaderCallbacks中的回调方法onCreateLoader()。这是实例化并返回一个新Loader的地方。
③操作ListView控件对象:先findViewById(),然后setAdapter();
备注:此时必须使用SimpleCursorAdater适配器,而构建适配器的时候,第三个参数Cursor设置为null,最后一个参数:flags必须是:CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER。
④重写onCreateLoader()方法。返回CursorLoader的构造方法。
例如: return new CursorLoader(this, uri, null, null, null, null);
备注:new CursorLoader()的参数:
• uri —要获取的内容的URI;
• projection —要返回的列组成的数组。传入null 将会返回所有的列,但这样会导致低效;
• selection —表明哪些行将被返回,相当于SQL语句中的WHERE条件 (不包括WHERE关键词)。传入null 将返回所有的行;
• selectionArgs —Where语句中的'?’组成的数组。
• sortOrder —如何排序,相当于SQL语句中的 ORDER BY 语句(不包括ORDER BY关键词)。传入null将使用默认顺序。
6.使用CursorLoader来读取联系人的姓名及号码的实例代码:
①MainActivity的代码,代码的实现顺序按照代码中的标记进行,为了向下兼容,全部实现v4包下的类:
②main_activity.xml布局文件:
③ListView的条目布局item.xml:
④查询结果如下所示:
![](http://img.blog.csdn.net/20160919213526363?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
7. AsyncTaskLoader实现数据加载的步骤:
①创建LoaderManager对象:通过getLoaderManager()或getSupportLoaderManager()方法来实现。如果是继承于FragmentActivity类,则使用getSupportLoaderManager()方法来创建LoaderManger对象,否则使用前者创建即可;
②初始化LoaderManager对象:调用initLoader()方法来初始化;
initLoader()方法有以下参数:
一个唯一ID来标志装载器
可选的参数,用于装载器初始化时
一个LoaderManager.LoaderCallbacks的实现。被LoaderManager调用以报告装载器的事件。一般窗体都实现了这个接口,所以传的是它自己:this;
initLoader()保证一个装载器被初始化并激活.它具有两种可能的结果:
如果ID所指的装载器已经存在,那么这个装载器将被重用;
如果装载器不存在,initLoader()就触发LoaderManager.LoaderCallbacks中的回调方法onCreateLoader()。这是实例化并返回一个新Loader的地方。
③操作ListView控件对象:先findViewById(),然后setAdapter();
备注:此时必须使用SimpleCursorAdater适配器,而构建适配器的时候,第三个参数Cursor设置为null,最后一个参数:flags必须是:CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER。
④自定义Loader,作为onCreateLoader()的返回值(也就是说onCreateLoader()方法必须返回自定义Loader的实例);
自定义Loader要继承于AsyncTaskLoader<Cursor>;
必须要有构造方法;
必须重写onStartLoading()、loadInBackground() 、deliverResult()。而且要在onStartLoading中调用forceLoad()方法才能依次调用下一个即将执行的方法。
在loadInBackground()方法中执行数据库查询,返回Cursor;
在deliverResult()方法中执行跟适配器交换数据的操作。adapter.swapCursor(data)。
⑤SimpleCursorAdapter构造方法的参数讲解。
方法原型:new SimpleCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to , int flags) ;
参数:
1)Context context, 这个与 SimpleListItemFactory 相关的 ListView 所处运行上下文(context)。也就是这个 ListView 所在的 Activity。
2)int layout, 显示 list item 的 布局文件。这个 layout 文件中至少要包含在 "to" 参数中命名的 views。
3)Cursor c, 数据库的光标( Cursor )。如果 cursor 无效,则该参数可以为 null
4)String[] from, 指定 column 中的哪些列的数据将绑定(显示)到 UI 中。如果 cursor 无效, 则该参数可为 null。
5)int[] to, 指定用于显示 "from" 参数指定的数据列表的 views。 这些 views 必须都是 TextViews。 "from" 参数的前 N 个值(valus)和 "to" 参数的前 N 个 views 是一一对应的关系。如果 cursor 无效,则该参数可为
null。
6)flags,用于定义适配器行为的标志位。
Flags used to determine the behavior of the adapter; may be any combination of
FLAG_AUTO_REQUERY(常量值:1 )从 API11 开始已经废弃。因为他会在应用程序的 UI 线程中执行游标查询操作, 导致响应缓慢甚至应用程序无响应(ANR)的错误。作为替代方案,请使用 LoaderManager 和 AsyncTaskLoader、CursorLoader。
如果设置FLAG_REGISTER_CONTENT_OBSERVER(常量值:2),适配器会在Cursor上注册一个内容观测器,当通知到达时会调用 onContentChanged() 方法。
⑥LoaderManager.LoaderCallbacks主要回调方法:
1)onCreateLoader() :初始化并返回一个新的Loader;
当你试图去操作一个装载器时(比如,通过initLoader()),会检查是否指定ID的装载器已经存在.如果它不存在,将会触发LoaderManager.LoaderCallbacks 的方法onCreateLoader();
2)onLoadFinished():当一个装载器完成了它的装载过程后被调用;
这个方法是在前面已创建的装载器已经完成其加载过程后被调用.这个方法保证会在应用到装载器上的数据被释放之前被调用;
3)onLoaderReset() :当一个装载器被重置而其数据无效时被调用。
所谓Loader的重置,就是指Loader对象还保留,只是清除Loader中的数据,所以onLoaderReset()方法相当于Loader的销毁方法。因此在onLoaderReset()方法中会找到即将释放的数据的引用,并移除这些引用。移除引用后,GC才可以清除这些数据。当一个已创建的装载器被重置从而使其数据无效时,此方法被调用.此回调使你能发现什么时候数据将被释放。你可以释放对它的引用。
8.使用AsyncTaskLoader来读取短信的地址及短信内容的实例代码:
①MainActivity的代码:
②自定义Loader类的代码:
③main_activity.xml中的布局文件:
④ListView的条目布局item.xml:
2.官方API介绍装载器具有如下特性:
它们对每个Activity和Fragment都有效;
他们提供了异步加载数据的能力;
它拥有一个数据改变通知机制,当数据源做出改变时会及时通知。
也就是可以监听数据源,一旦数据源发生变化,Loader会感知这些变化;
当Cursor 发生变化时,会自动加载数据,因此并不需要再重新进行数据查询。
android设计Loader的初衷是想让大家像CursorLoader的做法一样,通过loader去维护数据,每次启动loader时先检查有没有旧的数据并把旧的数据先deliver给用户,然后再考虑要不要重新加载新的数据。
3.在使用装载器时,会涉及很多类和接口,在下表中对它们总结一下:
Class/Interface | 说明 |
LoaderManager | 一个抽像类,关联到一个Activity或Fragment,管理一个或多个装载器的实例。这帮助一个应用管理那些与Activity或Fragment的生命周期相关的长时间运行的操作。最常见的方式是与一个CursorLoader一起使用,然而应用是可以随便写它们自己的装载器以加载其它类型的数据。 每个activity或fragment只有一个LoaderManager。但是一个LoaderManager可以拥有多个装载器。 |
LoaderManager.LoaderCallbacks | 一个用于客户端与LoaderManager交互的回调接口。例如,你使用回调方法onCreateLoader()来创建一个新的装载器。 |
Loader(装载器) | 一个执行异步数据加载的抽象类。它是加载器的基类。你可以使用典型的CursorLoader,但是你也可以实现你自己的子类。一旦装载器被激活,它们将监视它们的数据源并且在数据改变时发送新的结果。 |
AsyncTaskLoader | 提供一个AsyncTask来执行异步加载工作的抽象类。 |
CursorLoader | AsyncTaskLoader的子类,它查询ContentResolver然后返回一个Cursor。这个类为查询cursor以标准的方式实现了装载器的协议,它的游标查询是通过AsyncTaskLoader在后台线程中执行,从而不会阻塞界面。使用这个装载器是从一个ContentProvider异步加载数据的最好方式。相比之下,通过fragment或activity的API来执行一个被管理的查询就不行了。 |
①API11中开始加入Loader:
java.lang.Object
↳ android.content.Loader<D>
↳ android.content.AsyncTaskLoader<D>
子类:
java.lang.Object
↳ android.content.Loader<D>
↳ android.content.AsyncTaskLoader<D>
↳ android.content.CursorLoader
②为了兼容1.6以下版本:
java.lang.Object
↳ android.support.v4.content.Loader<D>
↳ android.support.v4.content.AsyncTaskLoader<D>
子类:
java.lang.Object
↳ android.support.v4.content.Loader<D>
↳ android.support.v4.content.AsyncTaskLoader<D>
↳ android.support.v4.content.CursorLoader
5. CursorLoader实现数据加载的步骤:
①创建LoaderManager对象:通过getLoaderManager()或getSupportLoaderManager()方法来实现。如果是继承于FragmentActivity类,则使用getSupportLoaderManager()方法来创建LoaderManger对象,否则使用前者创建即可;
②初始化LoaderManager对象:调用initLoader()方法来初始化;
initLoader()方法有以下参数:
一个唯一ID来标志装载器
可选的参数,用于装载器初始化时
一个LoaderManager.LoaderCallbacks的实现。被LoaderManager调用以报告装载器的事件。一般窗体都实现了这个接口,所以传的是它自己:this;
initLoader()保证一个装载器被初始化并激活.它具有两种可能的结果:
如果ID所指的装载器已经存在,那么这个装载器将被重用;
如果装载器不存在,initLoader()就触发LoaderManager.LoaderCallbacks中的回调方法onCreateLoader()。这是实例化并返回一个新Loader的地方。
③操作ListView控件对象:先findViewById(),然后setAdapter();
备注:此时必须使用SimpleCursorAdater适配器,而构建适配器的时候,第三个参数Cursor设置为null,最后一个参数:flags必须是:CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER。
④重写onCreateLoader()方法。返回CursorLoader的构造方法。
例如: return new CursorLoader(this, uri, null, null, null, null);
备注:new CursorLoader()的参数:
• uri —要获取的内容的URI;
• projection —要返回的列组成的数组。传入null 将会返回所有的列,但这样会导致低效;
• selection —表明哪些行将被返回,相当于SQL语句中的WHERE条件 (不包括WHERE关键词)。传入null 将返回所有的行;
• selectionArgs —Where语句中的'?’组成的数组。
• sortOrder —如何排序,相当于SQL语句中的 ORDER BY 语句(不包括ORDER BY关键词)。传入null将使用默认顺序。
6.使用CursorLoader来读取联系人的姓名及号码的实例代码:
①MainActivity的代码,代码的实现顺序按照代码中的标记进行,为了向下兼容,全部实现v4包下的类:
<span style="font-size:14px;">package com.example.administrator.loadertest; 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.CursorLoader; import android.support.v4.content.Loader; import android.support.v4.widget.SimpleCursorAdapter; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.View; import android.widget.Adapter; import android.widget.Button; import android.widget.ListView; public class MainActivity extends AppCompatActivity implements View.OnClickListener { private LoaderManager supportLoaderManager; private SimpleCursorAdapter adapter; private Button btn; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //7.强制关闭loader的按钮 btn = (Button) findViewById(R.id.btn); btn.setOnClickListener(this); //5.把查询到的数据显示到listview上 ListView lv = (ListView) findViewById(R.id.lv); adapter = new SimpleCursorAdapter(MainActivity.this, R.layout.item, null, new String[]{ContactsContract.Contacts.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER }, new int[]{R.id.tv_name, R.id.tv_number}, //要显示的参数所对应的布局控件 SimpleCursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER); //指定该常量之后会对数据源进行监听 lv.setAdapter(adapter); //1.获取loader管理器 supportLoaderManager = getSupportLoaderManager(); //2.通过loader管理器初始化出Loader supportLoaderManager.initLoader(1, null, new LoaderManager.LoaderCallbacks<Cursor>() { //创建loader时调用此方法,在子线程中进行,把查询到的数据返回给onLoadFinished @Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { //3.初始化CursorLoader对象,并为其指定要查询的表及列 CursorLoader cursorLoader = new CursorLoader(MainActivity.this, ContactsContract.CommonDataKinds.Phone.CONTENT_URI, //查询content(联系人)表 new String[]{"_id", ContactsContract.Contacts.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER}, null,null,null); return cursorLoader; } //加载完成,接收onCreateLoader返回的结果数据,在主线程中进行数据更新 @Override public void onLoadFinished(Loader<Cursor> loader, Cursor data) { //6.改变数据源,初始化adapter时穿进去的cursor为空,程序运行到此处有数据了,再改变其值 adapter.changeCursor(data); //4.onCreateLoader方法返回的数据封装在了data中,循环遍历取出其中的数据 while (data.moveToNext()){ String name = data.getString(data.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)); String number = data.getString(data.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); Log.e("name", name); Log.e("number", number); } } //重置加载器,activity销毁的时候不需要数据时调用此方法 @Override public void onLoaderReset(Loader<Cursor> loader) { } }); } @Override public void onClick(View v) { //loader管理器通过id去销毁某一个loader supportLoaderManager.destroyLoader(1); } } </span>
②main_activity.xml布局文件:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.administrator.loadertest.MainActivity" android:orientation="vertical"> <Button android:id="@+id/btn" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="关闭loader" /> <ListView android:id="@+id/lv" android:layout_width="match_parent" android:layout_height="match_parent"> </ListView> </LinearLayout>
③ListView的条目布局item.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:id="@+id/tv_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="18sp"/> <TextView android:id="@+id/tv_number" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="18sp"/> </LinearLayout>
④查询结果如下所示:
7. AsyncTaskLoader实现数据加载的步骤:
①创建LoaderManager对象:通过getLoaderManager()或getSupportLoaderManager()方法来实现。如果是继承于FragmentActivity类,则使用getSupportLoaderManager()方法来创建LoaderManger对象,否则使用前者创建即可;
②初始化LoaderManager对象:调用initLoader()方法来初始化;
initLoader()方法有以下参数:
一个唯一ID来标志装载器
可选的参数,用于装载器初始化时
一个LoaderManager.LoaderCallbacks的实现。被LoaderManager调用以报告装载器的事件。一般窗体都实现了这个接口,所以传的是它自己:this;
initLoader()保证一个装载器被初始化并激活.它具有两种可能的结果:
如果ID所指的装载器已经存在,那么这个装载器将被重用;
如果装载器不存在,initLoader()就触发LoaderManager.LoaderCallbacks中的回调方法onCreateLoader()。这是实例化并返回一个新Loader的地方。
③操作ListView控件对象:先findViewById(),然后setAdapter();
备注:此时必须使用SimpleCursorAdater适配器,而构建适配器的时候,第三个参数Cursor设置为null,最后一个参数:flags必须是:CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER。
④自定义Loader,作为onCreateLoader()的返回值(也就是说onCreateLoader()方法必须返回自定义Loader的实例);
自定义Loader要继承于AsyncTaskLoader<Cursor>;
必须要有构造方法;
必须重写onStartLoading()、loadInBackground() 、deliverResult()。而且要在onStartLoading中调用forceLoad()方法才能依次调用下一个即将执行的方法。
在loadInBackground()方法中执行数据库查询,返回Cursor;
在deliverResult()方法中执行跟适配器交换数据的操作。adapter.swapCursor(data)。
⑤SimpleCursorAdapter构造方法的参数讲解。
方法原型:new SimpleCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to , int flags) ;
参数:
1)Context context, 这个与 SimpleListItemFactory 相关的 ListView 所处运行上下文(context)。也就是这个 ListView 所在的 Activity。
2)int layout, 显示 list item 的 布局文件。这个 layout 文件中至少要包含在 "to" 参数中命名的 views。
3)Cursor c, 数据库的光标( Cursor )。如果 cursor 无效,则该参数可以为 null
4)String[] from, 指定 column 中的哪些列的数据将绑定(显示)到 UI 中。如果 cursor 无效, 则该参数可为 null。
5)int[] to, 指定用于显示 "from" 参数指定的数据列表的 views。 这些 views 必须都是 TextViews。 "from" 参数的前 N 个值(valus)和 "to" 参数的前 N 个 views 是一一对应的关系。如果 cursor 无效,则该参数可为
null。
6)flags,用于定义适配器行为的标志位。
Flags used to determine the behavior of the adapter; may be any combination of
FLAG_AUTO_REQUERYand
FLAG_REGISTER_CONTENT_OBSERVER。
FLAG_AUTO_REQUERY(常量值:1 )从 API11 开始已经废弃。因为他会在应用程序的 UI 线程中执行游标查询操作, 导致响应缓慢甚至应用程序无响应(ANR)的错误。作为替代方案,请使用 LoaderManager 和 AsyncTaskLoader、CursorLoader。
如果设置FLAG_REGISTER_CONTENT_OBSERVER(常量值:2),适配器会在Cursor上注册一个内容观测器,当通知到达时会调用 onContentChanged() 方法。
⑥LoaderManager.LoaderCallbacks主要回调方法:
1)onCreateLoader() :初始化并返回一个新的Loader;
当你试图去操作一个装载器时(比如,通过initLoader()),会检查是否指定ID的装载器已经存在.如果它不存在,将会触发LoaderManager.LoaderCallbacks 的方法onCreateLoader();
2)onLoadFinished():当一个装载器完成了它的装载过程后被调用;
这个方法是在前面已创建的装载器已经完成其加载过程后被调用.这个方法保证会在应用到装载器上的数据被释放之前被调用;
3)onLoaderReset() :当一个装载器被重置而其数据无效时被调用。
所谓Loader的重置,就是指Loader对象还保留,只是清除Loader中的数据,所以onLoaderReset()方法相当于Loader的销毁方法。因此在onLoaderReset()方法中会找到即将释放的数据的引用,并移除这些引用。移除引用后,GC才可以清除这些数据。当一个已创建的装载器被重置从而使其数据无效时,此方法被调用.此回调使你能发现什么时候数据将被释放。你可以释放对它的引用。
8.使用AsyncTaskLoader来读取短信的地址及短信内容的实例代码:
①MainActivity的代码:
package com.example.administrator.asynctasktest2; import android.database.Cursor; import android.provider.ContactsContract; import android.provider.Telephony; import android.support.v4.app.LoaderManager; import android.support.v4.content.CursorLoader; import android.support.v4.content.Loader; import android.support.v4.widget.SimpleCursorAdapter; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.widget.Adapter; import android.widget.ListView; public class MainActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor> { private LoaderManager supportLoaderManager; private SimpleCursorAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //给listview设置数据 ListView lv = (ListView) findViewById(R.id.lv); adapter = new SimpleCursorAdapter(this, R.layout.item, null,new String[]{Telephony.Sms.ADDRESS, Telephony.Sms.BODY}, new int[]{R.id.tv_address,R.id.tv_body}, SimpleCursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER); lv.setAdapter(adapter); supportLoaderManager = getSupportLoaderManager(); supportLoaderManager.initLoader(1,null,this); } @Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { MyAsyncLoader loader = new MyAsyncLoader(MainActivity.this); return loader; } @Override public void onLoadFinished(Loader<Cursor> loader, Cursor data) { //更新adapter中的cursor数据 adapter.changeCursor(data); String address = data.getString(data.getColumnIndex(Telephony.Sms.ADDRESS)); String body = data.getString(data.getColumnIndex(Telephony.Sms.BODY)); Log.e("address",address); Log.e("body",body); } @Override public void onLoaderReset(Loader<Cursor> loader) { } }
②自定义Loader类的代码:
package com.example.administrator.asynctasktest2; import android.annotation.SuppressLint; import android.content.ContentResolver; import android.content.Context; import android.database.Cursor; import android.provider.Telephony; import android.support.v4.content.AsyncTaskLoader; /** * Created by Administrator on 2016/9/19. */ public class MyAsyncLoader extends AsyncTaskLoader<Cursor> { public MyAsyncLoader(Context context) { super(context); } //在后台执行,查询短信 @SuppressLint("NewApi") @Override public Cursor loadInBackground() { ContentResolver contentResolver = getContext().getContentResolver(); Cursor cursor = contentResolver.query(Telephony.Sms.CONTENT_URI, new String[]{"_id", Telephony.Sms.ADDRESS, Telephony.Sms.BODY}, null, null, null); return cursor; } //开始进行加载 @Override protected void onStartLoading() { super.onStartLoading(); //强制进行加载 forceLoad(); } }
③main_activity.xml中的布局文件:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.administrator.asynctasktest2.MainActivity" android:orientation="vertical"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" /> <ListView android:id="@+id/lv" android:layout_width="match_parent" android:layout_height="match_parent"> </ListView> </LinearLayout>
④ListView的条目布局item.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/tv_address" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:id="@+id/tv_body" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout>
相关文章推荐
- Android Loader详解一:概述
- 传智播客Java web之 Servlet中的类装载器详解
- ClassLoader 详解
- Android Loader详解三:重启与回调
- android loader 详解
- Android-Universal-Image-Loader应用详解
- Android Loader详解四:回调及完整例子
- Android Loader详解
- Android Loader详解二:使用加载器
- JAVA类装载器classloader和命名空间namespace
- Android Loader详解二:使用加载器
- Android Loader详解三:重启与回调
- Android Loader详解四:回调及完整例子
- Android Loader详解二:使用加载器
- ClassLoader详解
- SQL*Loader 详解
- Android Loader详解一:概述
- Android Loader详解一:概述
- 类装载器ClassLoader
- Android-Universal-Image-Loader应用详解