您的位置:首页 > 编程语言 > PHP开发

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显示已经插入的数据.

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: