随笔 - 33, 文章 - 0, 评论 - 12, 引用 - 0
数据加载中……

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的文字自动变化设置到数据库中的字符串。[code]
01package ty.com.lto;
02 
03import android.app.Activity;
04import android.content.Intent;
05import android.database.ContentObserver;
06import android.os.Bundle;
07import android.os.Handler;
08import android.view.View;
09import android.widget.Button;
10 
11public class ListenDataTest extends Activity{
12    private Button testBtn;
13 
14        @Override
15        protected void onCreate(Bundle savedInstanceState) {
16                super.onCreate(savedInstanceState);
17                setContentView(R.layout.listen_data_test);
18               getContentResolver().registerContentObserver(DataChangeProvider.CONTENT_URI,
19                                true, cob);
20                 
21                testBtn = (Button)findViewById(R.id.test_btn);
22                testBtn.setOnClickListener(new View.OnClickListener() {
23                         
24                        public void onClick(View v) {
25                                Intent in = newIntent(ListenDataTest.this,DataChangeTest.class);
26                                startActivity(in);
27                                 
28                        }
29                });
30                 
31        }
32         
33        private ContentObserver cob = new ContentObserver(new Handler()) {
34 
35                @Override
36                public boolean deliverSelfNotifications() {
37                        return super.deliverSelfNotifications();
38                }
39 
40                @Override
41                public void onChange(boolean selfChange) {
42                        super.onChange(selfChange);
43                       testBtn.setText(DataUtils.getChangeName(getApplicationContext()));
44                }
45                  
46         };
47 
48        @Override
49        protected void onDestroy() {
50                super.onDestroy();
51                getContentResolver().unregisterContentObserver(cob);
52        }
53      
54          
55}
[code]
01package ty.com.lto;
02 
03import android.app.Activity;
04import android.content.ContentValues;
05import android.content.Intent;
06import android.database.ContentObservable;
07import android.database.ContentObserver;
08import android.os.Bundle;
09import android.os.Handler;
10import android.view.View;
11import android.widget.Button;
12 
13public class DataChangeTest extends Activity{
14     private Button dataBtn;
15     DataSqlite mDataSqlite;
16     @Override
17     protected void onCreate(Bundle savedInstanceState) {
18        super.onCreate(savedInstanceState);
19        setContentView(R.layout.data_change_test);
20        dataBtn = (Button)findViewById(R.id.data_test_btn);
21        mDataSqlite = new DataSqlite(this);
22        dataBtn.setOnClickListener(new View.OnClickListener() {
23             
24            public void onClick(View v) {
25                ContentValues con = new ContentValues();
26                con.put("name""数据变化了");
27                getContentResolver().insert(DataChangeProvider.CONTENT_URI, con);
28                finish();
29            }
30        });
31     }
32}
[code]
001package ty.com.lto;
002  
003  
004import android.content.ContentProvider;
005import android.content.ContentUris;
006import android.content.ContentValues;
007import android.content.Context;
008import android.content.UriMatcher;
009import android.database.Cursor;
010import android.database.SQLException;
011import android.database.sqlite.SQLiteDatabase;
012import android.database.sqlite.SQLiteOpenHelper;
013import android.database.sqlite.SQLiteQueryBuilder;
014import android.database.sqlite.SQLiteDatabase.CursorFactory;
015import android.net.Uri;
016import android.text.TextUtils;
017  
018public class DataChangeProvider extends ContentProvider{
019    private SQLiteOpenHelper mOpenHelper;
020    private static final int ALARMS = 1;
021    private static final int ALARMS_ID = 2;
022    private static final UriMatcher sURLMatcher = new UriMatcher(UriMatcher.NO_MATCH);
023    public static final Uri CONTENT_URI = Uri.parse("content://ty.com.lto/test");
024  
025    static {
026        sURLMatcher.addURI("ty.com.lto""test", ALARMS);
027        sURLMatcher.addURI("ty.com.lto""test/#", ALARMS_ID);
028    }
029     
030    private static class DatabaseHelper extends SQLiteOpenHelper{
031         private static final String TEST_DATABASE = "test.db";
032         private static final int VERSION = 1;
033          
034         public DatabaseHelper(Context context) {
035             super(context, TEST_DATABASE, null, VERSION);
036             // TODO Auto-generated constructor stub
037         }
038           
039  
040         @Override
041         public void onCreate(SQLiteDatabase db) {
042             String sql = "CREATE TABLE "+"test"+" (" +
043                     "_id INTEGER PRIMARY KEY," +
044                     "name TEXT "+
045                      ");";
046             db.execSQL(sql);
047         }
048  
049         @Override
050         public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
051             String sql = "DROP TABLE IF EXIST "+TEST_DATABASE;
052             db.execSQL(sql);
053             onCreate(db);
054         }
055          
056    }
057     
058    public DataChangeProvider() {
059    }
060     
061    @Override
062    public int delete(Uri url, String where, String[] whereArgs) {
063        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
064        int count;
065        long rowId = 0;
066        switch (sURLMatcher.match(url)) {
067            case ALARMS:
068                count = db.delete("test", where, whereArgs);
069                break;
070            case ALARMS_ID:
071                String segment = url.getPathSegments().get(1);
072                rowId = Long.parseLong(segment);
073                if (TextUtils.isEmpty(where)) {
074                    where = "_id=" + segment;
075                else {
076                    where = "_id=" + segment + " AND (" + where + ")";
077                }
078                count = db.delete("test", where, whereArgs);
079                break;
080            default:
081                throw new IllegalArgumentException("Cannot delete from URL: " + url);
082        }
083  
084        getContext().getContentResolver().notifyChange(url, null);
085        return count;
086    }
087  
088    @Override
089    public String getType(Uri url) {
090        int match = sURLMatcher.match(url);
091        switch (match) {
092            case ALARMS:
093                return "vnd.android.cursor.dir/alarms";
094            case ALARMS_ID:
095                return "vnd.android.cursor.item/alarms";
096            default:
097                throw new IllegalArgumentException("Unknown URL");
098        }
099    }
100  
101    @Override
102    public Uri insert(Uri url, ContentValues initialValues) {
103        if (sURLMatcher.match(url) != ALARMS) {
104            throw new IllegalArgumentException("Cannot insert into URL: " + url);
105        }
106  
107        ContentValues values;
108        if (initialValues != null) {
109            values = new ContentValues(initialValues);
110        else {
111            values = new ContentValues();
112        }
113             
114        if (!values.containsKey("name"))
115            values.put("name""");
116  
117        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
118        long rowId = db.insert("test"null, values);
119        if (rowId < 0) {
120            throw new SQLException("Failed to insert row into " + url);
121        }
122        Uri newUrl = ContentUris.withAppendedId(CONTENT_URI, rowId);
123        getContext().getContentResolver().notifyChange(newUrl, null);
124        return newUrl;
125    }
126  
127    @Override
128    public boolean onCreate() {
129        mOpenHelper = new DatabaseHelper(getContext());
130        return true;
131    }
132  
133    @Override
134    public Cursor query(Uri url, String[] projection, String where,
135            String[] whereArgs, String sortOrder) {
136        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
137        int match = sURLMatcher.match(url);
138        switch (match) {
139            case ALARMS:
140                qb.setTables("test");
141                break;
142            case ALARMS_ID:
143                qb.setTables("test");
144                qb.appendWhere("_id=");
145                qb.appendWhere(url.getPathSegments().get(1));
146                break;
147            default:
148                throw new IllegalArgumentException("Unknown URL " + url);
149        }
150  
151        SQLiteDatabase db = mOpenHelper.getReadableDatabase();
152        Cursor cur = qb.query(db, projection, where, whereArgs,nullnull, sortOrder);
153        if (cur != null) {
154            cur.setNotificationUri(getContext().getContentResolver(), url);
155              
156        }
157        return cur;
158    }
159  
160    @Override
161    public int update(Uri url, ContentValues values, String where,String[] whereArgs) {
162        int count;
163        long rowId = 0;
164        int match = sURLMatcher.match(url);
165        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
166        switch (match) {
167            case ALARMS_ID: {
168                String segment = url.getPathSegments().get(1);
169                rowId = Long.parseLong(segment);
170                count = db.update("test", values, "_id=" + rowId, null);
171                break;
172            }
173            default: {
174                throw new UnsupportedOperationException(
175                        "Cannot update URL: " + url);
176            }
177        }
178        getContext().getContentResolver().notifyChange(url, null);
179        return count;
180    }
181  
182}
[code]
01<?xml version="1.0" encoding="utf-8"?>
02<manifest xmlns:android="http://schemas.android.com/apk/res/android"
03      package="ty.com.lto"
04      android:versionCode="1"
05      android:versionName="1.0"
06      >
07    <application android:icon="@drawable/icon" android:label="@string/app_name">
08    <provider android:name="DataChangeProvider" android:authorities="ty.com.lto"/>
09        <activity android:name=".ListenDataTest"
10                  android:label="@string/app_name">
11            <intent-filter>
12                <action android:name="android.intent.action.MAIN" />
13                <category android:name="android.intent.category.LAUNCHER" />
14            </intent-filter>
15        </activity>
16    <activity android:name=".DataChangeTest" android:label="@string/app_name"/>
17    </application>
18<uses-permission android:name="android.permission.INTERNET"/>
19<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
20 
21</manifest>







 转载于  
http://dev.10086.cn/cmdn/bbs/thread-37427-1-1.html





posted on 2011-10-27 22:11 建华 阅读(4947) 评论(1)  编辑  收藏 所属分类: Android

评论

# re: android 使用contentobserver监听数据库内容变化  回复  更多评论   

这个监听数据库很不好用,多次走onChage函数,最可恨的是当收到长短信时(大于70个字)没操作数据库之前就走多次onChage
2011-10-31 11:32 | 本人

只有注册用户登录后才能发表评论。


网站导航: