日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

Android中的跨进程通信方法实例及特点分析(二):ContentProvider

發(fā)布時(shí)間:2025/7/14 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android中的跨进程通信方法实例及特点分析(二):ContentProvider 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1.ContentProvider簡單介紹 ? ? ? ?

? ? ? ?在Android中有些數(shù)據(jù)(如通訊錄、音頻、視頻文件等)是要供非常多應(yīng)用程序使用的。為了更好地對(duì)外提供數(shù)據(jù),Android系統(tǒng)給我們提供了Content Provider使用,通過它能夠訪問上面所說的數(shù)據(jù)。比如非常多音樂播放器中的掃描功能事實(shí)上就用到了Content Provider功能(當(dāng)然,也有的播放器是自己去實(shí)現(xiàn)更底層的功能)。

這種優(yōu)點(diǎn)是統(tǒng)一管理,比方添加了某個(gè)音頻文件,底層就會(huì)將這種變化通知Content Provider。從而當(dāng)應(yīng)用程序訪問時(shí)就能夠獲得當(dāng)前最新的數(shù)據(jù)。

? ? ? ?當(dāng)然,Android也同意我們定義自己的Content Provider。僅僅要繼承它的基類,而且實(shí)現(xiàn)以下的方法就可以。

public boolean?onCreate() 在創(chuàng)建ContentProvider時(shí)調(diào)用
public Cursor?query(Uri, String[], String, String[], String):用于查詢指定Uri的ContentProvider,返回一個(gè)Cursor
public Uri?insert(Uri, ContentValues):依據(jù)指定的Uri加入數(shù)據(jù)到ContentProvider中
public int?update(Uri, ContentValues, String, String[]):用于更新指定Uri的ContentProvider中的數(shù)據(jù)
public int?delete(Uri, String, String[]):依據(jù)Uri刪除指定的數(shù)據(jù)
public String?getType(Uri):用于返回指定的Uri中的數(shù)據(jù)的MIME類型
*假設(shè)操作的數(shù)據(jù)屬于集合類型。那么MIME類型字符串應(yīng)該以vnd.android.cursor.dir/開頭。
比如:要得到全部p1記錄的Uri為content://contacts/p1。那么返回的MIME類型字符串為"vnd.android.cursor.dir/p1"。


*假設(shè)要操作的數(shù)據(jù)屬于非集合類型數(shù)據(jù),那么MIME類型字符串應(yīng)該以vnd.android.cursor.item/開頭。
比如:要得到id為100的student記錄的Uri為content://contacts/student/100,那么返回的MIME類型字符串應(yīng)為"vnd.android.cursor.item/student"。


2.Uri簡單介紹

? ? ?一個(gè)標(biāo)準(zhǔn)的Uri為content://authority/path可分為下面三部分:

(1)content://:這個(gè)部分是ContentProvider規(guī)定的,就像http://代表Http這個(gè)協(xié)議一樣。使用ContentProvider的協(xié)議是content://

(2)authorities:它在所在的Android系統(tǒng)必須是唯一的。由于系統(tǒng)就是通過它來決定操作或訪問哪個(gè)ContentProvider的。這與互聯(lián)網(wǎng)上的網(wǎng)址必須唯一是一樣的道理。

(3)path:資源路徑。

? ? ? ?顯然,從上面的分析能夠看出ContentProvider盡管也可實(shí)現(xiàn)跨進(jìn)程通信。可是它適用的場景主要是與數(shù)據(jù)庫相關(guān)。有時(shí)也可能是文本文件或XML等存儲(chǔ)方式。

3.ContentResolver

? ? ? ?假設(shè)僅僅是定義一個(gè)ContentProvider的話,沒有不論什么意義,由于ContentProvider僅僅是內(nèi)容提供者。它要被別的應(yīng)用(進(jìn)程)讀取才有價(jià)值。與實(shí)現(xiàn)ContentProvder的方法相相應(yīng),使用ContentResolver相關(guān)的方法例如以下所看到的:

