1.ContentProvider(android四大组件之一)
简单的说,它起到能让android设备上其他应用访问本应用的数据库(如某些应用可以读取手机上的联系人列表,媒体文件等等)
2.LoaderManager
用于管理一个或多个装载器,及时监数据的改变并及时修正客户端数据
下面有代码说明:
两个应用
MyContentProvider.java(GamePlayer应用提供访问接口)
package com.provider;
import com.db.DatabaseHelper;
import com.db.GameMetaData;
import android.content.ContentProvider;
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;
import android.util.Log;
public class MyContentProvider extends ContentProvider {
private DatabaseHelper helper = null;
private static String AUTHORITY = "com.provider.mycontentprovider";
private static UriMatcher matcher = null;
private static int SINGLE_CODE = 1;
private static int MULTI_CODE = 2;
static{
matcher = new UriMatcher(UriMatcher.NO_MATCH);
//添加匹配器 #:整数参数 不写: 无参
matcher.addURI(AUTHORITY, "game_player/#", SINGLE_CODE);
matcher.addURI(AUTHORITY, "game_player", MULTI_CODE);
};
@Override
public boolean onCreate() {
// TODO Auto-generated method stub
helper = new DatabaseHelper(getContext());
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
// TODO Auto-generated method stub
int key = matcher.match(uri);
Log.e("key=", key+"");
switch (key) {
case 1:
long id = ContentUris.parseId(uri);
SQLiteDatabase database = helper.getReadableDatabase();
Cursor cursor = database.query(GameMetaData.GamePlayer.GAMEPLAYER_TB, new String[]{GameMetaData.GamePlayer._ID,GameMetaData.GamePlayer.PLAYER,GameMetaData.GamePlayer.SCORE,GameMetaData.GamePlayer.LEVEL}, "_id=?", new String[]{id+""}, null, null, null);
return cursor;
case 2:
database = helper.getReadableDatabase();
return database.query(GameMetaData.GamePlayer.GAMEPLAYER_TB, new String[]{GameMetaData.GamePlayer._ID,GameMetaData.GamePlayer.PLAYER,GameMetaData.GamePlayer.SCORE,GameMetaData.GamePlayer.LEVEL}, selection, selectionArgs, null, null, null);
default:
break;
}
SQLiteDatabase database = helper.getReadableDatabase();
database.query(GameMetaData.GamePlayer.GAMEPLAYER_TB, null, null, null, null, null, null);
return null;
}
@Override
public String getType(Uri uri) {
// TODO Auto-generated method stub
return null;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
// TODO Auto-generated method stub
SQLiteDatabase database = helper.getWritableDatabase();
long id = database.insert(GameMetaData.GamePlayer.GAMEPLAYER_TB, null, values);
return ContentUris.withAppendedId(uri, id);
}
/**
* 返回受影响的行数
*/
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
// TODO Auto-generated method stub
SQLiteDatabase database = helper.getWritableDatabase();
return database.delete(GameMetaData.GamePlayer.GAMEPLAYER_TB, selection, selectionArgs);
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
// TODO Auto-generated method stub
SQLiteDatabase database = helper.getWritableDatabase();
return database.update(GameMetaData.GamePlayer.GAMEPLAYER_TB, values, selection, selectionArgs);
}
}
AndroidManifest.xml中注册:
<provider android:name="com.provider.MyContentProvider"
android:authorities="com.provider.mycontentprovider"
android:exported="true"></provider>
ProviderActivity1.java(应用Lesson,利用CursorLoader访问应用GamePlayer的数据库)
/**
* 异步加载Cursor数据,适用于数据库
* CursorLoader
* @author Administrator
*
*/
public class ProviderActivity1 extends Activity implements OnClickListener,LoaderCallbacks<Cursor>{
private SimpleCursorAdapter adapter = null;
private CursorLoader loader = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
Log.e("action=", "onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_provider);
Button bt = (Button) findViewById(R.id.bt_add);
bt.setOnClickListener(this);
ListView listView = (ListView) findViewById(R.id.my_ListView);
//注意最后一个参数,标志为内容观察者,只有标志这个才能让loader随时加载数据
adapter = new SimpleCursorAdapter(getApplicationContext(), R.layout.activity_provider_list_item, initData(), new String[]{"_id","player","score","level"}, new int[]{R.id.result1,R.id.result2,R.id.result3,R.id.result4},SimpleCursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
listView.setAdapter(adapter);
/**
* 初始化loader装载器
* 参数一:唯一标识装载器
* 参数二:可选的装载器初始化参数
* 参数三:装载器的回调接口
*/
getLoaderManager().initLoader(0, null, this);
}
public Cursor initData(){
ContentResolver resolver = getContentResolver();
Uri uri = Uri.parse("content://com.provider.mycontentprovider/game_player");
Cursor cursor = resolver.query(uri, null, null, null, null);
return cursor;
}
@Override
public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) {
// TODO Auto-generated method stub
Uri uri = Uri.parse("content://com.provider.mycontentprovider/game_player");
loader = new CursorLoader(getApplicationContext(), uri, new String[]{"_id","player","score","level"}, null, null, null);
return loader;//返回加载器对象,接着调用onLoadFinished
}
/**
* 将加载出来的数据加入适配器中
*/
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
// TODO Auto-generated method stub
adapter.swapCursor(data);
}
/**
* 加载器重新加载完数据返回客户端时,需要清空listView里的数据
*/
@Override
public void onLoaderReset(Loader<Cursor> loader) {
// TODO Auto-generated method stub
adapter.swapCursor(null);
}
int index = 0;
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.bt_add:
Uri uri = Uri.parse("content://com.provider.mycontentprovider");
ContentResolver resolver = getContentResolver();
ContentValues values = new ContentValues();
values.put("player", "new" + index++);
values.put("score", 232+"");
values.put("level", 4+"");
resolver.insert(uri, values);
//通知加载器去加载数据
//或getLoaderManager().restartLoader(0, null, this);//重新开启加载器(不建议使用)
loader.onContentChanged();
break;
default:
break;
}
}
}
ProviderActivity.java(应用Lesson,利用MyAsyncTaskLoader访问应用GamePlayer的数据库)
/**
* 异步线程加载ListView数据
* MyAsyncTaskLoader
* @author Administrator
*
*/
public class ProviderActivity extends Activity implements OnClickListener,LoaderCallbacks<List<Player>>{
private MyAdapter adapter = null;
private MyAsyncTaskLoader loader = null;
private DBAdapter db_adapter = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
Log.e("action=", "onCreate");
setContentView(R.layout.activity_provider);
Button bt_findById = (Button) findViewById(R.id.bt_findById);
Button bt_findAll = (Button) findViewById(R.id.bt_findAll);
Button bt_update = (Button) findViewById(R.id.bt_update);
Button bt_del = (Button) findViewById(R.id.bt_del);
Button bt_add = (Button) findViewById(R.id.bt_add);
bt_findById.setOnClickListener(this);
bt_findAll.setOnClickListener(this);
bt_update.setOnClickListener(this);
bt_del.setOnClickListener(this);
bt_add.setOnClickListener(this);
db_adapter = new DBAdapter();
List<Player> players = db_adapter.initData();
ListView listView = (ListView) findViewById(R.id.my_ListView);
adapter = new MyAdapter();
adapter.setPlayer(players);
listView.setAdapter(adapter);
// adapter.notifyDataSetChanged();
//初始化加载器
getLoaderManager().initLoader(0, null, this);
}
private int index = 0;
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.bt_findById:
ContentResolver resolver = getContentResolver();
///GamePlayer/src/com/provider/MyContentProvider.java
List<Player> list = db_adapter.initData();
int id = list.get(0).getId();
String url = "content://com.provider.mycontentprovider/game_player/"+id;
Uri uri = Uri.parse(url);
Cursor cursor = resolver.query(uri, null, null, null, null);
cursor.moveToNext();
Player player = new Player();
player.setId(cursor.getInt(cursor.getColumnIndex("_id")));
player.setPlayer(cursor.getString(cursor.getColumnIndex("player")));
player.setScore(cursor.getInt(cursor.getColumnIndex("score")));
player.setLevel(cursor.getInt(cursor.getColumnIndex("level")));
TextView textView = (TextView) findViewById(R.id.result);
textView.setText(player.toString());
break;
case R.id.bt_findAll:
resolver = getContentResolver();
///GamePlayer/src/com/provider/MyContentProvider.java
url = "content://com.provider.mycontentprovider/game_player";
uri = Uri.parse(url);
//Log.e("uri=", uri+"");
cursor = resolver.query(uri, null, null, null, null);
player = new Player();
String players = null;
List<Player> list_player = new ArrayList<Player>();
while (cursor.moveToNext()) {
player.setId(cursor.getInt(cursor.getColumnIndex("_id")));
player.setPlayer(cursor.getString(cursor.getColumnIndex("player")));
player.setScore(cursor.getInt(cursor.getColumnIndex("score")));
player.setLevel(cursor.getInt(cursor.getColumnIndex("level")));
players = players + " -###- " + player.toString();
list_player.add(player);
}
textView = (TextView) findViewById(R.id.result);
textView.setText(players);
break;
case R.id.bt_update:
resolver = getContentResolver();
///GamePlayer/src/com/provider/MyContentProvider.java
url = "content://com.provider.mycontentprovider";
uri = Uri.parse(url);
list = db_adapter.initData();
id = list.get(0).getId();
ContentValues values = new ContentValues();
// values.put("_id", id+"");
values.put("player", "我是1号");
values.put("score", 111+"");
values.put("level", 11+"");
int rows = resolver.update(uri, values, "_id=?", new String[]{id+""});
textView = (TextView) findViewById(R.id.result);
textView.setText("执行更新操作!受影响"+rows+"行");
loader.onContentChanged();
//或loader.commitContentChanged()(18支持)
//或getLoaderManager().restartLoader(0, null, this);
break;
case R.id.bt_del:
resolver = getContentResolver();
///GamePlayer/src/com/provider/MyContentProvider.java
url = "content://com.provider.mycontentprovider";
uri = Uri.parse(url);
list = new ArrayList<Player>();
list = db_adapter.initData();
id = list.get(0).getId();
//删除第一条数据
rows = resolver.delete(uri, "_id=?", new String[]{id+""});
textView = (TextView) findViewById(R.id.result);
textView.setText("执行删除操作!受影响"+rows+"行");
loader.onContentChanged();
break;
case R.id.bt_add:
resolver = getContentResolver();
///GamePlayer/src/com/provider/MyContentProvider.java
url = "content://com.provider.mycontentprovider";
uri = Uri.parse(url);
values = new ContentValues();
// values.put("_id", 1+"");
values.put("player", "新人甲" + index++);
values.put("score", 555+"");
values.put("level", 34+"");
resolver.insert(uri, values);
textView = (TextView) findViewById(R.id.result);
textView.setText("执行添加操作!");
loader.onContentChanged();
break;
default:
break;
}
}
private class MyAdapter extends BaseAdapter{
List<Player> data = new ArrayList<Player>();
// public MyAdapter(){
//
// }
public void setPlayer(List<Player> data){
Log.e("action=", "setPlayer");
this.data = data;
Log.e("this.data=", this.data.size()+"-------");
}
@Override
public int getCount() {
// TODO Auto-generated method stub
Log.e("action=", "getCount");
Log.e("data.size()=", data.size()+"");
return data.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
Log.e("action=", "getItem");
return data.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
Log.e("action=", "getView");
ViewHolder viewHolder = null;
if(convertView == null){
convertView = getLayoutInflater().inflate(R.layout.activity_provider_list_item, null);
viewHolder = new ViewHolder();
viewHolder.text1 = (TextView) convertView.findViewById(R.id.result1);
viewHolder.text2 = (TextView) convertView.findViewById(R.id.result2);
viewHolder.text3 = (TextView) convertView.findViewById(R.id.result3);
viewHolder.text4 = (TextView) convertView.findViewById(R.id.result4);
convertView.setTag(viewHolder);
}else{
viewHolder = (ViewHolder) convertView.getTag();
}
Log.e("data.get(0).getPlayer()=", data.get(position).getPlayer());
viewHolder.text1.setText(data.get(position).getId()+"--");
viewHolder.text2.setText(data.get(position).getPlayer()+"--");
viewHolder.text3.setText(data.get(position).getScore()+"--");
viewHolder.text4.setText(data.get(position).getLevel()+"--");
return convertView;
}
}
private static class ViewHolder{
TextView text1;
TextView text2;
TextView text3;
TextView text4;
}
/*********************实现LoaderCallbacks需要的方法**********************/
/**
*
*/
@Override
public Loader<List<Player>> onCreateLoader(int arg0, Bundle arg1) {
// TODO Auto-generated method stub
Log.e("action=", "onCreateLoader");
loader = new MyAsyncTaskLoader(getApplicationContext(), db_adapter);
return loader;
}
@Override
public void onLoadFinished(Loader<List<Player>> loader, List<Player> data) {
// TODO Auto-generated method stub
Log.e("action=", "onLoadFinished");
adapter.setPlayer(data);
adapter.notifyDataSetChanged();
}
@Override
public void onLoaderReset(Loader<List<Player>> arg0) {
// TODO Auto-generated method stub
Log.e("action=", "onLoaderReset");
adapter.setPlayer(null);
}
/**
* 异步加载器的类
*/
private static class MyAsyncTaskLoader extends AsyncTaskLoader<List<Player>>{
DBAdapter adapter = null;
List<Player> data = new ArrayList<Player>();
public MyAsyncTaskLoader(Context context, DBAdapter adapter) {
super(context);
// TODO Auto-generated constructor stub
this.adapter = adapter;
Log.e("action=", "MyAsyncTaskLoader");
}
/**
* 开启一个线程去加载数据
*/
@Override
public List<Player> loadInBackground() {
// TODO Auto-generated method stub
Log.e("action=", "loadInBackground");
data = adapter.initData();
return data;
}
@Override
protected void onStartLoading() {
// TODO Auto-generated method stub
super.onStartLoading();
Log.e("action=", "onStartLoading");
Log.e("data=", ""+data.size());
if(data != null && data.size() > 0){
deliverResult(data);
}
}
@Override
public void deliverResult(List<Player> data) {
// TODO Auto-generated method stub
Log.e("action=", "deliverResult");
super.deliverResult(data);
}
}
private class DBAdapter{
public List<Player> initData(){
Log.e("action=", "initData");
ContentResolver resolver = getContentResolver();
///GamePlayer/src/com/provider/MyContentProvider.java
String url = "content://com.provider.mycontentprovider/game_player";
Uri uri = Uri.parse(url);
Log.e("uri=", uri+"");
Cursor cursor = resolver.query(uri, null, null, null, null);
List<Player> list_player = new ArrayList<Player>();
while (cursor.moveToNext()) {
Player player = new Player();
player.setId(cursor.getInt(cursor.getColumnIndex("_id")));
player.setPlayer(cursor.getString(cursor.getColumnIndex("player")));
player.setScore(cursor.getInt(cursor.getColumnIndex("score")));
player.setLevel(cursor.getInt(cursor.getColumnIndex("level")));
list_player.add(player);
Log.e("p.getPlayer()==", player.getPlayer()+"");
Log.e("p.getId()==", player.getId()+"");
}
for (Player p : list_player) {
Log.e("p.getId()", p.getId()+"");
}
return list_player;
}
}
}