<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                **ContentProvider.java::openTypedAssetFile** ~~~ public AssetFileDescriptor openTypedAssetFile(Uriuri, String mimeTypeFilter, Bundle opts) throws FileNotFoundException { //本例滿足下面的if條件 if("*/*".equals(mimeTypeFilter)) return openAssetFile(uri, "r");//此函數的代碼見下文 StringbaseType = getType(uri); if(baseType != null && ClipDescription.compareMimeTypes(baseType, mimeTypeFilter)) { return openAssetFile(uri, "r"); } throw newFileNotFoundException("Can't open " + uri + " as type " + mimeTypeFilter); } ~~~ **ContentProvider.java::openAssetFile** ~~~ public AssetFileDescriptor openAssetFile(Uri uri,String mode) throws FileNotFoundException { //openFile由子類實現。這里還以MediaProvider為例 ParcelFileDescriptor fd = openFile(uri, mode); //根據openFile返回的fd得到一個AssetFileDescriptor對象 returnfd != null ? new AssetFileDescriptor(fd, 0, -1) : null; } ~~~ 下面分析MediaProvider實現的openFile函數。 1. MediaProvideropenFile分析 **MediaProvider.java::openFile** ~~~ public ParcelFileDescriptor openFile(Uri uri,String mode) throws FileNotFoundException { ParcelFileDescriptor pfd = null; //假設URI符合下面的if條件,即客戶端想讀取的是某音樂文件所屬專輯(Album)的信息 if(URI_MATCHER.match(uri) == AUDIO_ALBUMART_FILE_ID) { DatabaseHelper database = getDatabaseForUri(uri); ...... SQLiteDatabase db = database.getReadableDatabase(); ...... SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); //得到客戶端指定的代表該音樂文件的_id值 intsongid = Integer.parseInt(uri.getPathSegments().get(3)); qb.setTables("audio_meta"); qb.appendWhere("_id=" + songid); Cursor c = qb.query(db, new String [] { MediaStore.Audio.Media.DATA, MediaStore.Audio.Media.ALBUM_ID }, null, null, null, null, null); if(c.moveToFirst()) { String audiopath = c.getString(0); //獲取該音樂所屬的album_id值 int albumid = c.getInt(1); //注意,下面函數中調用的ALBUMART_URI將指向album_art表 Uri newUri = ContentUris.withAppendedId(ALBUMART_URI, albumid); try { //調用ContentProvider實現的openFileHelper函數。注意,pfd的 //類型是ParcelFileDescriptor pfd = openFileHelper(newUri, mode); } ...... } c.close(); return pfd; } ...... } ~~~ 在以上代碼中,MediaProvider將首先通過客戶端指定的音樂文件的_id去查詢它的專輯信息。此處給讀者一個示例,如圖7-8所示。 :-: ![](http://img.blog.csdn.net/20150803131007500?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center) 圖7-8 audio_meta內容展示 圖7-8中設置的SQL語句是select _id,album_id,_data from audio_meta,得到的結果集包含:第一列音樂文件的_id值,第二列返回音樂文件所屬專輯的album_id值,第三列返回對應歌曲的文件存儲路徑。 以上代碼在調用openFileHelper函數前構造了一個新的URI變量,根據代碼中的注釋可知,它將查詢album_art表,不妨再看一個示例,如圖7-9所示。 :-: ![](http://img.blog.csdn.net/20150803131023705?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center) 圖7-9 album_art內容展示 在圖7-9中,結果集的第一列為專輯藝術家的縮略圖文件存儲路徑,第二列為專輯藝術家album_id值。所以,要打開的文件就是對應album_id的縮略圖。再來看openFileHelper的代碼。 2. ContentProvideropenFileHelper函數分析 **ContentProvider.java::openFileHelper** ~~~ protected final ParcelFileDescriptoropenFileHelper(Uri uri, String mode) throws FileNotFoundException { //獲取縮略圖的文件路徑 Cursor c =query(uri, new String[]{"_data"}, null, null, null); int count= (c != null) ? c.getCount() : 0; if (count!= 1) { ......//一個album_id只能對應一個縮略圖文件 } c.moveToFirst(); int i =c.getColumnIndex("_data"); Stringpath = (i >= 0 ? c.getString(i) : null); c.close(); if (path == null) throw new FileNotFoundException("Column _data not found."); intmodeBits = ContentResolver.modeToMode(uri, mode); //創建ParcelFileDescriptor對象,內部會首先打開一個文件以得到 //一個FileDescriptor對象,然后再創建一個ParcelFileDescriptor對象,其實 //就是設置ParcelFileDescriptor中成員變量mFileDescriptor的值 returnParcelFileDescriptor.open(new File(path), modeBits); } ~~~ 至此,服務端已經打開指定文件了。那么,這個服務端的文件描述符是如何傳遞到客戶端的呢?我們單起一節來回答這個問題。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看