- 浏览: 22829 次
文章分类
最新评论
多线程中,线程之间程序空间和数据空间是共享的 (局部变量不共享)。
如下的代码中是测试自定义contentprovider和contentobserver的实例,
在代码中,contentsevice和activity分别在不同的线程中,onchange就是在contentservice的线程中被执行的,而它访问里activity线程中的mhandler数据变量。
package com.test;
import android.R.bool; import android.R.integer; import android.app.Activity; import android.app.AlertDialog; import android.content.ContentProvider; import android.content.ContentResolver; import android.content.ContentValues; import android.content.DialogInterface; import android.database.ContentObserver; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.CompoundButton; import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.Switch; //import android.widget.Switch; import android.widget.TextView; import android.widget.Toast; /*当开关状体发生发生变化时更新状态,当点击textview是插入一个条目 * 当数据库发生变化时,observer会在contentservice的线程中被调用onchang(),在onchange中我们通知主线程数据库发生了变化。 * 主线程的handler主要处理数据库的变化,这里这是简单的打印*/ public class TestContentObserverActivity extends Activity { /** Called when the activity is first created. */ private int num=0; private Boolean bool = true; private ContentResolver mContentResolver; private Handler mHandler = new Handler(){ /* (non-Javadoc) * @see android.os.Handler#handleMessage(android.os.Message) */ @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub // super.handleMessage(msg); Log.d("", "handle maeesage "+ num+" "+Thread.currentThread()+" "+mHandler.getLooper().getThread()); } }; private ContentObserver contentObserver = new ContentObserver(null) { /* (non-Javadoc) * @see android.database.ContentObserver#onChange(boolean) */ @Override public void onChange(boolean selfChange) { // TODO Auto-generated method stub // super.onChange(selfChange); Log.d("", "observer onchang"+ getTaskId()+Thread.currentThread()+" "+num); // mTextView.setText(""+num); 不能再子线程中更新UI num = num +1; Message msg = new Message(); mHandler.sendMessage(msg); /*Looper.prepare(); Toast.makeText(getApplicationContext(), "change", Toast.LENGTH_SHORT).show(); Looper.loop(); 子线程中无法获取操作窗口的权限,所以次数不能显示dialog final AlertDialog.Builder mBuilder = new AlertDialog.Builder(getApplicationContext()); mBuilder.setTitle("observer"); mBuilder.setMessage("good"); mBuilder.setPositiveButton(((CharSequence)"ok"), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub mBuilder.create().dismiss(); } }); mBuilder.setNegativeButton(((CharSequence)"cancel"), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub AlertDialog mAlertDialog = mBuilder.create(); } }); mBuilder.create().show();*/ } }; private Switch mSwitch; private TextView mTextView; @Override public void onCreate(Bundle savedInstanceState) { Log.d("", "activity create" +getTaskId()+Thread.currentThread()); super.onCreate(savedInstanceState); setContentView(R.layout.main); mContentResolver = getContentResolver(); mSwitch=(Switch) findViewById(R.id.switch1); mTextView= (TextView) findViewById(R.id.text); mTextView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub Log.d("", "onclick "+Thread.currentThread()); Uri uri = Uri.parse("content://com.test/observer"); ContentValues values = new ContentValues(); values.put("status", bool); getContentResolver().insert(uri, values); } }); mSwitch.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { // TODO Auto-generated method stub Log.d("", "onCheckedChanged " +Thread.currentThread()); Uri uri = Uri.parse("content://com.test/observer"); ContentValues values = new ContentValues();; values.put("status", isChecked); String where = "status =?"; Boolean boo = !isChecked; String[] whereArgs = {boo.toString()}; getContentResolver().update(uri, values, where, whereArgs); } }); mContentResolver.registerContentObserver(Uri.parse("content://com.test/observer"), true, contentObserver); } /* (non-Javadoc) * @see android.app.Activity#onResume() */ @Override protected void onResume() { // TODO Auto-generated method stub super.onResume(); Log.d("", "activity resume"); // ContentValues mValues = new ContentValues(); // mValues.put("status", false); // mContentResolver.insert(Uri.parse("content://com.test/observer"), mValues); } public ContentObserver getContentObserver(){ return contentObserver; } public static TestContentObserverActivity getTestContentObserverActivity(){ return new TestContentObserverActivity(); } }
package com.test;
import android.content.ContentProvider; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; import android.content.UriMatcher; import android.database.ContentObserver; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.net.Uri; import android.util.Log; public class MyContentProvider extends ContentProvider{ private static final UriMatcher sURLMatcher = new UriMatcher( UriMatcher.NO_MATCH); private Boolean bool = true; static { sURLMatcher.addURI("com.test", "observer", 1); sURLMatcher.addURI("com.test", "observer/#", 2); // sURLMatcher.addURI("com.test", "location", LOCATIONS); // sURLMatcher.addURI("com.test", "apps", APPS); } // private ContentObserver contentObserver = TestContentObserverActivity.getTestContentObserverActivity().getContentObserver(); private SQLiteDatabase mSqLiteDatabase; private SQLiteOpenHelper mSqLiteOpenHelper; public class MySQLiteOpenHelper extends SQLiteOpenHelper{ public MySQLiteOpenHelper(Context context){ super(context, "mydb.db", null, 6); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // TODO Auto-generated method stub Log.d("", "helper upgrade"); db.execSQL("drop table if exists observer"); onCreate(db); } @Override public void onCreate(SQLiteDatabase db) { // TODO Auto-generated method stub Log.d("", "helper create"); String sql="CREATE TABLE if not exists observer(_id INTEGER primary key autoincrement, status Boolean)"; if (db==null) Log.d("", "helper create failed"); db.execSQL(sql); } } /* (non-Javadoc) * @see android.content.ContentProvider#onCreate() */ @Override public boolean onCreate() { // TODO Auto-generated method stub Log.d("", "mycontentprovider create"); Context context = getContext(); Log.d("",""+context); if (mSqLiteOpenHelper == null) mSqLiteOpenHelper = new MySQLiteOpenHelper(context); return true; } /* (non-Javadoc) * @see android.content.ContentProvider#query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String) */ @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { // TODO Auto-generated method stub return null; } /* (non-Javadoc) * @see android.content.ContentProvider#insert(android.net.Uri, android.content.ContentValues) */ @Override public Uri insert(Uri uri, ContentValues values) { Log.d("", "mycontentprovider insert"); // TODO Auto-generated method stub SQLiteDatabase mDatabase = mSqLiteOpenHelper.getWritableDatabase(); mDatabase.insert("observer", null, values); Context context = getContext(); context.getContentResolver().notifyChange(uri, null); return null; } /* (non-Javadoc) * @see android.content.ContentProvider#update(android.net.Uri, android.content.ContentValues, java.lang.String, java.lang.String[]) */ @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { Log.d("", "mycontentprovider update"); // TODO Auto-generated method stub SQLiteDatabase mDatabase = mSqLiteOpenHelper.getWritableDatabase(); mDatabase.update("observer", values, selection, selectionArgs); Context context = getContext(); context.getContentResolver().notifyChange(uri, TestContentObserverActivity.getTestContentObserverActivity().getContentObserver()); return 1; } @Override public String getType(Uri uri) { // TODO Auto-generated method stub int match = sURLMatcher.match(uri); switch (match) { case 1: return "vnd.android.cursor.dir/observer"; case 2: return "vnd.android.cursor.item/observer"; default: throw new IllegalArgumentException("Unknown URL"); } } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { // TODO Auto-generated method stub return 0; } }
其他的应用访问数据库:
package com.test1; import android.R.integer; import android.app.Activity; import android.content.ContentResolver; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.util.Log; public class TestsqlActivity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); query(); } private void query(){ Uri uri=Uri.parse("content://com.test/observer"); ContentResolver mcr= getContentResolver(); Cursor mCursor = mcr.query(uri, new String[]{"_id","status"},null, null, null); // mCursor.moveToFirst(); while(mCursor.moveToNext()){ Log.d("111111111 ", "_id = "+ mCursor.getColumnIndex("_id")+", status= "+ mCursor.getColumnIndex("status")); int id = mCursor.getInt(mCursor.getColumnIndex("_id")); int status = mCursor.getInt(mCursor.getColumnIndex("status")); Log.d(" 2222", "_id = "+ id+", status= "+ status); Log.d("3333 ", ""+mCursor); } mCursor.close(); } }
相关推荐
Android高级编程雪梨作业之自定义ContentProvider 将任务01生词本作业中生成的生词本数据库通过自定义ContentProvider的方式,共享给其他应用。 要求如下: (1) 使用自定义SQLiteOpenHelper来管理数据库; (2) 提交...
自定义ContentProvider实例,包含提供数据端和读取数据端
这是学习ContentProvider的第二个练习。 里面自定义ContentProvider类来与SQLite交互。 大致类容就是:通过ContentProvider,创建自己的.db,操作自己的.db. 代码里有详细的解释
自定义contentprovider 在其它应用中访问该应用暴露的数据。
NULL 博文链接:https://sunzone.iteye.com/blog/1884167
android 数据库 以及自定义ContentProvider demo
android 自定义 ContentProvider 以及 ContentResolver
ContentProvider自定义以及使用系统ContentProvider
NULL 博文链接:https://catkingwong.iteye.com/blog/1313740
自定义ContentProvider完成数据交互,文章:http://write.blog.csdn.net/postedit/43950781
资源包涵两个Demo,其中一个是自定义的ContentProvider,另一个demo是访问第一个demo的ContentProvider并且去读写第一个demo的数据库。
应用A(TestBaidu)调用另外一个应用(TestContentProvider)中的自定义ContentProvider,具体实现如下,感兴趣的朋友可以参考下哈
Android 自定义ContentProvider简单实例 Android允许我们定义自己的的ContentProvider对象来共享数据,练练手,简单来实现一下。 要使用ContentProvider来操作数据,必须要有保存数据的场所。可以使用文件或SQLite...
android自定义ContentProvider,可以实现程序之间共享数据
********************************************** 通过SQLiteDatabase实现自定义ContentProvider增删改查 *********************************************
在android中自定义一个ContentProvider大致需要四步:1,定义数据的MetaData;2,定义一个类继承ContentProvider;3,覆写自定义类中的getType(),onCreate(),insert(),delete(),update(),query()六个方法;4,在...