Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android內容提供者——Content Providers(一)

Android內容提供者——Content Providers(一)

編輯:關於Android編程

Content Providers是Android四大組件之一,扮演者非常重要的角色,看下官方文檔對它的解釋:

Content providers manage access to a structured set of data. They encapsulate the data, and provide mechanisms for defining data security. Content providers are the standard interface that connects data in one process with code running in another process.

可以看到Content providers負責管理結構化數據的訪問,Content providers封裝數據並且提供一套定義數據安全的機制。Content providers是一套在不同進程間進行數據訪問的接口。
Content providers為數據跨進程訪問提供了一套安全的訪問機制,對數據組織和安全訪問提供了可靠的保證。

另外來看看官方文檔是如何解釋Content Providers的使用的:
When you want to access data in a content provider, you use theContentResolver object in your application's Context to communicate with the provider as a client. The ContentResolverobject communicates with the provider object, an instance of a class that implements ContentProvider. The provider object receives data requests from clients, performs the requested action, and returns the results.

意思是當你想要通過Content Providers訪問數據時,在應用程序的上下文(Context)中使用ContentResolver對象最為客戶端(client)與provider進行交互。ContentResolver對象通過實現抽象類ContentProvider的一個實例來訪問provider。Provider對象從客戶端(client)接收數據請求,執行請求操作並且返回請求結果。

Android通過Content Provider來管理數據諸如音頻、視頻、圖片和通訊錄等。還可以通過ContentProvider來訪問SQLite數據庫等,下面來看看Content Provider的基本使用。

在此之前,官方文檔中給出了一些是否需要需用Content Providers的建議:
Decide if you need a content provider. You need to build a content provider if you want to provide one or more of the following features:
You want to offer complex data or files to other applications.
You want to allow users to copy complex data from your app into other apps.
You want to provide custom search suggestions using the search framework.

在以下情況下你需要使用Content Providers:
1.你想為其他應用程序提供復雜數據或文件;
2.你想允許用戶從你的應用程序中拷貝復雜數據到其他的應用中
3.你想使用搜索框架提供自定義的查詢建議功能

Content Provider通過URI(統一資源定位符)來訪問數據,URI可以理解為訪問數據的唯一地址,URI由authority和數據地址構成,關於authority可以理解成網站地址中的主機地址,而數據地址可以理解成某一個頁面的子地址,二者共同構成了一個完整的訪問地址,關於authority的命名,官方文檔中有這麼一句話 If your Android package name iscom.example.<appname>, you should give your provider the authority com.example.<appname>.provider.可見對於authority的命名還是有一定的規范性的。
關於URI的格式:content://<authority>/<path>/<id>,path就是數據路徑,比如說一張表,而id就是這張表中主鍵為id的一行,也可以理解成一個實體對象。

