ContentProvider 实例详解二(观察者模式监测数据的变化)

上一篇博客主要讲解了下在我们程序中ContentProvider的创建过程。在上一篇博客有上传2份代码分别为testContentProvider(创建ContentProvider的程序),testZSGC调用testContentProvider里面的ContentProvider的程序。当testContentProvider中数据库数据有变化时,如何能够通知到testZSGC这个程序呢?其实android已经为我们提供了监测这变化的功能,那就是ContentObserver,称之为内容观察者。具体使用方法有如下几个步骤,可以下载代码结合阅读:

1:创建一个类继承至ContentObserver,并实现onChange函数。每当有数据变化时就会触发onChange函数。

	class MyObserver extends ContentObserver {

		public MyObserver(Handler handler) {
			super(handler);
		}

		@Override
		public void onChange(boolean selfChange) {

			handler.obtainMessage(LISTENER_TYPE).sendToTarget();
		}
	}
2:在ContentProvider的增删改查函数值添加如下代码:

this.getContext().getContentResolver().notifyChange(mUri, null);   
//notifyChange第一个参数就是我们访问ContentProvider的uri路径

3:在创建Activity时注册ContentObserver

mContext.getContentResolver().registerContentObserver(mUri, true, mObserver);
//mObserver就是步骤1中的MyObserver对象,mUri就是我们访问ContentProvider的uri路径
4:在退出Activity时注销ContentObserver
mContext.getContentResolver().unregisterContentObserver(mObserver);
5:通过上面几步,每当ContentProvider数据有变化时,就会触发步骤1中的onChange函数,然后我们回调至我们的Activity中做出相应的处理。

ObserverHandler.java代码

import android.content.Context;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Handler;
import android.os.Message;

public class ObserverHandler {
	
	private onDataChangeListener mListener;
	private int LISTENER_TYPE = 0;
	private Uri mUri;
	private Context mContext;
	private MyObserver mObserver;

	public interface onDataChangeListener {
		public void onChange(Uri uri);
		public Context getContext();
	}
	
	public ObserverHandler(Uri uri,onDataChangeListener listener)
	{
		mListener = listener;
		mUri = uri;
		mContext = mListener.getContext();
	}
	
	public void registerObserver()
	{
		mObserver = new MyObserver(handler);
		mContext.getContentResolver().registerContentObserver(mUri, true, mObserver);
	}
	
	public void unRegisterObserver()
	{
		mContext.getContentResolver().unregisterContentObserver(mObserver);
	}

	public Handler handler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			
			if(msg.what == LISTENER_TYPE)
			{
				mListener.onChange(mUri);
			}
		}
	};

	class MyObserver extends ContentObserver {

		public MyObserver(Handler handler) {
			super(handler);
		}

		@Override
		public void onChange(boolean selfChange) {

			handler.obtainMessage(LISTENER_TYPE).sendToTarget();
		}
	}

}

MainActivity.java代码

import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;

import com.example.testzsgc.ObserverHandler.onDataChangeListener;

public class MainActivity extends Activity implements onDataChangeListener{

	Uri mUri_insert = Uri.parse("content://com.example.testcontentprovider/test");  
	Uri mUris_del = Uri.parse("content://com.example.testcontentprovider/test/1");  //删除id为1的数据  
	Uri mUris_query = Uri.parse("content://com.example.testcontentprovider/test/2");  //查询id为2的数据  
	Uri mUris_update = Uri.parse("content://com.example.testcontentprovider/test/3");  //修改id为2的数据  
	
	private ObserverHandler mObserverHandler;
	
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        mObserverHandler = new ObserverHandler(mUri_insert,this);
        mObserverHandler.registerObserver();
    }
    
    
    
    public void insert(View v)
    {
    	ContentResolver cr = this.getContentResolver();
    	ContentValues value = new ContentValues();
    	value.put("name", "test1");
    	Uri uri = cr.insert(mUri_insert, value);
    }
    
    
    public void delete(View v)
    {
    	ContentResolver cr = this.getContentResolver();
    	int m = cr.delete(mUris_del, null, null);
    }
    
    
    public void query(View v)
    {
    	ContentResolver cr = this.getContentResolver();
    	Cursor c= cr.query(mUris_query, null, null, null, null);
    	if(c.moveToFirst() ==  false)
    	{
    		return;
    	}
    	int nameindex = c.getColumnIndex("name");
    	String strname = c.getString(nameindex);
    	Toast.makeText(this, strname, Toast.LENGTH_SHORT).show();
      	c.close();
    }
    
    
    public void modify(View v)
    {
    	ContentResolver cr = this.getContentResolver();
    	ContentValues value = new ContentValues();
    	value.put("name", "testupdate");
    	cr.update(mUris_update, value, null, null);
    }



    @Override
    public void onChange(Uri uri) {
	Toast.makeText(this, "uri有改变", Toast.LENGTH_SHORT).show();
    }

    @Override
    public Context getContext() {
	// TODO Auto-generated method stub
	return this;
    }
	
    @Override
    public void onDestroy()
    {
	super.onDestroy();
	mObserverHandler.unRegisterObserver();
    }
	
}
MycontentProvider.java代码

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.net.Uri;
import android.text.TextUtils;

public class MyContentProvider extends ContentProvider{

	private SqliteHelper mHelper;
	
	private static final UriMatcher uriMatcher;
	public static final String strUri = "com.example.testcontentprovider";
	
	private static final int TEST = 101;
	private static final int TESTS = 102;
	
	public static final String CONTENT_TYPE = "vnd.android.cursor.dir/com.example.testcontentproviders";
	public static final String CONTENT_TYPE_ITEM = "vnd.android.cursor.item/com.example.testcontentprovider";
	
	Uri mUri = Uri.parse("content://com.example.testcontentprovider/test");  
	
	static
	{
		uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
		uriMatcher.addURI(strUri, "test", TESTS);
		uriMatcher.addURI(strUri, "test/#", TEST);
	}
	
	@Override
	public boolean onCreate() {

		mHelper = new SqliteHelper(getContext());
		return false;
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {
		SQLiteDatabase db = mHelper.getReadableDatabase();
		switch(uriMatcher.match(uri))
		{
		case TEST:
			long id = ContentUris.parseId(uri);    
			String where = "id="+id;
	        where += !TextUtils.isEmpty(selection) ? " and (" + selection + ")" : "";// 把其它条件附加上    
	        this.getContext().getContentResolver().notifyChange(mUri, null);
	        return db.query(SqliteHelper.DB_TABLE, projection, where, selectionArgs, null, null, sortOrder);
		case TESTS:
			this.getContext().getContentResolver().notifyChange(mUri, null);
			return db.query(SqliteHelper.DB_TABLE, projection, selection, selectionArgs, null, null, sortOrder);
		default:
			throw new IllegalArgumentException("Unknown URI " + uri);
		}
		
	}

	@Override
	public String getType(Uri uri) {
		switch(uriMatcher.match(uri))
		{
		case TEST:
			return CONTENT_TYPE_ITEM;
		case TESTS:
			return CONTENT_TYPE;
		default:
			throw new IllegalArgumentException("Unknown URI " + uri);
		}
	}

	@Override
	public Uri insert(Uri uri, ContentValues initvalues) {

		SQLiteDatabase db = mHelper.getWritableDatabase();
		ContentValues values;
		if(initvalues != null)
		{
			values = new ContentValues(initvalues);
		}else
		{
			values = new ContentValues();
		}
		
		switch( uriMatcher.match(uri))
		{
		case TEST:
			break;
		case TESTS:
			if(values.containsKey(SqliteHelper.DB_TABLE_NAME) == false)
			{
				values.put(SqliteHelper.DB_TABLE_NAME, "");
			}
			break;
		default:    
            throw new IllegalArgumentException("Unknown URI " + uri);  
		}
		
		long rowid = db.insert(SqliteHelper.DB_TABLE, null, values); // 返回的是记录的行号,主键为int,实际上就是主键值 
		if(rowid > 0)
		{
			Uri noteuri = ContentUris.withAppendedId(uri, rowid);
			this.getContext().getContentResolver().notifyChange(mUri, null);
			return noteuri;
		}
	
		throw new SQLException("Failed to insert row into " + uri);
	}

	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		SQLiteDatabase db = mHelper.getWritableDatabase();
		int count = 0;
		switch( uriMatcher.match(uri))
		{
		case TEST: //删除指定数据
			long id = ContentUris.parseId(uri);
			String where = "id="+id;
			where += !TextUtils.isEmpty(selection)?" and ("+selection+")" : "";
			count = db.delete(SqliteHelper.DB_TABLE, where, selectionArgs);
			break;
		case TESTS:  //删除所有数据
			count = db.delete(SqliteHelper.DB_TABLE, selection, selectionArgs);
			break;
		 default:    
	            throw new IllegalArgumentException("Unknown URI " + uri);    
	        }    
		 this.getContext().getContentResolver().notifyChange(mUri, null);
	     db.close();    
	     return count;  
	}

	@Override
	public int update(Uri uri, ContentValues values, String selection,
			String[] selectionArgs) {
		SQLiteDatabase db = mHelper.getWritableDatabase();
		int count = 0;
		switch( uriMatcher.match(uri))
		{
		case TEST:
			long id = ContentUris.parseId(uri);
			String where = "id="+id;
			where += !TextUtils.isEmpty(selection)?" and ("+selection+")" : "";
			count = db.update(SqliteHelper.DB_TABLE,values, where, selectionArgs);
			break;
		case TESTS: 
			db.update(SqliteHelper.DB_TABLE, values, selection, selectionArgs);
			break;
		 default:    
	            throw new IllegalArgumentException("Unknown URI " + uri);    
	        }    
		 this.getContext().getContentResolver().notifyChange(mUri, null);
	     db.close();    
	     return count;  
	}

}

class SqliteHelper extends SQLiteOpenHelper{
	
	public final static String DB_NAME = android.os.Environment.getExternalStorageDirectory().getAbsolutePath()+"/test.db";
	public final static int DB_VERSION = 1;
	
	public final static String DB_ID = "id";
	public final static String DB_TABLE = "test";
	public final static String DB_TABLE_NAME = "name";
	
	
	public SqliteHelper(Context context)
	{
		super(context,DB_NAME,null,DB_VERSION);
	}

	@Override
	public void onCreate(SQLiteDatabase db) {
		db.execSQL("CREATE TABLE " + DB_TABLE + " (" 
		        + DB_ID + " INTEGER PRIMARY KEY," 
				+ DB_TABLE_NAME + " TEXT"
		        + ");");
	}

	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		db.execSQL("DROP TABLE IF EXISTS "+DB_TABLE);	
		onCreate(db);
	}

}
源码下载

ContentProvider 实例详解一(创建一个自己的ContentProvider)
ContentProvider 实例详解二(观察者模式监测数据的变化)






  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值