android 使用contentobserver监听数据库内容变化

android 使用contentobserver监听数据库内容变化

在android中经常会用到改变数据库内容后再去使用数据库更新的内容,很多人会重新去query一遍,但是这样的问题就是程序会特别占内存,而且有可能会搂关cursor而导致程序内存未释放等等。其实android内部提供了一种ContentObserver的东西来监听数据库内容的变化。


ContentObserver的构造函数需要一个参数Hanlder,因为ContentObserver内部使用了一个实现Runnable接口的内部类NotificationRunnable,来实现数据库内容的变化。需要使用hanlder去post消息。注册ContentObserver的方法是:getContentResolver().registerContentObserver(uri, notifyForDescendents, observer).
上面3个参数为:

uri----Uri类型,是需要监听的数据库的uri.
notifyForDescendents---boolean  true的话就会监听所有与此uri相关的uri。false的话则是直接特殊的uri才会监听。一般都设置为true.
observer-----ContentObserver  就是需要的contentobserver.


初始化一个ContentObserver对象,重载onChange(boolean ),在这个方法里去操作数据库的使用,针对变化后的使用。
写了一个小demo,可以参考下。提示这种监听方式必须是contentprovider才能使用,因为contentprovider有uri.简单的那种sqlite数据库没有uri是使用不了的。
下面demo操作的是在一个activityA里点击button跳转至另外一个activityB,在B中点击button往数据库中加数据,加完后关闭B回到A。A的button的文字自动变化设置到数据库中的字符串。

package ty.com.lto;



import android.app.Activity;

import android.content.Intent;

import android.database.ContentObserver;

import android.os.Bundle;

import android.os.Handler;

import android.view.View;

import android.widget.Button;



public class ListenDataTest extends Activity{

    private Button testBtn;



        @Override

        protected void onCreate(Bundle savedInstanceState) {

                super.onCreate(savedInstanceState);

                setContentView(R.layout.listen_data_test);

                getContentResolver().registerContentObserver(DataChangeProvider.CONTENT_URI,

                                true, cob);

                

                testBtn = (Button)findViewById(R.id.test_btn);

                testBtn.setOnClickListener(new View.OnClickListener() {

                        

                        public void onClick(View v) {

                                Intent in = new Intent(ListenDataTest.this,DataChangeTest.class);

                                startActivity(in);

                                

                        }

                });

                

        }

        

        private ContentObserver cob = new ContentObserver(new Handler()) {



                @Override

                public boolean deliverSelfNotifications() {

                        return super.deliverSelfNotifications();

                }



                @Override

                public void onChange(boolean selfChange) {

                        super.onChange(selfChange);

                        testBtn.setText(DataUtils.getChangeName(getApplicationContext()));

                }

                 

         };



        @Override

        protected void onDestroy() {

                super.onDestroy();

                getContentResolver().unregisterContentObserver(cob);

        }

     

         

}

 

package ty.com.lto;



import android.app.Activity;

import android.content.ContentValues;

import android.content.Intent;

import android.database.ContentObservable;

import android.database.ContentObserver;

import android.os.Bundle;

import android.os.Handler;

import android.view.View;

import android.widget.Button;



public class DataChangeTest extends Activity{

     private Button dataBtn;

     DataSqlite mDataSqlite;

     @Override

     protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.data_change_test);

        dataBtn = (Button)findViewById(R.id.data_test_btn);

        mDataSqlite = new DataSqlite(this);

        dataBtn.setOnClickListener(new View.OnClickListener() {

            

            public void onClick(View v) {

                ContentValues con = new ContentValues();

                con.put("name", "数据变化了");

                getContentResolver().insert(DataChangeProvider.CONTENT_URI, con);

                finish();

            }

        });

     }

}

 

package ty.com.lto;

 

 

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.database.sqlite.SQLiteQueryBuilder;

import android.database.sqlite.SQLiteDatabase.CursorFactory;

import android.net.Uri;

import android.text.TextUtils;

 

public class DataChangeProvider extends ContentProvider{

    private SQLiteOpenHelper mOpenHelper;

    private static final int ALARMS = 1;

    private static final int ALARMS_ID = 2;

    private static final UriMatcher sURLMatcher = new UriMatcher(UriMatcher.NO_MATCH);

    public static final Uri CONTENT_URI = Uri.parse("content://ty.com.lto/test"); 

 

    static {

        sURLMatcher.addURI("ty.com.lto", "test", ALARMS);

        sURLMatcher.addURI("ty.com.lto", "test/#", ALARMS_ID);

    }

    

    private static class DatabaseHelper extends SQLiteOpenHelper{

         private static final String TEST_DATABASE = "test.db";

         private static final int VERSION = 1;

         

         public DatabaseHelper(Context context) {

             super(context, TEST_DATABASE, null, VERSION);

             // TODO Auto-generated constructor stub

         }

          

 

         @Override

