Android 4种数据存储方式详解(二)

Android提供ContentProvider向外界提供数据以及修改数据的方法,以达到应用之间的数据共享。使用ContentProvider进行数据共享的好处在于使用数据者不需要知道数据提供者是以何种方式进行数据存储的,只需要通过数据提供者所提供出来的同一方法即可达到共享数据、操作数据的目的!下面以一个小例子来具体说明是怎么实现的:

数据提供者:

继承ContentProvider

定义访问者URI路径,向外界暴露出真删改查方法

URI形如:content:\\niko.android.demopro/provider/10,其具体组成部分分4部分:

1、scheme:content:\\

2、authority:用于唯一标识这个ContentProvider,外部调用者可以根据这个标识来找到它,如niko.android.demo

      3、path:可以用来表示我们要操作的数据,路径的构建应根据业务而定,如 /provider

      4、ID:如果没有ID,即表示是对数据整个的访问,有的话就是对具体一些数据的访问,如/10(对于本例就是tid=10的数据)

一般在ContentProvider应用中,需要定义一个常量类来管理URI中一些常量,比如authority,path等,本文的常量类为ConstantsUtil类,因为本例是以Sqlite进行数据存储,所以该常量类中还包括了表的一些结构常量,如表名,字段,版本号等常量。

/**
 * 常量类,保存的是数据库表字段名 以及 uri相关
 */
public class ConstantsUtil {
	
	public static final String TABLE = "userinfos";
	public static String TID = "tid";
	public static final String USERNAME = "username";
	public static final String SEX = "sex";
	public static final int VERSION = 8;
	
	
	public static final String SCHEME = "content://";
	//authority必须与manifest中配置一致,其作用是解析该uri时可以找到对应的ContentProvider
	public static final String AUTHORITY = "niko.android.demo";
	public static final String PATH = "provider";
	public static final Uri CONTENT_URI = Uri.parse(SCHEME + AUTHORITY +  "/"+PATH);
	
	//Mime类型所对应的匹配码
	public static final int CODE_ALL_DATA = 1;
    public static final int CODE_SPECIFIC_DATA = 2;
    //Mime类型
    public static final String CONTENT_ALL_TYPE = "vnd.android.cursor.item/"+"android.provider.demo";//单一数据
    public static final String CONTENT_SPECIFIC_TYPE = "vnd.android.cursor.dir/"+"android.provider.demo";//多项数据
    
}

public class MyProvider extends ContentProvider {
	private static final String TAG = "provider";
	private Context mContext;
	private DbHelper helper;
	private SQLiteDatabase database;
	private static final UriMatcher uriMatcher;
	//添加URI匹配
	static {
		uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
		uriMatcher.addURI(ConstantsUtil.AUTHORITY, ConstantsUtil.PATH, ConstantsUtil.CODE_ALL_DATA);
		uriMatcher.addURI(ConstantsUtil.AUTHORITY, ConstantsUtil.PATH+"/#", ConstantsUtil.CODE_SPECIFIC_DATA);
	}
	
	@Override
	public boolean onCreate() {
		//外界调用ContentResolver时调用
		mContext = this.getContext();
		helper = new DbHelper(mContext);
		return true;
	}

	@Override
	public String getType(Uri uri) {
		switch (uriMatcher.match(uri)){
		case ConstantsUtil.CODE_ALL_DATA:
        	return ConstantsUtil.CONTENT_ALL_TYPE;
		case ConstantsUtil.CODE_SPECIFIC_DATA:
        	return ConstantsUtil.CONTENT_SPECIFIC_TYPE;
		default:
            throw new IllegalArgumentException("Unknown URI"+uri);
        }

	}

	@Override
	public Uri insert(Uri uri, ContentValues values) {
		database = helper.getWritableDatabase();
	    long rowId = database.insert(ConstantsUtil.TABLE,"",values);
        Uri noteUri = ContentUris.withAppendedId(ConstantsUtil.CONTENT_URI, rowId);
        getContext().getContentResolver().notifyChange(noteUri, null);
        return noteUri;
	}

	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		database = helper.getWritableDatabase();
		int count = 0;
		switch (uriMatcher.match(uri)) {
		case ConstantsUtil.CODE_ALL_DATA:
			count = database.delete(ConstantsUtil.TABLE, selection, selectionArgs);
			break;
		case ConstantsUtil.CODE_SPECIFIC_DATA:
			//uri.getPathSegments()得到一个集合,内容分别为 uri的path和_id 即 [provider , _id]
			String id = uri.getPathSegments().get(1);
			count = database.delete(ConstantsUtil.TABLE, ConstantsUtil.TID+"="+id+(!TextUtils.isEmpty(selection)?" AND("+selection+')':""),selectionArgs);
			break;
		default:
			throw new IllegalArgumentException("Unknown URI"+uri);
		}
		//getContext().getContentResolver().notifyChange(uri, null);
		return count;
	}

	@Override
	public int update(Uri uri, ContentValues values, String selection,
			String[] selectionArgs) {
		int count = 0;
		database = helper.getWritableDatabase();
		count = database.update(ConstantsUtil.TABLE, values, selection, selectionArgs);
		/*getContext().getContentResolver().registerContentObserver(uri, true, new ContentObserver(new Handler()){
			@Override
			public void onChange(boolean selfChange) {
				super.onChange(selfChange);
			}
        });*/
		return count;
	}
	
	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {
		database = helper.getReadableDatabase();
		Cursor c = null;
		switch (uriMatcher.match(uri)) {
		case ConstantsUtil.CODE_ALL_DATA:
			c = database.query(ConstantsUtil.TABLE, projection, selection, selectionArgs, null, null, null);
			break;
		case ConstantsUtil.CODE_SPECIFIC_DATA:
			//uri.getPathSegments()得到一个集合,内容分别为 uri的path和_id 即 [provider , _id]
			String id = uri.getPathSegments().get(1);
			c = database.query(ConstantsUtil.TABLE, projection, ConstantsUtil.TID+"="+id+(!TextUtils.isEmpty(selection)?" AND("+selection+')':""),selectionArgs, null, null, sortOrder);
			break;
		default:
			throw new IllegalArgumentException("Unknown URI"+uri);
		}
		return c;
	}

}

public class DbHelper extends SQLiteOpenHelper {
	
	private static final String TAG = "";
	
	public DbHelper(Context context){
		super(context, ConstantsUtil.TABLE, null, ConstantsUtil.VERSION);
	}
	
	public DbHelper(Context context, String name, CursorFactory factory,
			int version) {
		super(context, name, factory, version);
	}

	@Override
	public void onCreate(SQLiteDatabase db) {
		db.execSQL("create table "+ConstantsUtil.TABLE+"(" +
				 ConstantsUtil.TID+" integer primary key autoincrement not null,"+
				 ConstantsUtil.USERNAME+" text not null," +
				 ConstantsUtil.SEX+" text not null);");
	}

	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		db.execSQL("DROP TABLE IF EXISTS "+ConstantsUtil.TABLE);
        onCreate(db);
	}
	
	public void add(String username,String sex){
        SQLiteDatabase db = getWritableDatabase();
        ContentValues values = new ContentValues();
        values.put(ConstantsUtil.USERNAME, username);
        values.put(ConstantsUtil.SEX, sex);
        db.insert(ConstantsUtil.TABLE, "", values);
	}
	
	
}
在同一个应用中访问ContentProvider提供的数据:


public class ContentProviderDemoActivity extends Activity {

	private DbHelper helper;
	private ContentResolver contentResolver;
	private TextView tv;
	
	
	@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        tv = (TextView)findViewById(R.id.tv);
        helper = new DbHelper(this);
        helper.add("ZhangJin", "男");
        helper.add("Niko", "男");
        helper.add("Lucy", "女");
        
        contentResolver = this.getContentResolver();
        Cursor cursor = contentResolver.query(
        		                  ConstantsUtil.CONTENT_URI, 
        		                  new String[] {
        		                		  	ConstantsUtil.TID,
        		                		  	ConstantsUtil.USERNAME,
        		                		  	ConstantsUtil.SEX },
        		                  null, null, null);
       
        while (cursor.moveToNext()) {
           String text = "tid : "+cursor.getString(0)+" , name : "+cursor.getString(1)+" , sex : "+cursor.getString(2);
           tv.append(text+"\n");
        }
        startManagingCursor(cursor);  //查找后关闭游标
        
    }
	
}

在另一个应用中访问数据并且操作数据(把那个ConstantsUtil常量工具类copy到另一个工程中)


public class ContentResolverDemoActivity extends Activity {

	private ContentResolver contentResolver;
	private TextView tv;
	private Button btn,btn1,btn2;
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		tv = (TextView)findViewById(R.id.tv);
		btn = (Button)findViewById(R.id.btn);
	    btn1 = (Button)findViewById(R.id.btn1);
	    btn2 = (Button)findViewById(R.id.btn2);
		
		contentResolver = this.getContentResolver();

		Cursor cursor = contentResolver.query(ConstantsUtil.CONTENT_URI,
				new String[] { ConstantsUtil.TID, ConstantsUtil.USERNAME,
						ConstantsUtil.SEX }, null, null, null);

		while (cursor.moveToNext()) {
			String text = "tid : " + cursor.getString(0) + " , name : "
					+ cursor.getString(1) + " , sex : " + cursor.getString(2);
			tv.append(text + "\n");
		}
		startManagingCursor(cursor); // 查找后关闭游标
		
		btn.setOnClickListener(listener);
	       btn1.setOnClickListener(listener);
	       btn2.setOnClickListener(listener);
	}
	
	
	private OnClickListener listener = new OnClickListener() {
		@Override
		public void onClick(View v) {
			switch (v.getId()) {
			case R.id.btn:
				//按条件查询
				Uri uri = Uri.parse("content://niko.android.demo/provider/#");
				Cursor c = contentResolver.query(uri,  
											new String[] {
			        		                		  	ConstantsUtil.TID,
			        		                		  	ConstantsUtil.USERNAME,
			        		                		  	ConstantsUtil.SEX }, 
			        		                ConstantsUtil.USERNAME+" = ?", 
			        		                new String[]{"Lucy"}, 
			        		                null);
				while(c.moveToNext()){
					String text = "tid : "+c.getString(0)+" , name : "+c.getString(1)+" , sex : "+c.getString(2);
					btn.append(text);
				}
				c.close();
				break;
			case R.id.btn1:
				//删除
				Uri uri1 = Uri.parse("content://niko.android.demo/provider/#");
				int res = contentResolver.delete(uri1, ConstantsUtil.USERNAME+" = ? ", new String[]{"Niko"});
				setTitle("已经删除 "+res+" 数据");
				break;
			case R.id.btn2:
				//更新
				Uri uri2 = Uri.parse("content://niko.android.demo/provider/#");
				ContentValues values = new ContentValues();
				values.put(ConstantsUtil.USERNAME, "Jack");
				values.put(ConstantsUtil.SEX, "女");
				int res2 = contentResolver.update(uri2, values, ConstantsUtil.USERNAME+" = ? ", new String[]{"ZhangJin"});
				setTitle("已经更新 "+res2+" 数据");
				break;
			default:
				break;
			}
		}
	};
	
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值