Android ContentProvider一个不恰当的简例实战却能说明道理
周末了,闲来无事看了网上几篇大神的博客,写的不错,适合入门,遂自己建了一个工程按照自己想法捣腾了一阵子,就有了下边代码的诞生。特别感谢这几篇博文,有了牛人博文在也用买书了,全是干货,麻麻、爸比再也不用担心我的学习了!
致谢:Android四大组件介绍 里面对方法参数的汉语注释简直就是雪中送炭,同事我把你的汉语注释部分copy到了我的方法上(方便日后查阅,哈哈)。
ContentProvider是Android在不同应用程序之间实现数据共享的一种机制。一个应用如果需要让别的程序可以操作自己的数据,即可采用这种机制。并且此种方式忽略了底层的数据存储实现,ContentProvider提供了一种统一的通过Uri实现数据操作的方式。其步骤为:1. 在当前应用程序中定义一个ContentProvider。2. 在当前应用程序的AndroidManifest.xml中注册此ContentProvider。3. 其他应用程序通过ContentResolver和Uri来获取此ContentProvider的数据。ContentResolver提供了诸如insert(), delete(), query()和update()之类的方法。用于实现对ContentProvider中数据的存取操作。
Uri是一个通用资源标志符,将其分为A,B,C,D 4个部分:1、无法改变的标准前缀,包括;"content://"、"tel://"等。当前缀是"content://"时,说明通过一个Content Provider控制这些数据。2、URI的标识,它通过authorities属性声明,用于定义了是哪个ContentProvider提供这些数据。对于第三方应用程序,为了保证URI标识的唯一性,它必须是一个完整的、小写的 类名。例如;"content://com.jesse.myprovider"。3、路径,可以近似的理解为需要操作的数据库中表的名字,如:"content://yb.android.jesse.myprovider/name"中的name。4、如果URI中包含表示需要获取的记录的ID;则就返回该id对应的数据,如果没有ID,就表示返回全部。
ContentProvider这种存储方式相比SQLite和SharedPreferences,其复杂性太明显了,但是在处处可见“云端服务”的今天(不是“莞式服务”(哈哈))数据交互需求使得ContentProvider越来也特么重要了。
上代码:功能:contentprovidertest这个apk提供通过ContentProvider创建数据源(类似云端),contentresolvertest这个apk用来取数据显示。重点之重点已经红色高亮了。
contentprovidertest apk代码:
MainActivity.java
package com.example.contentprovidertest; import android.os.Bundle; import android.app.Activity; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); MyContentProvider contentProvider = new MyContentProvider(); } }
MyContentProvider.java
package com.example.contentprovidertest; import android.content.ContentProvider; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.net.Uri; public class MyContentProvider extends ContentProvider { private static final String DBASE_TABLE_NAME = "tel_number_tab"; private static final String DBASE_FILE_NAME = "StudyContentProvider.db"; /** * 初始化操作 */ public boolean onCreate() { // TODO Auto-generated method stub SQLiteDatabase mDataBase = this.getContext().openOrCreateDatabase(DBASE_FILE_NAME, Context.MODE_PRIVATE, null); mDataBase.execSQL("CREATE TABLE " +DBASE_TABLE_NAME+ " (_id INTEGER PRIMARY KEY AUTOINCREMENT, tel_num TEXT NOT NULL)"); //模拟数据方法调运 insertDbaseData(mDataBase); mDataBase.close(); return true; } /** * 从内容提供者中删除数据(允许其他应用删除你应用的数据时重写) * @param uri * @param selection 条件语句 * @param selectionArgs 参数 * @return */ public int delete(Uri uri, String selection, String[] selectionArgs) { // TODO Auto-generated method stub return 0; } /** * 用于返回当前Uri所代表数据的MIME类型 * 如果操作的数据为集合类型(多条数据),那么返回的类型字符串应该为vnd.android.cursor.dir/开头 * 例如要得到所有person记录的Uri为content://com.bravestarr.provider.personprovider/person, * 那么返回的MIME类型字符串应该为"vnd.android.cursor.dir/person" * 如果操作的数据为单一数据,那么返回的类型字符串应该为vnd.android.cursor.item/开头 * 例如要得到id为10的person记录的Uri为content://com.bravestarr.provider.personprovider/person/10, * 那么返回的MIME类型字符串应该为"vnd.android.cursor.item/person" * @param uri */ public String getType(Uri uri) { // TODO Auto-generated method stub return null; } /** * 插入数据到内容提供者(允许其他应用向你的应用中插入数据时重写) * @param uri * @param initialValues 插入的数据 * @return */ public Uri insert(Uri uri, ContentValues values) { // TODO Auto-generated method stub return null; } /** * 返回数据给调用者(允许其他应用从你的应用中获取数据时重写) * @param uri * @param projection 列名 * @param selection 条件语句 * @param selectionArgs 参数 * @param sortOrder 排序 * @return */ public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { // TODO Auto-generated method stub SQLiteDatabase mDataBase = this.getContext().openOrCreateDatabase(DBASE_FILE_NAME, Context.MODE_PRIVATE, null); Cursor cursor = mDataBase.query(DBASE_TABLE_NAME, null, null, null, null, null, null); return cursor; } /** * 更新内容提供者已存在的数据(允许其他应用更新你应用的数据时重写) * @param uri * @param values 更新的数据 * @param selection 条件语句 * @param selectionArgs 参数 * @return */ public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { // TODO Auto-generated method stub return 0; } //-------------------------------------------------------------------------------- //Jesse逻辑模拟产生电话号码数据库数据方法 private void insertDbaseData(SQLiteDatabase db) { for (int index=0; index<5; index++) { ContentValues values =new ContentValues(); values.put("tel_num", "156999999" + index + (index+1)); db.insert(DBASE_TABLE_NAME, "_id", values); } } }
AndroidMainifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.contentprovidertest" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="17" android:targetSdkVersion="18" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.example.contentprovidertest.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <provider android:name=".MyContentProvider" android:exported="true" android:authorities="com.example.MyContentProvider"/> </application> </manifest>
contentresolvertest apk代码:
MainActivity.java
package com.jesse.contentresolvertest; import android.net.Uri; import android.os.Bundle; import android.widget.TextView; import android.app.Activity; import android.content.ContentResolver; import android.content.Context; import android.database.Cursor; public class MainActivity extends Activity { private Context mContext; private TextView mTextView; private String mTelNum = ""; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mContext = MainActivity.this; mTextView = (TextView) this.findViewById(R.id.tel); ContentResolver resolver = mContext.getContentResolver(); Uri uri = Uri.parse("content://com.example.MyContentProvider"); Cursor cursor = resolver.query(uri, null, null, null, null); cursor.moveToFirst(); for(int i=0; i<cursor.getCount(); i++){ int index = cursor.getColumnIndexOrThrow("tel_num"); String src = cursor.getString(index); mTelNum = mTelNum + src + "\n"; cursor.moveToNext(); } cursor.close(); mTextView.setText(mTelNum); } }
说明:contentprovidertest apk运行后产生数据库和对外声明的URL,contentresolvertest apk通过URL访问不是自己apk所属目录下的数据库资源。这就是一个简单的用来理解概念的实战实例。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。