看下構建Content Provider和使用URI的代碼:
[java] 
publicclassExampleProviderextendsContentProvider{... 
    // Creates a UriMatcher object. 
    privatestaticfinalUriMatcher sUriMatcher;... 
    /*
     * The calls to addURI() go here, for all of the content URI patterns that the provider
     * should recognize. For this snippet, only the calls for table 3 are shown.
     */... 
    /*
     * Sets the integer value for multiple rows in table 3 to 1. Notice that no wildcard is used
     * in the path
     */ 
    sUriMatcher.addURI("com.example.app.provider","table3",1); 
 
    /*
     * Sets the code for a single row to 2. In this case, the "#" wildcard is
     * used. "content://com.example.app.provider/table3/3" matches, but
     * "content://com.example.app.provider/table3 doesn't.
   * 這裡說明了兩種通配符的作用
   * *: Matches a string of any valid characters of any length.
   * #: Matches a string of numeric characters of any length.
 
     */ 
    sUriMatcher.addURI("com.example.app.provider","table3/#",2);... 
    // Implements ContentProvider.query() 
    publicCursor query( 
        Uri uri, 
        String[] projection, 
        String selection, 
        String[] selectionArgs, 
        String sortOrder){... 
        /*
         * Choose the table to query and a sort order based on the code returned for the incoming
         * URI. Here, too, only the statements for table 3 are shown.
         */ 
        switch(sUriMatcher.match(uri)){ 
 
 
            // If the incoming URI was for all of table3 
            case1: 
 
                if(TextUtils.isEmpty(sortOrder)) sortOrder ="_ID ASC"; 
                break; 
 
            // If the incoming URI was for a single row 
            case2: 
 
                /*
                 * Because this URI was for a single row, the _ID value part is
                 * present. Get the last path segment from the URI; this is the _ID value.
                 * Then, append the value to the WHERE clause for the query
                 */ 
                selection = selection +"_ID = " uri.getLastPathSegment(); 
                break; 
 
            default: 
            ... 
                // If the URI is not recognized, you should do some error handling here. 
        } 
        // call the code to actually do the query } 

實現抽象類ContentProvider後,有幾個需要實現的方法:
query()
Retrieve data from your provider. Use the arguments to select the table to query, the rows and columns to return, and the sort order of the result. Return the data as a Cursor object.
insert()
Insert a new row into your provider. Use the arguments to select the destination table and to get the column values to use. Return a content URI for the newly-inserted row.
update()
Update existing rows in your provider. Use the arguments to select the table and rows to update and to get the updated column values. Return the number of rows updated.
delete()
Delete rows from your provider. Use the arguments to select the table and the rows to delete. Return the number of rows deleted.
getType()
Return the MIME type corresponding to a content URI. This method is described in more detail in the sectionImplementing Content Provider MIME Types.
onCreate()
Initialize your provider. The Android system calls this method immediately after it creates your provider. Notice that your provider is not created until a ContentResolver object tries to access it.
舉一個例子,如果使用SQLite作為Content Provider的數據源,下面這段代碼片段建立了SQLiteOpenHelper的子類MainDatabaseHelper,並且生成了表main
[java]
// A string that defines the SQL statement for creating a tableprivatestaticfinalString SQL_CREATE_MAIN ="CREATE TABLE "+ 
    "main "+                       // Table's name 
    "("+                           // The columns in the table 
    " _ID INTEGER PRIMARY KEY, "+ 
    " WORD TEXT" 
    " FREQUENCY INTEGER "+ 
    " LOCALE TEXT )";.../**
 * Helper class that actually creates and manages the provider's underlying data repository.
 */protectedstaticfinalclassMainDatabaseHelperextendsSQLiteOpenHelper{ 
 
    /*
     * Instantiates an open helper for the provider's SQLite data repository
     * Do not do database creation and upgrade here.
     */ 
    MainDatabaseHelper(Context context){ 
        super(context, DBNAME,null,1); 
    } 
 
    /*
     * Creates the data repository. This is called when the provider attempts to open the
     * repository and SQLite reports that it doesn't exist.
     */ 
    publicvoid onCreate(SQLiteDatabase db){ 
 
        // Creates the main table 
        db.execSQL(SQL_CREATE_MAIN); 
    } } 

然後定義ContentProvider來操作數據庫,這樣,就建立了一套在數據源(SQLite)和客戶端(client)之間的接口
[java] 
publicclassExampleProviderextendsContentProvider 
 
    /*
     * Defines a handle to the database helper object. The MainDatabaseHelper class is defined
     * in a following snippet.
     */ 
    privateMainDatabaseHelper mOpenHelper; 
 
    // Defines the database name 
    privatestaticfinalString DBNAME ="mydb"; 
 
    // Holds the database object 
    privateSQLiteDatabase db; 
 
    publicboolean onCreate(){ 
 
        /*
         * Creates a new helper object. This method always returns quickly.
         * Notice that the database itself isn't created or opened
         * until SQLiteOpenHelper.getWritableDatabase is called
         */ 
        mOpenHelper =newSQLiteOpenHelper( 
            getContext(),        // the application context 
            DBNAME,              // the name of the database) 
            null,                // uses the default SQLite cursor 
            1                    // the version number 
        ); 
 
        returntrue; 
    } 
 
    ... 
 
    // Implements the provider's insert method 
    publicCursor insert(Uri uri,ContentValues values){ 
        // Insert code here to determine which table to open, handle error-checking, and so forth 
        /*
         * Gets a writeable database. This will trigger its creation if it doesn't already exist.
         *
         */ 
        db = mOpenHelper.getWritableDatabase(); 
    } } 

簡單的總結一些Content Providers:www.2cto.com
1.Content Providers是Android系統中四大組件之一,提供一套在客戶端(client)和數據源(data source)之間的訪問接口
2.Content Providers可以提供跨進程訪問數據的功能,能暴露本地數據給其他應用訪問
3.實現Content Providers只需要繼承抽象類ContentProvider並實現必要的抽象方法即可,訪問ContentProvider則根據URI來訪問


作者:tangren03
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved