实现跨程序数据共享
我們這里先假設(shè)先有一個(gè)A應(yīng)用程序,這個(gè)程序中存在一個(gè)BookStore數(shù)據(jù)庫(kù)和一張Book表,
然后還有一個(gè)B應(yīng)用程序,跨程序?qū)崿F(xiàn)數(shù)據(jù)共享的意思就是,通過(guò)B程序,我們可以對(duì)A程序中Book表中的數(shù)據(jù)進(jìn)行CRUD(增刪改查)操作。
下面我們就一一來(lái)實(shí)現(xiàn)A應(yīng)用程序和B應(yīng)用程序。
A應(yīng)用程序:DatabaseSave
B應(yīng)用程序:ProviderTest
我們需要實(shí)現(xiàn)ProviderTest應(yīng)用程序?qū)atabaseSave應(yīng)用程序的CRUD操作。
?
Database項(xiàng)目GitHub地址:
https://github.com/Skymqq/DatabaseSave.git
ProviderTest項(xiàng)目GitHub地址:
https://github.com/Skymqq/ProvidertTest.git
?
應(yīng)用程序A(DatabaseSave項(xiàng)目)
我們就直接引用之前創(chuàng)建的DatabaseSave項(xiàng)目文件來(lái)繼續(xù)學(xué)習(xí)。
如果你沒(méi)有看過(guò)之前的數(shù)據(jù)庫(kù)存儲(chǔ)項(xiàng)目,可以去GitHub下載一下,項(xiàng)目地址:
https://github.com/Skymqq/DatabaseSave.git
下載之后導(dǎo)入到AS中后,新建一個(gè)ContentProvider,步驟如下:
new---》other---》ContentProvider
可以看到,我們將
內(nèi)容提供器命名為DatabaseProvider
authority指定為com.example.databasesave.provider
Exported屬性表示是否允許外部程序訪問(wèn)我們的內(nèi)容提供器
Enabled屬性表示是否啟用這個(gè)內(nèi)容提供器。
將兩個(gè)屬性都勾上,點(diǎn)擊Finish完成創(chuàng)建。
DatabaseProvider.java代碼:
package com.example.administrator.databasesave;import android.content.ContentProvider; import android.content.ContentValues; import android.content.UriMatcher; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.net.Uri;public class DatabaseProvider extends ContentProvider {public static final int BOOK_DIR = 0;public static final int BOOK_ITEM = 1;public static final int CATEGORY_DIR = 2;public static final int CATEGORY_ITEM = 3;public static final String AUTHORITY = "com.example.databasesave.provider";private static UriMatcher uriMatcher;private MyDatabaseHelper helper;static {//在靜態(tài)代碼塊中對(duì)UriMatcher進(jìn)行初始化操作,并將期望匹配的幾種URI格式添加進(jìn)去uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);uriMatcher.addURI(AUTHORITY, "book", BOOK_DIR);uriMatcher.addURI(AUTHORITY, "book/#", BOOK_ITEM);uriMatcher.addURI(AUTHORITY, "category", CATEGORY_DIR);uriMatcher.addURI(AUTHORITY, "category/#", CATEGORY_ITEM);}@Overridepublic boolean onCreate() {//完成創(chuàng)建、升級(jí) BookStore數(shù)據(jù)庫(kù)helper = new MyDatabaseHelper(getContext(), "BookStore.db", null, 2);return true;}@Overridepublic Cursor query(Uri uri, String[] projection, String selection,String[] selectionArgs, String sortOrder) {//查詢數(shù)據(jù)SQLiteDatabase db = helper.getWritableDatabase();Cursor cursor = null;switch (uriMatcher.match(uri)) {case BOOK_DIR:cursor = db.query("Book", projection, selection, selectionArgs, null, null, sortOrder);break;case BOOK_ITEM:String bookId = uri.getPathSegments().get(1);cursor = db.query("Book", projection, "id = ?", new String[]{bookId}, null, null, sortOrder);break;case CATEGORY_DIR:cursor = db.query("Category", projection, selection, selectionArgs, null, null, sortOrder);break;case CATEGORY_ITEM:String categoryId = uri.getPathSegments().get(1);cursor = db.query("Category", projection, "id = ?", new String[]{categoryId}, null, null, sortOrder);break;default:break;}return cursor;}@Overridepublic Uri insert(Uri uri, ContentValues values) {//添加數(shù)據(jù)SQLiteDatabase db = helper.getWritableDatabase();Uri uriReturn = null;switch (uriMatcher.match(uri)) {case BOOK_DIR:case BOOK_ITEM:long newBookId = db.insert("Book", null, values);uriReturn = Uri.parse("content://" + AUTHORITY + "/book/" + newBookId);break;case CATEGORY_DIR:case CATEGORY_ITEM:long newCategoryId = db.insert("Category", null, values);uriReturn = Uri.parse("content://" + AUTHORITY + "/category/" + newCategoryId);break;default:break;}return uriReturn;}@Overridepublic int update(Uri uri, ContentValues values, String selection,String[] selectionArgs) {//更新數(shù)據(jù)SQLiteDatabase db = helper.getWritableDatabase();int updateRows = 0;switch (uriMatcher.match(uri)) {case BOOK_DIR:updateRows = db.update("Book", values, selection, selectionArgs);break;case BOOK_ITEM:String bookId = uri.getPathSegments().get(1);updateRows = db.update("Book", values, "id = ?", new String[]{bookId});break;case CATEGORY_DIR:updateRows = db.update("Category", values, selection, selectionArgs);break;case CATEGORY_ITEM:String categoryId = uri.getPathSegments().get(1);updateRows = db.update("Category", values, "id = ?", new String[]{categoryId});break;default:break;}return updateRows;}@Overridepublic int delete(Uri uri, String selection, String[] selectionArgs) {//刪除數(shù)據(jù)SQLiteDatabase db = helper.getWritableDatabase();int deleteRows = 0;switch (uriMatcher.match(uri)) {case BOOK_DIR:deleteRows = db.delete("Book", selection, selectionArgs);break;case BOOK_ITEM:String bookId = uri.getPathSegments().get(1);deleteRows = db.delete("Book", "id = ?", new String[]{bookId});break;case CATEGORY_DIR:deleteRows = db.delete("Category", selection, selectionArgs);break;case CATEGORY_ITEM:String categoryId = uri.getPathSegments().get(1);deleteRows = db.delete("Category", "id = ?", new String[]{categoryId});break;default:break;}return deleteRows;}@Overridepublic String getType(Uri uri) {switch (uriMatcher.match(uri)) {case BOOK_DIR:return "vnd.android.cursor.dir/vnd.com.example.databasesave.provider.book";case BOOK_ITEM:return "vnd.android.cursor.item/vnd.com.example.databasesave.provider.book";case CATEGORY_DIR:return "vnd.android.cursor.dir/vnd.com.example.databasesave.provider.category";case CATEGORY_ITEM:return "vnd.android.cursor.item/vnd.com.example.databasesave.provider.category";}return null;}}MyDatabaseHelper.java代碼:
package com.example.administrator.databasesave;import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.widget.Toast;public class MyDatabaseHelper extends SQLiteOpenHelper {private Context context;public static final String CREATE_BOOK = "create table Book(" +"id integer primary key autoincrement," +"author text," +"price real," +"pages integer," +"name text)";public static final String CREATE_CATEGORY = "create table Category(" +"id integer primary key autoincrement," +"category_name text," +"category_code integer)";public MyDatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {super(context, name, factory, version);this.context = context;}@Overridepublic void onCreate(SQLiteDatabase db) {db.execSQL(CREATE_BOOK);//執(zhí)行sql語(yǔ)句創(chuàng)建Book表db.execSQL(CREATE_CATEGORY);//執(zhí)行sql語(yǔ)句創(chuàng)建Category表}@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {db.execSQL("drop table if exists Book");db.execSQL("drop table if exists Category");onCreate(db);} }?
AndroidManifest.xml代碼:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.example.administrator.databasesave"><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><applicationandroid:allowBackup="true"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/AppTheme"><activity android:name=".MainActivity"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity><providerandroid:name=".DatabaseProvider"android:authorities="com.example.databasesave.provider"android:enabled="true"android:exported="true"></provider></application></manifest>現(xiàn)在這個(gè)DatabaseSave項(xiàng)目已經(jīng)擁有了跨程序共享數(shù)據(jù)的功能了,再此,我們先將之前運(yùn)行在模擬器上的DatabaseSave應(yīng)用卸載,再重新安裝應(yīng)用,以防止之前的項(xiàng)目文件對(duì)我們?cè)斐筛蓴_。
?
?
應(yīng)用程序B(ProviderTest項(xiàng)目)
下面我們?cè)傩陆ㄒ粋€(gè)ProviderTest項(xiàng)目,我們希望通過(guò)這個(gè)新建的項(xiàng)目去訪問(wèn)DatabaseSave項(xiàng)目中的數(shù)據(jù),從而實(shí)現(xiàn)跨程序共享數(shù)據(jù)的功能。
activity_main.xml代碼:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><Buttonandroid:id="@+id/btn_add"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="Add Data To Book"android:textAllCaps="false"android:textSize="18sp"android:textStyle="bold" /><Buttonandroid:id="@+id/btn_query"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="Query Data From Book"android:textAllCaps="false"android:textSize="18sp"android:textStyle="bold" /><Buttonandroid:id="@+id/btn_update"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="Update Book"android:textAllCaps="false"android:textSize="18sp"android:textStyle="bold" /><Buttonandroid:id="@+id/btn_delete"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="Delete Data From Book"android:textAllCaps="false"android:textSize="18sp"android:textStyle="bold" /></LinearLayout>MainActivity.java代碼:
package com.example.administrator.providertest;import android.content.ContentValues; import android.database.Cursor; import android.net.Uri; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.Toast;public class MainActivity extends AppCompatActivity implements View.OnClickListener {private static final String TAG = "MainActivity";private Button btn_add, btn_query, btn_update, btn_delete;private String newId;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();//初始化UI控件}private void initView() {btn_add = (Button) findViewById(R.id.btn_add);btn_query = (Button) findViewById(R.id.btn_query);btn_update = (Button) findViewById(R.id.btn_query);btn_delete = (Button) findViewById(R.id.btn_delete);btn_add.setOnClickListener(this);btn_query.setOnClickListener(this);btn_update.setOnClickListener(this);btn_delete.setOnClickListener(this);}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.btn_add:add();//添加數(shù)據(jù)Toast.makeText(this, "add successfully", Toast.LENGTH_SHORT).show();break;case R.id.btn_query:query();//查詢數(shù)據(jù)Toast.makeText(this, "query successfully", Toast.LENGTH_SHORT).show();break;case R.id.btn_update:update();//更新數(shù)據(jù)Toast.makeText(this, "update successfully", Toast.LENGTH_SHORT).show();break;case R.id.btn_delete:delete();//刪除數(shù)據(jù)Toast.makeText(this, "delete successfully", Toast.LENGTH_SHORT).show();break;default:break;}}private void add() {Uri uri = Uri.parse("content://com.example.databasesave.provider/book");ContentValues cv = new ContentValues();cv.put("name", "A Clash of Kings");cv.put("author", "George Martin");cv.put("pages", 1040);cv.put("price", 22.85);Uri newUri = getContentResolver().insert(uri, cv);newId = newUri.getPathSegments().get(1);}private void query() {Uri uri = Uri.parse("content://com.example.databasesave.provider/book");Cursor cursor = getContentResolver().query(uri, null, null, null, null);if (cursor != null) {while (cursor.moveToNext()) {String name = cursor.getString(cursor.getColumnIndex("name"));String author = cursor.getString(cursor.getColumnIndex("author"));int pages = cursor.getInt(cursor.getColumnIndex("pages"));double price = cursor.getDouble(cursor.getColumnIndex("price"));Log.e(TAG, "book name is " + name);Log.e(TAG, "book author is " + author);Log.e(TAG, "book pages are " + pages);Log.e(TAG, "book price is " + price);}cursor.close();}}private void update() {Uri uri = Uri.parse("content://com.example.databasesave.provider/book/" + newId);ContentValues cv = new ContentValues();cv.put("name", "A Storm of Swords");cv.put("pages", 1216);cv.put("price", 24.05);getContentResolver().update(uri, cv, null, null);}private void delete() {Uri uri = Uri.parse("content://com.example.databasesave.provider/book/" + newId);getContentResolver().delete(uri, null, null);} }運(yùn)行ProviderTest應(yīng)用程序:
1.添加數(shù)據(jù)
在PrioviderTest中點(diǎn)擊Add Data To Book按鈕向Book表中添加數(shù)據(jù)
使用adb shell查看Book表中的數(shù)據(jù)如下:
?
2.查詢數(shù)據(jù):
在PrioviderTest中點(diǎn)擊Query Data From Book按鈕從Book表中查詢數(shù)據(jù):
ProviderTest中的Logcat將Book表中查詢出來(lái)的數(shù)據(jù)打印:
?
3.更新數(shù)據(jù):
在PrioviderTest中點(diǎn)擊Update Data 按鈕更新Book表中的數(shù)據(jù):
Logcat打印:
未更新前的數(shù)據(jù):
更新后的數(shù)據(jù):
4.刪除數(shù)據(jù):
在PrioviderTest中點(diǎn)擊Delete Data From Book按鈕刪除Book表中的數(shù)據(jù):
adb shell查看Book表中是否還有數(shù)據(jù):
說(shuō)明我們的刪除功能也是可以使用的。
?
跨程序共享數(shù)據(jù)的CRUD操作,基本上就這些。
?
?
總結(jié)
- 上一篇: 假山可以做石敢当吗?
- 下一篇: 相对布局(RelativeLayout)