<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>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                **ContentResolver.java::openAssetFileDescriptor** ~~~ public final AssetFileDescriptoropenAssetFileDescriptor(Uri uri, String mode) throws FileNotFoundException { //openAssetFileDescriptor是一個通用函數,它支持三種scheme類型的URI。見 //下文的解釋 Stringscheme = uri.getScheme(); if(SCHEME_ANDROID_RESOURCE.equals(scheme)) { if(!"r".equals(mode)) { throw new FileNotFoundException("Can't write resources: " +uri); } //創建資源文件輸入流 OpenResourceIdResult r = getResourceId(uri); try{ return r.r.openRawResourceFd(r.id); } ...... }else if (SCHEME_FILE.equals(scheme)) { //創建普通文件輸入流 ParcelFileDescriptor pfd = ParcelFileDescriptor.open( new File(uri.getPath()), modeToMode(uri, mode)); return new AssetFileDescriptor(pfd, 0, -1); }else { if ("r".equals(mode)) { //我們重點分析這個函數,用于讀取目標ContentProvider的數據 return openTypedAssetFileDescriptor(uri, "*/*", null); } ......//其他模式的支持,請讀者學完本章后自行研究這部分內容 } } ~~~ 如以上代碼所述,openAssetFileDescriptor是一個通用函數,它支持三種sheme類型的URI。 - SCHEME_ANDROID_RESOURCE:字符串表達為“android.resource”。通過它可以讀取APK包(其實就是一個壓縮文件)中封裝的資源。假設在應用進程的res/raw目錄下存放一個test.ogg文件,最終生成的資源id由R.raw.tet來表達,那么如果應用進程想要讀取這個資源,創建的URI就是“android.resource://com.package.name/R.raw.test”。 讀者不妨試一試。 - SCHEME_FILE:字符串表達為“file”。通過它可以讀取普通文件。 - 除上述兩種scheme之外的URI:這種資源背后到底對應的是什么數據需要由目標CP來解釋。 接下來分析在第三種sheme類型下調用的openTypedAssetFileDescriptor函數。 1. openTypedAssetFileDescriptor函數分析 **ContentResolver.java::openTypedAssetFileDescriptor** ~~~ public final AssetFileDescriptoropenTypedAssetFileDescriptor(Uri uri, String mimeType, Bundle opts) throws FileNotFoundException { //建立和目標CP進程交互的通道。讀者還記得此處provider的真實類型嗎? //其真實類型是ContentProviderProxy IContentProvider provider = acquireProvider(uri); try { //①調用遠端CP的openTypedAssetFile函數,返回值的 //類型是AssetFileDescriptor。此處傳遞參數的值為:mimeType="*/*" //opts=null AssetFileDescriptor fd = provider.openTypedAssetFile(uri, mimeType, opts); ...... //②創建一個ParcelFileDescriptor類型的變量 ParcelFileDescriptor pfd = new ParcelFileDescriptorInner( fd.getParcelFileDescriptor(), provider); provider = null; //③又創建一個AssetFileDescriptor類型的變量作為返回值 return new AssetFileDescriptor(pfd, fd.getStartOffset(), fd.getDeclaredLength()); }...... finally { if (provider != null) { releaseProvider(provider); } } } ~~~ 在以上代碼中,阻礙我們思維的依然是新冒出來的類。先應解決它們,然后再分析代碼中的關鍵調用。 2. FileDescriptor家族介紹 本節涉及的類家族圖譜如圖7-7所示。 :-: ![](http://img.blog.csdn.net/20150803130950821?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center) 圖7-7 FileDescriptor家族圖譜 圖7-7中的內容比較簡單,只需稍作介紹。 - FileDescriptor類是Java的標準類,它是對文件描述符的封裝。進程打開的每一個文件都有一個對應的文件描述符。在Native語言開發中,它用一個int型變量來表示。 - 文件描述符作為進程的本地資源,如想越過進程邊界將其傳遞給其他進程,則需借助進程間共享技術。在Android平臺上,設計者封裝了一個ParcelFileDescriptor類。此類實現了Parcel接口,自然就支持了序列化和反序列化的功能。從圖7-7可知,一個ParcelFileDescriptor通過mFileDescritpor指向一個文件描述符。 - AssetFileDescriptor也實現了Parcel接口,其內部通過mFd成員變量指向一個ParcelFileDescriptor對象。從這里可看出,AssetFileDescritpor是對ParcelFileDescriptor類的進一步封裝和擴展。實際上,根據SDK文檔中對AssetFileDescritpor的描述可知,其作用在于從AssetManager(后續分析資源管理的時候會介紹它)中讀取指定的資源數據。 * * * * * **提示**:簡單向讀者介紹一下與AssetFileDescriptor相關的知識。它用于讀取APK包中指定的資源數據。以前面提到的test.ogg為例,如果通過AssetFileDescriptor讀取它,那么其mFd成員則指向一個ParcelFileDescriptor對象。且不管這個對象是否跨越了進程邊界,它畢竟代表一個文件。假設這個文件是一個APK包,AssetFileDescriptor的mStartOffset變量用于指明test.ogg在這個APK包中的起始位置,比如100字節。而mLength用于指明test.ogg的長度,假設是1000字節。通過上面的介紹可知,該APK文件從100字節到1100字節這一段空間中存儲的就是test.ogg的數據。這樣,AssetFileDescriptor就能將test.ogg數據從APK包中讀取出來了。 * * * * * 下面來看ContentProvider的openTypedAssetFile函數。
                  <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>

                              哎呀哎呀视频在线观看