Android 面試題ContentProvider使用+實例

      網友投稿 800 2022-05-29

      好問的人,只做了五分鐘的愚人;恥于發問的人,終身為愚人。

      Android提供了5種方式來讓用戶保存持久化應用程序數據。根據自己的需求來做選擇,比如數據是否是應用程序私有的,是否能被其他程序訪問,需要多少數據存儲空間等,分別是:

      使用SharedPreferences存儲數據

      文件存儲數據

      SQLite數據庫存儲數據

      「使用ContentProvider存儲數據」

      網絡存儲數據

      咱們今天就來學習一下ContentProvider。作為Android四大巨頭之一的他有點名不副實,因為在一般的開發過程中,使用的次數比較少。大部分應用的數據緩存用SharedPreferences就能搞定了。

      「ContentProvider(數據提供者)是應用程序之間共享數據的一種接口機制,是一種更為高級的數據共享方法。」

      ContentProvider可以指定需要共享的數據,而其他應用程序則可以在不知道數據來源、路徑的情況下,對共享數據進行增刪改查等操作。

      在Android系統中,許多Android系統內置的數據也是通過ContentProvider提供給用戶使用,例如通訊錄、音視頻文件和圖像文件等。

      一、什么是ContentProvider

      ContentProvider是Android的四大組件之一,以標準化的方式在Android 應用間共享數據。

      ContentProvider封裝的數據存儲以及增刪改查等,并且必須實現一個對外統一的接口(Uri)。

      二、什么是Uri

      Uri(通用資源標識符 Universal Resource Identifer),代表數據操作的地址,每一個ContentProvider都會有唯一的地址。

      ContentProvider使用的Uri語法結構如下:

      content://authority/data_path/id

      「content://」 是通用前綴,表示該Uri用于ContentProvider定位資源。

      「authority」 是授權者名稱,用來確定具體由哪一個ContentProvider提供資源。因此一般authority都由類的小寫全稱組成,以保證唯一性。

      「data_path」 是數據路徑,用來確定請求的是哪個數據集。

      「id」 是數據編號,用來請求單條數據。如果是多條這個字段忽略。

      樣例:

      content://com.scc.userprovider/user多條

      content://com.scc.userprovider/user/10單條

      三、什么是ContentResolver

      ContentResolver是數據調用者,ContentProvider將數據發布出來,通過ContentResolver對象結合Uri進行調用。

      一般來說ContentProvider是單例模式,多個應用可通過ContentResolver調用ContentProvider的增刪改查操作數據,ContentResolver調用的數據操作會讓同一個ContentProvider處理。

      四、創建ContentProvider

      1、創建一個類讓其繼承ContentProvider,并重載6個函數

      需要實現的主要方法是:

      「insert()」、「delete()」、「update()」、「query()」:用于對數據集的增刪改查操作。

      「onCreate()」:一般用來初始化底層數據集和建立數據連接等工作

      「getType()」:用來返回指定Uri的MIME數據類型,

      若Uri是單條數據,則返回的MIME數據類型以vnd.Android.cursor.item開頭;

      若Uri是多條數據,則返回的MIME數據類型以vnd.android.cursor.dir/開頭。

      數據訪問方法「如insert(Uri,ContentValues)和update(Uri,ContentValues,Bundle)」 可以同時從多個線程調用,并且必須是線程安全的。其他方法「如onCreate()」 僅從應用程序主線程調用,并且必須避免執行冗長的操作。請參閱其預期線程行為的方法描述。

      2、聲明Uri規則,實現UriMatcher

      咱先來看看UriMatcher是干嘛的,UriMatcher本質上是一個文本過濾器,有助于解析Uri,用在ContentProvider中幫助我們過濾,分辨出查詢者想要查詢哪個數據表。

      UriMatcher的構造函數中,UriMatcher.NO_MATCH是Uri無匹配時的返回代碼,值為-1。addUri()方法用來添加新的匹配項,語法為:

      public?void?addUri(String?authority,?String?path,?int?code)

      authority表示匹配的授權者名稱;

      path表示數據路徑;

      code表示返回代碼。

      下面咱搞個實例:

      //這里的名稱必須與AndroidManifest.xml中android:authorities保持一致

      public?static?final?String?AUTHORITY?=?"com.scc.userprovider";

      //數據路徑

      public?static?final?String?PATH_USERS?=?"user";

      //訪問ContentProvider的URL

      public?static?final?Uri?CONTENT_URI?=?Uri.parse("content://"?+?AUTHORITY?+?"/"?+?PATH_USERS);

      Android 面試題之ContentProvider使用+實例

      //返回代碼

      public?static?final?int?USER_INFO?=?1;

      //創建UriMatcher對象

      private?static?UriMatcher?uriMatcher;

      //創建靜態代碼塊

      static?{

      //實例化UriMatcher對象

      uriMatcher?=?new?UriMatcher(UriMatcher.NO_MATCH);

      //參數1:authority;參數2:路徑;參數3:自定義代碼

      uriMatcher.addURI(UserInfoContent.AUTHORITY,?UserInfoContent.PATH_USERS,?USER_INFO);

      }

      3、注冊ContentProvider

      在AndroidManifest.xml文件中的 application節點下使用標簽注冊。樣例:

      android:name=".UserProvider"

      android:exported="true"/>

      五、使用ContentProvider

      1、通過insert()方法添加單條數據

      ContentValues?cv?=?new?ContentValues();

      cv.put(UserInfoContent._ID,?bean.get_id());

      cv.put(UserInfoContent.USER_NAME,?bean.getName());

      cv.put(UserInfoContent.USER_AGE,?bean.getAge());

      cv.put(UserInfoContent.USER_UPDATE_TIME,?bean.getUpdate_time());

      Uri?uri?=?getContentResolver().insert(UserInfoContent.CONTENT_URI,?cv);

      Log.e(getClass().getName(),?"insert:"?+?uri);

      通過bulkInsert()方法添加多條數據

      ContentValues[]?arrayValues?=?new?ContentValues[10];

      //實例化每一個ContentValues...

      int?count?=?getContentResolver().bulkInsert(UserInfoContent.CONTENT_URI,?arrayValues);

      2、指定ID刪除單條數據

      int?delete?=?getContentResolver().delete(UserInfoContent.CONTENT_URI,?"_id=12",?null);

      Log.e(getClass().getName(),?"delete(失敗返回-1):"?+?delete);

      通過selection語句刪除多條數據

      String?selection?=?UserInfoContent._ID?+?">12";

      int?result?=?getContentResolver().delete(UserInfoContent.CONTENT_URI,?selection,?null);

      3、修改數據

      UserInfoBean?bean?=?new?UserInfoBean("蚩尤",?32,?"12:00");

      ContentValues?cv?=?new?ContentValues();

      cv.put(UserInfoContent.USER_NAME,?bean.getName());

      cv.put(UserInfoContent.USER_AGE,?bean.getAge());

      cv.put(UserInfoContent.USER_UPDATE_TIME,?bean.getUpdate_time());

      getContentResolver().update(UserInfoContent.CONTENT_URI,?cv,?"_id=18",?null);

      4、查詢數據

      Cursor?cursor?=?getContentResolver().query(UserInfoContent.CONTENT_URI,?null,?selection,?null,?null);

      //循環取出游標指向的每條用戶記錄

      while?(cursor.moveToNext())?{

      UserInfoBean?user?=?new?UserInfoBean();

      user.name?=?cursor.getString(cursor.getColumnIndex(UserInfoContent.USER_NAME));

      user.age?=?cursor.getInt(cursor.getColumnIndex(UserInfoContent.USER_AGE));

      user._id?=?cursor.getString(cursor.getColumnIndex(UserInfoContent._ID));

      user.update_time?=?cursor.getString(cursor.getColumnIndex(UserInfoContent.USER_UPDATE_TIME));

      userList.add(user);?//添加到用戶信息列表

      }

      cursor.close();?//關閉數據庫游標

      Log.e(getClass().getName(),?"Query用戶:"?+?String.format("當前共找到%d個用戶",?userList.size()));

      六、跨應用使用ContentProvider

      跨應用和本應用使用ContentProvider一樣的方法,這邊就不做復制了。

      例五的Uri是拼接字段,拼接后的結果 :

      「content://com.scc.userprovider/user。」

      跨平臺使用getContentResolver().方法 的第一個參數:

      「Uri uricontent = Uri.parse("content://com.scc.userprovider/user");」

      1、新增數據+查找數據

      2、修改數據+刪除數據

      七、java.lang.SecurityException: Permission Denial: opening provider com.scc.cp.UserProvider from ProcessRecord

      解決方案:

      在AndroidManifest.xml文件中的 application節點下使用標簽注冊時android:exported="false"時,不允許其他應用調用。

      所以其他和應用使用ContentProvider會崩潰報錯。將exported改為:android:exported="true"即可。

      源碼:ContentProviderDemo.zip

      Android

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:今天聊聊分布式鎖 No.86
      下一篇:Java 每半年就會更新一次新特性,再不掌握就要落伍了:Java13 的新特性
      相關文章
      亚洲国产日韩在线成人蜜芽| 亚洲校园春色小说| 亚洲五月六月丁香激情| 亚洲av永久中文无码精品 | 亚洲中文字幕精品久久| 亚洲色偷偷av男人的天堂| 亚洲国产精品无码久久SM| 亚洲免费观看视频| 久久乐国产精品亚洲综合| 亚洲国产午夜中文字幕精品黄网站| 亚洲AV日韩AV永久无码色欲 | 亚洲一区无码中文字幕| 亚洲婷婷五月综合狠狠爱| 亚洲熟妇中文字幕五十中出| 国产亚洲精品成人AA片新蒲金 | 亚洲Av高清一区二区三区| 国产精品亚洲精品青青青| 亚洲一区免费视频| 成人亚洲国产va天堂| 亚洲熟妇无码AV| 亚洲人AV在线无码影院观看| 亚洲高清乱码午夜电影网| 国产精品亚洲AV三区| 亚洲国产精品一区二区九九| 亚洲综合色在线观看亚洲| 国产精品亚洲片在线观看不卡 | 无码久久精品国产亚洲Av影片 | 亚洲国产中文字幕在线观看| 久久久无码精品亚洲日韩软件| 亚洲精品~无码抽插| 水蜜桃亚洲一二三四在线| 亚洲精品自在线拍| 亚洲中文字幕无码一去台湾| 亚洲av永久中文无码精品综合 | 亚洲男人的天堂在线va拉文| 亚洲精品成人无限看| 亚洲视频一区网站| 亚洲最大中文字幕无码网站| 精品久久久久亚洲| 亚洲精品无码久久毛片| 亚洲精品~无码抽插|