         public void onCreate(SQLiteDatabase db) {

             String sql = "CREATE TABLE "+"test"+" (" +

                     "_id INTEGER PRIMARY KEY," +

                     "name TEXT "+ 

                      ");";

             db.execSQL(sql);

         }

 

         @Override

         public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

             String sql = "DROP TABLE IF EXIST "+TEST_DATABASE;

             db.execSQL(sql);

             onCreate(db);

         }

         

    }

    

    public DataChangeProvider() {

    }

    

    @Override

    public int delete(Uri url, String where, String[] whereArgs) {

        SQLiteDatabase db = mOpenHelper.getWritableDatabase();

        int count;

        long rowId = 0;

        switch (sURLMatcher.match(url)) {

            case ALARMS:

                count = db.delete("test", where, whereArgs);

                break;

            case ALARMS_ID:

                String segment = url.getPathSegments().get(1);

                rowId = Long.parseLong(segment);

                if (TextUtils.isEmpty(where)) {

                    where = "_id=" + segment;

                } else {

                    where = "_id=" + segment + " AND (" + where + ")";

                }

                count = db.delete("test", where, whereArgs);

                break;

            default:

                throw new IllegalArgumentException("Cannot delete from URL: " + url);

        }

 

        getContext().getContentResolver().notifyChange(url, null);

        return count;

    }

 

    @Override

    public String getType(Uri url) {

        int match = sURLMatcher.match(url);

        switch (match) {

            case ALARMS:

                return "vnd.android.cursor.dir/alarms";

            case ALARMS_ID:

                return "vnd.android.cursor.item/alarms";

            default:

                throw new IllegalArgumentException("Unknown URL");

        }

    }

 

    @Override

    public Uri insert(Uri url, ContentValues initialValues) {

        if (sURLMatcher.match(url) != ALARMS) {

            throw new IllegalArgumentException("Cannot insert into URL: " + url);

        }

 

        ContentValues values;

        if (initialValues != null) {

            values = new ContentValues(initialValues);

        } else {

            values = new ContentValues();

        }

            

        if (!values.containsKey("name"))

            values.put("name", "");

 

        SQLiteDatabase db = mOpenHelper.getWritableDatabase();

        long rowId = db.insert("test", null, values);

        if (rowId < 0) {

            throw new SQLException("Failed to insert row into " + url);

        }

        Uri newUrl = ContentUris.withAppendedId(CONTENT_URI, rowId);

        getContext().getContentResolver().notifyChange(newUrl, null);

        return newUrl;

    }

 

    @Override

    public boolean onCreate() {

        mOpenHelper = new DatabaseHelper(getContext());

        return true;

    }

 

    @Override

    public Cursor query(Uri url, String[] projection, String where,

            String[] whereArgs, String sortOrder) {

        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();

        int match = sURLMatcher.match(url);

        switch (match) {

            case ALARMS:

                qb.setTables("test");

                break;

            case ALARMS_ID:

                qb.setTables("test");

                qb.appendWhere("_id=");

                qb.appendWhere(url.getPathSegments().get(1));

                break;

            default:

                throw new IllegalArgumentException("Unknown URL " + url);

        }

 

        SQLiteDatabase db = mOpenHelper.getReadableDatabase();

        Cursor cur = qb.query(db, projection, where, whereArgs,null, null, sortOrder);

        if (cur != null) {

            cur.setNotificationUri(getContext().getContentResolver(), url);

             

        } 

        return cur;

    }

 

    @Override

    public int update(Uri url, ContentValues values, String where,String[] whereArgs) {

        int count;

        long rowId = 0;

        int match = sURLMatcher.match(url);

        SQLiteDatabase db = mOpenHelper.getWritableDatabase();

        switch (match) {

            case ALARMS_ID: {

                String segment = url.getPathSegments().get(1);

                rowId = Long.parseLong(segment);

                count = db.update("test", values, "_id=" + rowId, null);

                break;

            }

            default: {

                throw new UnsupportedOperationException(

                        "Cannot update URL: " + url);

            }

        }

        getContext().getContentResolver().notifyChange(url, null);

        return count;

    }

 

}

 

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

      package="ty.com.lto"

      android:versionCode="1"

      android:versionName="1.0"

      >

    <application android:icon="@drawable/icon" android:label="@string/app_name">

    <provider android:name="DataChangeProvider" android:authorities="ty.com.lto"/>

        <activity android:name=".ListenDataTest"

                  android:label="@string/app_name">

            <intent-filter>

                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />

            </intent-filter>

        </activity>

    <activity android:name=".DataChangeTest" android:label="@string/app_name"/>

    </application>

<uses-permission android:name="android.permission.INTERNET"/>

<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>



</manifest>


 

 

转载自:http://dev.10086.cn/cmdn/bbs/viewthread.php?tid=37427&extra=page%3D1%26amp%3Bfilter%3Dtype%26amp%3Btypeid%3D67

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值