ContentProvider作为Android的四大存储方式之一,有着广泛的应用性,它暴露了数据地址,可以让其他应用访问数据,可以用于存储图片、通讯录等信息,这篇博文将详细介绍ContentProvider、URIMatcher,LoaderManager,cursorAdapter的方法使用与介绍。使用ContentProvider的时候一定要注意在manifest清单文件中像Acticity文件一样,声明其属性。如图所示
此外因为我们是用loadermanager来加载数据,MainAcitivity类要实现LoaderCallback接口。按照惯例我们还是看下谷歌官方文档对contentprovider的解释,ContentProvider管理一个结构化的数据集。它封装了数据,并提供定义数据安全机制。ContentProvider的标准接口实现多线程机制来连接数据,一般是用loaderManager异步加载数据。当你想要访问数据在一个ContentProvider,我们使用ContentResolver对象在应用程序的上下文中作为沟通方法。ContentResolver用来解析请求码返还数据。
我们先看看一下本次介绍的工程的目录结构
MainActivity的代码
package com.example.f14_contentprovider;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.app.LoaderManager;
import android.app.LoaderManager.LoaderCallbacks;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.CursorLoader;
import android.content.Loader;
import android.database.Cursor;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
public class MainActivity extends Activity implements LoaderCallbacks<Cursor> {
private Button button;
private ListView listView;
private LoaderManager loaderManager;
private SimpleCursorAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button) this.findViewById(R.id.button1);
listView = (ListView) this.findViewById(R.id.listView1);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
ContentResolver resolver = getContentResolver();
Uri uri = Uri
.parse("content://com.example.f14_contentprovider.PersonContentProvider/person");
ContentValues values = new ContentValues();
values.put("name", "jack");
values.put("address", "hangzhou");
resolver.insert(uri, values);
loaderManager.restartLoader(1001, null, MainActivity.this);
}
});
loaderManager = getLoaderManager();
loaderManager.initLoader(1001, null, this);
}
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
// TODO Auto-generated method stub
/**
* CursorLoader该类用于加载程序,查询ContentResolver并返回一个指针。这个类实现了装载机协议查询游标的标准方法,
* 基于AsyncTaskLoader执行游标查询在一个后台线程,以便它不会阻止应用程序的UI。
*/
CursorLoader loader = new CursorLoader(this);
Uri uri = Uri
.parse("content://com.example.f14_contentprovider.PersonContentProvider/person");
loader.setUri(uri);
loader.setProjection(new String[] { "name", "address" });
return loader;
}
@SuppressWarnings("deprecation")
@Override
public void onLoadFinished(Loader<Cursor> arg0, Cursor arg1) {
// TODO Auto-generated method stub
List<HashMap<String, String>> list = new ArrayList<HashMap<String, String>>();
// 加载数据
while (arg1.moveToNext()) {
HashMap<String, String> map = new HashMap<String, String>();
map.put("name", arg1.getString(arg1.getColumnIndex("name")));
map.put("address", arg1.getString(arg1.getColumnIndex("address")));
list.add(map);
}
adapter = new SimpleCursorAdapter(this, R.layout.item, arg1,
new String[] { "name", "address" }, new int[] { R.id.textView1,
R.id.textView2 });
listView.setAdapter(adapter);
adapter.notifyDataSetChanged();// 若内容发生变化 触发该方法
}
@Override
public void onLoaderReset(Loader<Cursor> arg0) {
// TODO Auto-generated method stub
}
}
如上所示,在MainAcitivity主方法中,大家可以看到第40-47行代码中,通过内容提供者contentProvider插入数据的时候,是通过contentResolver进行连接,通过其insert方法提供插入指定的数据表和数据完成操作。操作完成后还需要调用loadermanager的restart方法更新一次UI。
PersonContentProvider继承了ContentProvider的方法
package com.example.f14_contentprovider;
import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
//要在manifest文件中注册provider
public class PersonContentProvider extends ContentProvider {
private MyOpenHelper helper;
private static final UriMatcher matcher = new UriMatcher(
UriMatcher.NO_MATCH);// 专门用来匹配URI的类
private static final int PERSONS = 1;
private static final int PERSON = 2;
private ContentResolver resolver;
static {
matcher.addURI("com.example.f14_contentprovider.PersonContentProvider",
"person", PERSONS);
matcher.addURI("com.example.f14_contentprovider.PersonContentProvider",
"person/#", PERSON);
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
// TODO Auto-generated method stub
return 0;
}
// 当您需要匹配一个URI,调用匹配(URI),用来来建立一个查询,返回类型,插入或删除一行。
@Override
public String getType(Uri arg0) {
// TODO Auto-generated method stub
int match = matcher.match(arg0);
switch (match) {
case PERSONS:
return "vnd.android.cursor.dir/person";
case PERSON:
return "vnd.android.cursor.item/person";
default:
return null;
}
}
@Override
public Uri insert(Uri uri, ContentValues values) {
// TODO Auto-generated method stub
SQLiteDatabase database = helper.getWritableDatabase();
long id = database.insert("person", null, values);
Uri rUri = ContentUris.withAppendedId(uri, id);
resolver.notifyChange(rUri, null);
return rUri;
}
@Override
public boolean onCreate() {
// TODO Auto-generated method stub
helper = new MyOpenHelper(getContext());
resolver = getContext().getContentResolver();
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
// TODO Auto-generated method stub
Cursor cursor = null;
int flag = matcher.match(uri);
SQLiteDatabase database = helper.getReadableDatabase();
switch (flag) {
case PERSONS:
cursor=database.query("person", null, null, null,null, null, null);
break;
case PERSON:
long _id = ContentUris.parseId(uri);
String where_value = " _id = " + _id;
if (selection != null && !selection.equals("")) {
where_value += selection;
}
cursor = database.query("person", projection, where_value,
selectionArgs, null, null, sortOrder);
break;
default:
break;
}
cursor.setNotificationUri(resolver, uri);
return cursor;
}
@Override
public int update(Uri arg0, ContentValues arg1, String arg2, String[] arg3) {
// TODO Auto-generated method stub
return 0;
}
}
数据库创建类MyopenHelper
package com.example.f14_contentprovider;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class MyOpenHelper extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 1;
private static final String PERSON_TABLE_NAME = "person";
public MyOpenHelper(Context context) {
super(context, PERSON_TABLE_NAME, null, DATABASE_VERSION);
// TODO Auto-generated constructor stub
}
@Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
db.execSQL("create table "
+ PERSON_TABLE_NAME
+ "(_id integer primary key autoincrement,name varchar(64),address varchar(64))");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
}