getContentResolver():Context類提供的。用于獲取ContentResolver對(duì)象。

insert(Uri uri,ContentValues values):向Uri相應(yīng)的ContentProvider中插入values相應(yīng)的數(shù)據(jù);

update(Uri uri,ContentValues values,String where,String[]selectionArgs):更新Uri相應(yīng)的ContentProvider中where處的數(shù)據(jù),當(dāng)中selectionArgs是篩選參數(shù)。

query(Uri uri,String[]projection,String selection,String[]selectionArgs,String sortOrder):查詢Uri相應(yīng)的ContentProvider中where處的數(shù)據(jù),當(dāng)中selectionArgs是篩選參數(shù)。sortOrder是排序方式;

delete(Uri uri,String where,String[]selectionArgs):刪除Uri相應(yīng)的ContentProvider中where處的數(shù)據(jù)。當(dāng)中selectionArgs是篩選參數(shù)。

4.UriMatcher

? ? ? 為了確定一個(gè)ContentProvider實(shí)際能處理的Uri,以及確定每一個(gè)方法中Uri參數(shù)所操作的數(shù)據(jù)。Android系統(tǒng)提供了UriMatcher工具類。它主要有例如以下兩個(gè)方法:

(1)void addURI(String authority,String path,String code):該方法用于向UriMatcher對(duì)象注冊(cè)Uri。當(dāng)中authority和path組合成一個(gè)Uri,而code則代表該Uri相應(yīng)的標(biāo)識(shí)碼;

(2)int match(Uri uri):依據(jù)前面注冊(cè)的Uri來推斷指定Uri相應(yīng)的標(biāo)識(shí)碼。假設(shè)找不到匹配的標(biāo)識(shí)碼,該方法將會(huì)返回-1。

? ? ? ? 以下通過兩個(gè)實(shí)例來解說ContentProvider的使用方法,第一個(gè)實(shí)例是自定義了一個(gè)ContentProvider而且在還有一個(gè)應(yīng)用中讀取它。第二個(gè)實(shí)例是讀取當(dāng)前手機(jī)中的聯(lián)系人。

? ? ? ?首先是第一個(gè)樣例,項(xiàng)目結(jié)構(gòu)例如以下圖所看到的:


以下是各個(gè)類的代碼,首先是常量的定義:

package com.android.student.utils;import android.net.Uri;/*** 這里定義了與ContentProvider相關(guān)的字符串以及Student相應(yīng)的數(shù)據(jù)表中的字段* @author Bettar**/ public class StudentWords {//注意Manifest文件里的authorities屬性要跟這里保持一致。public static final String AUTHORITY="com.android.student.provider";public static final Uri STUDENT_WITH_ID_URI=Uri.parse("content://"+AUTHORITY+"/student");public static final Uri STUDENT_URI=Uri.parse("content://"+AUTHORITY+"/student");public static final String TABLE_NAME="student";public static final String ID="id";public static final String NAME="name";public static final String SCORE="score";public static final String ADDR="address";} 然后是數(shù)據(jù)庫幫助類:

import com.android.student.utils.StudentWords;import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.widget.Toast;public class StudentDbHelper extends SQLiteOpenHelper{private Context context;public StudentDbHelper(Context context,String name,int version){super(context,name,null,version);this.context=context;}@Overridepublic void onCreate(SQLiteDatabase db){String createSQL="create table "+StudentWords.TABLE_NAME+"("+StudentWords.ID+" integer primary key autoincrement,"+StudentWords.NAME+" varchar,"+StudentWords.SCORE+" integer,"+StudentWords.ADDR+" varchar)";db.execSQL(createSQL);}@Overridepublic void onUpgrade(SQLiteDatabase db,int oldVersion,int newVersion){//升級(jí)版本號(hào)時(shí),可能要運(yùn)行表結(jié)構(gòu)的改動(dòng)之類,此處臨時(shí)不考慮升級(jí)問題,因而僅僅是用Toast提示Toast.makeText(context, "newVersion:"+newVersion+" will replace oldVersion:"+oldVersion,Toast.LENGTH_LONG).show(); }} 最后是ContentProvider類的定義:

package com.android.student.provider;import com.android.student.database.StudentDbHelper;import android.content.ContentProvider; import android.content.ContentUris; import android.content.ContentValues; import android.content.UriMatcher; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.net.Uri; import android.provider.UserDictionary.Words;import com.android.student.utils.StudentWords;public class StudentProvider extends ContentProvider{private static final String TAG="StudentProvider";private static UriMatcher matcher=new UriMatcher(UriMatcher.NO_MATCH);private static final int STUDENT_WITH_ID=1;private static final int STUDENT=2;private StudentDbHelper dbHelper;static{matcher.addURI(StudentWords.AUTHORITY,"student/#",STUDENT_WITH_ID);//matcher.addURI(StudentWords.AUTHORITY, "student", SINGLE_STUDENT);//注意當(dāng)中的#為通配符matcher.addURI(StudentWords.AUTHORITY, "student", STUDENT);}@Overridepublic boolean onCreate(){dbHelper=new StudentDbHelper(this.getContext(),"student.db3",1);return true;}@Overridepublic String getType(Uri uri){switch(matcher.match(uri)){case STUDENT_WITH_ID:return "vnd.android.cursor.item/com.android.student"; case STUDENT:return "vnd.android.cursor.dir/com.android.student";default:throw new IllegalArgumentException("Unknown Uri:"+uri);}}/*** 由單一的selection這一個(gè)篩選條件組合成包括id的復(fù)雜篩選條件* @param uri* @param selection* @return*/private String getComplexSelection(Uri uri,String selection){long id=ContentUris.parseId(uri);String complexSelection=StudentWords.ID+"="+id;if(selection!=null&&!"".equals(selection)){complexSelection+=" and "+selection;}return complexSelection;}@Overridepublic int delete(Uri uri,String selection,String[]selectionArgs) {SQLiteDatabase db=dbHelper.getReadableDatabase();int num=0;switch(matcher.match(uri)){case STUDENT_WITH_ID:String complexSelection=getComplexSelection(uri,selection);num=db.delete(StudentWords.TABLE_NAME, complexSelection, selectionArgs);break;case STUDENT:num=db.delete(StudentWords.TABLE_NAME,selection,selectionArgs);break;default:throw new IllegalArgumentException("Unknown Uri:"+uri);}//通知數(shù)據(jù)已經(jīng)改變getContext().getContentResolver().notifyChange(uri, null);return num;}@Overridepublic Uri insert(Uri uri, ContentValues values) {SQLiteDatabase db=dbHelper.getReadableDatabase();switch(matcher.match(uri)){case STUDENT_WITH_ID:case STUDENT:long rowId=db.insert(StudentWords.TABLE_NAME, StudentWords.ID,values);if(rowId>0){Uri studentUri=ContentUris.withAppendedId(uri, rowId);//假設(shè)設(shè)置了觀察者的話。要通知全部觀察者getContext().getContentResolver().notifyChange(studentUri, null);return studentUri;}break;default:throw new IllegalArgumentException("Unknow Uri:"+uri); }return null;}/*** 注意當(dāng)中的projection事實(shí)上是columns,即列名數(shù)組*/@Overridepublic Cursor query(Uri uri, String[] projection, String selection,String[] selectionArgs, String sortOrder) {SQLiteDatabase db=dbHelper.getReadableDatabase();switch(matcher.match(uri)){//這事實(shí)上是包括id信息的情況case STUDENT_WITH_ID:String complexSelection=getComplexSelection(uri,selection);return db.query(StudentWords.TABLE_NAME,projection,complexSelection,selectionArgs,null,null,sortOrder);//這是不帶數(shù)字的情況。可是也未必就是好多個(gè)。一個(gè)也能夠。case STUDENT: return db.query(StudentWords.TABLE_NAME,projection,selection,selectionArgs,null,null,sortOrder);default:throw new IllegalArgumentException("Unknow Uri"+uri);}}@Overridepublic int update(Uri uri, ContentValues values, String selection,String[] selectionArgs) {SQLiteDatabase db=dbHelper.getWritableDatabase();int num=0;switch(matcher.match(uri)){case STUDENT_WITH_ID:String complexSelection=getComplexSelection(uri,selection);num=db.update(StudentWords.TABLE_NAME, values, complexSelection, selectionArgs); break;case STUDENT:num=db.update(StudentWords.TABLE_NAME, values, selection,selectionArgs);break;default:throw new IllegalArgumentException("Unknow Uri:"+uri);}getContext().getContentResolver().notifyChange(uri,null);return num; }} 當(dāng)然,要記得在Manifest文件里增加ContentProvider的聲明:

<provider android:name="com.android.student.provider.StudentProvider"android:authorities="com.android.student.provider"android:exported="true"/>以下是對(duì)ContentResolver的樣例,首先項(xiàng)目中的文件結(jié)構(gòu)例如以下:



然后是layout文件 :

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="fill_parent"android:layout_height="wrap_content" > <LinearLayoutxmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:paddingBottom="@dimen/activity_vertical_margin"android:paddingLeft="@dimen/activity_horizontal_margin"android:paddingRight="@dimen/activity_horizontal_margin"android:paddingTop="@dimen/activity_vertical_margin"android:orientation="vertical"tools:context=".MainActivity" ><TextView android:id="@+id/tv"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="下面為輸入?yún)?shù):"/><EditTextandroid:id="@+id/nameET"android:layout_width="fill_parent"android:layout_height="wrap_content"android:hint="Name"/><EditTextandroid:id="@+id/scoreET"android:layout_width="fill_parent"android:layout_height="wrap_content"android:hint="Score"/><EditTextandroid:id="@+id/addrET"android:layout_width="fill_parent"android:layout_height="wrap_content"android:hint="Address"/><Buttonandroid:id="@+id/insertButton"android:layout_width="fill_parent"android:layout_height="wrap_content"android:text="Insert"/><TextView android:id="@+id/searchTv"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="下面為查詢參數(shù):"/> <EditText android:id="@+id/inputNameET"android:layout_width="fill_parent"android:layout_height="wrap_content"android:hint="Input name"/><Button android:id="@+id/searchButton"android:layout_width="fill_parent"android:layout_height="wrap_content"android:text="Search"/><TextView android:id="@+id/searchResultTv"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="下面為Update參數(shù)"/> <EditText android:id="@+id/inputIdET"android:layout_width="fill_parent"android:layout_height="wrap_content"android:hint="Input id"/><Button android:id="@+id/updateButton"android:layout_width="fill_parent"android:layout_height="wrap_content"android:text="Update"/><TextView android:id="@+id/searchResultTv"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="下面為刪除參數(shù)"/> <EditText android:id="@+id/inputIdForDeleteET"android:layout_width="fill_parent"android:layout_height="wrap_content"android:hint="Input id"/><Button android:id="@+id/deleteButton"android:layout_width="fill_parent"android:layout_height="wrap_content"android:text="Delete"/></LinearLayout></ScrollView> 項(xiàng)目中也有StudentWords這個(gè)類,由于與上面的StudentWords全然同樣,故此處不再列出,MainActivity的代碼例如以下:

package com.android.student.studentcontentresolver;import java.util.ArrayList; import java.util.List; import java.util.Map;import com.android.student.utils.StudentWords;import android.net.Uri; import android.os.Bundle; import android.app.Activity; import android.content.ContentResolver; import android.content.ContentUris; import android.content.ContentValues; import android.database.Cursor; import android.view.Menu; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; import android.view.View; public class MainActivity extends Activity implements View.OnClickListener{ContentResolver contentResolver;private EditText nameET,scoreET,addressET;private Button insertButton;private EditText inputNameET;private Button searchButton;private EditText inputIdForUpdateET,inputIdForDeleteET;private Button updateButton,deleteButton;private void initView(){nameET=(EditText)findViewById(R.id.nameET);scoreET=(EditText)findViewById(R.id.scoreET);addressET=(EditText)findViewById(R.id.addrET);insertButton=(Button)findViewById(R.id.insertButton);inputNameET=(EditText)findViewById(R.id.inputNameET);searchButton=(Button)findViewById(R.id.searchButton);inputIdForUpdateET=(EditText)findViewById(R.id.inputIdET);inputIdForDeleteET=(EditText)findViewById(R.id.inputIdForDeleteET);updateButton=(Button)findViewById(R.id.updateButton);deleteButton=(Button)findViewById(R.id.deleteButton);insertButton.setOnClickListener(this);searchButton.setOnClickListener(this);updateButton.setOnClickListener(this);deleteButton.setOnClickListener(this);}@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);contentResolver=getContentResolver();initView();}@Overridepublic void onClick(View view){switch(view.getId()){case R.id.insertButton:insert();break;case R.id.searchButton:query();break;case R.id.updateButton:update();break;case R.id.deleteButton:delete();break;default:break;}}private void insert(){String name=nameET.getText().toString();String score=scoreET.getText().toString();String addr=addressET.getText().toString();ContentValues values=new ContentValues();values.put(StudentWords.NAME, name);values.put(StudentWords.SCORE, new Integer(score));values.put(StudentWords.ADDR, addr);//contentResolver.insert(StudentWords.SINGLE_STUDENT_URI, values);//一個(gè)是多個(gè)的特例,所以此處用MANY_STUDENTS_URI就可以。

contentResolver.insert(StudentWords.STUDENT_URI, values); Toast.makeText(getBaseContext(), "加入學(xué)生信息成功", Toast.LENGTH_SHORT).show(); } private void query() { String name=inputNameET.getText().toString(); //Cursor cursor=contentResolver.query(uri, projection, selection, selectionArgs, sortOrder) Cursor cursor=contentResolver.query(StudentWords.STUDENT_URI, null, "name like ?

or address like ?", new String[]{"%"+name+"%","%"+name+"%"}, null); Toast.makeText(getBaseContext(), getResult(cursor), Toast.LENGTH_LONG).show(); } private void update() { //Uri updateUri=StudentWords.SINGLE_STUDENT_URI //更新id值為id的記錄 Integer id=new Integer(inputIdForUpdateET.getText().toString()); Uri updateUri=ContentUris.withAppendedId(StudentWords.STUDENT_WITH_ID_URI,id); ContentValues values=new ContentValues(); values.put(StudentWords.NAME,"VictorWang"); contentResolver.update(updateUri, values, null, null); } private void delete() { //刪除id值為id的記錄 Integer id=new Integer(inputIdForDeleteET.getText().toString()); Uri deleteUri=ContentUris.withAppendedId(StudentWords.STUDENT_WITH_ID_URI, id); contentResolver.delete(deleteUri, null, null); } private List<String>convertCursor2List(Cursor cursor) { List<String>result=new ArrayList<String>(); while(cursor.moveToNext()) { result.add(cursor.getString(1)+" "); result.add(cursor.getString(2)+" "); result.add(cursor.getString(3)+" "); } return result; } private String getResult(Cursor cursor) { StringBuilder sb=new StringBuilder(); while(cursor.moveToNext()) { sb.append(cursor.getString(1)+" "); sb.append(cursor.getString(2)+" "); sb.append(cursor.getString(3)+"\n"); } return sb.toString(); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } }

執(zhí)行結(jié)果例如以下:




今天先寫到這里,聯(lián)系人和ContentObserver的樣例后面再加入。

? ? ?

總結(jié)

以上是生活随笔為你收集整理的Android中的跨进程通信方法实例及特点分析(二):ContentProvider的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。