CursorLoader与ContentProvider结合,实现异步加载
2016-05-21 09:22
721 查看
使用CursorLoader和ContentProvider结合,可以实现异步更新数据
CursorLoader介绍
我们知道,Loader一个抽象的类,用于执行异步加载数据,这个Loader对象可以监视数据源的改变和在内容改变后,以新数据的内容改变UI的展示。它是一个抽象接口,所有需要实现的Loader功能的类都需要实现这个接口,但是如果需要自己开发一个装载机的话,一般并不推荐继承Loader接口,
而是继承它的子类 AsyncTaskLoader ,这是一个以AsyncTask框架执行的异步加载。
Android中还提供了一个 CursorLoader 类,它是 AsyncTaskLoader 的子类,一个异步的加载数据的类,
通过ContentResolver的标准查询并返回一个Cursor 。这个类实现了Loader的协议,以一种标准的方式查询Cursor。
CursorLoader类有两个构造函数, 推荐使用第二个 ,因为使用第一个构造函数,需要还需要通过CursorLoader提供的一些了getXXX()方法设置对应的属性
。两个构造方法如下:
CursorLoader(Context context) 使用此构造方法时,需要使用setXXX()设置相应的属性,否则不能进行查询
CursorLoader(Context context,Uri uri,String[] projection,String selection ,String[] selectionArgs,String sortOrder)shi
CursorLoader 会显示调用ContentProvier 的query方法进行查询,在ContentProvider 的query方法中应该写
如果对Loader机制不太了解的,请看前篇文章
Android Loader机制,实现异步加载数据
这里的ContentProvider为了简便,我就只写了query()方法,写多了不便于理解
/** * 使用ContentProvider提供数据的查询功能 * * @author TerryYang * */ public class PersonProvider extends ContentProvider { private MyDBHelper dbHelper; public PersonProvider(){ } @Override public int delete(Uri arg0, String arg1, String[] arg2) { // TODO Auto-generated method stub return 0; } @Override public String getType(Uri arg0) { // TODO Auto-generated method stub return null; } @Override public Uri insert(Uri arg0, ContentValues arg1) { // TODO Auto-generated method stub return null; } @Override public boolean onCreate() { // 初始化数据持久层 dbHelper = new MyDBHelper(getContext()); return false; } @Override public Cursor query(Uri arg0, String[] arg1, String arg2, String[] arg3, String arg4) { // 使用Loader 时,会首先调用query() Log.v("LOG","PersonProvider -- query()"); SQLiteDatabase db = dbHelper.getReadableDatabase(); Cursor cursor = db.rawQuery("select * from person", null); return cursor; } @Override public int update(Uri arg0, ContentValues arg1, String arg2, String[] arg3) { // TODO Auto-generated method stub return 0; } }
这里的ContentProvider提供了query(),需要使用ContentProvier的其他方法,自己重写即可。
public class MainActivity extends ActionBarActivity implements LoaderCallbacks<Cursor> { private ListView mList; private CursorAdapter mAdapter; private Cursor mCursor; private MyDBHelper mDBHelper; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mList = (ListView) findViewById(R.id.id_lv_person); mDBHelper = new MyDBHelper(this); SQLiteDatabase database = mDBHelper.getReadableDatabase(); mCursor = database.rawQuery("SELECT * FROM person", null); makeCursorAdapter(); // 使用Loader异步加载数据 initLoader(); mList.setAdapter(mAdapter); } private void initLoader() { getLoaderManager().initLoader(0, null, this); } /** * 初始化CursorAdapter */ private void makeCursorAdapter() { mAdapter = new CursorAdapter(this, mCursor) { // 初次创建View时,找到布局和控件 @Override public View newView(Context context, Cursor cursor, ViewGroup arg2) { LayoutInflater inflater = LayoutInflater.from(context); View view = inflater.inflate(R.layout.item_list, null); ViewHolder holder = new ViewHolder(); holder.name = (TextView) view.findViewById(R.id.id_tv_name); holder.age = (TextView) view.findViewById(R.id.id_tv_age); view.setTag(holder); return view; } // 绑定View时,复用布局 @Override public void bindView(View view, Context context, Cursor cursor) { ViewHolder holder = (ViewHolder) view.getTag(); String name = cursor.getString(cursor.getColumnIndex("name")); int age = cursor.getInt(cursor.getColumnIndex("age")); holder.name.setText(name); holder.age.setText(age + ""); } // 在匿名内部类声明内部类需使用final修饰 final class ViewHolder { TextView name; TextView age; } }; } // 插入测试数据 public void insertData(View view) { SQLiteDatabase db = mDBHelper.getWritableDatabase(); db.execSQL("insert into person(name, age) values('xxx',21)"); db.close(); getLoaderManager().restartLoader(0, null, this); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } // 这里 创建CursorLoader的过程,就 包含调用query(),进行查询的过程 @Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { Uri uri = Uri.parse("content://com.terry.Person/person"); CursorLoader cursorLoader = new CursorLoader(this, uri, null, null, null, null); return cursorLoader; } @Override public void onLoadFinished(Loader<Cursor> arg0, Cursor cursor) { mAdapter.swapCursor(cursor); } @Override public void onLoaderReset(Loader<Cursor> arg0) { mAdapter.swapCursor(null); } }
注意,每次调insert()时,需要使用*restartLoader()重新启动loader,即可显示异步加的数据.
每次使用InsertData插入测试数据时,在ListView显示已经插入的数据.
相关文章推荐
- php curl开启配置
- phpstorm——配置interpreter——找了半天终于ok
- php get set方法深入理解
- php编码规范
- PHP每周一个函数——strrchr() 函数
- php一种分类的排序方法
- yii2分页的基本使用及其配置详解
- Laravel5学生成绩管理系统-05-分页
- Laravel5学生成绩管理系统-06-资源控制器删除学生
- tftp_nfs_samba搭建
- phpstorm中的项目配置开发环境
- yii2-gii的详细操作步骤
- 7——PHP选择结构
- yii2搭建完美后台并实现rbac权限控制案例 - 之权限控制详细操作步骤
- 6——PHP顺序结构&&字符串连接符
- yii2搭建完美后台并实现rbac权限控制案例 - 之菜单menu详细教程
- php 保存到mysql数据库中的中文乱码
- 拥有编译器影子的PHP视图引擎Smarty
- PHP单例模式编写
- PHP单例模式编写