<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、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                1. 客戶端query關鍵點 按以前的分析習慣,碰到Binder調用時會馬上轉入服務端(即Bn端)去分析,但是這個思路在query函數中行不通。為什么?來看IContentProvider Bp端的query函數,它定義在ContentProviderProxy中,代碼如下: **ContentProviderNative.java::ContentProviderProxy.query** ~~~ public Cursor query(Uri url, String[] projection,String selection, String[] selectionArgs, String sortOrder) throws RemoteException { //①構造一個BulkCursorToCursorAdaptor對象 BulkCursorToCursorAdaptor adaptor = new BulkCursorToCursorAdaptor(); Parceldata = Parcel.obtain(); Parcel reply = Parcel.obtain(); try { data.writeInterfaceToken(IContentProvider.descriptor); ......//將參數打包到data請求包中 //②adaptor.getObserver()返回一個IContentObserver類型的對象,把它 //也打包到data請求包中。ContentObserver相關的知識留到第8章再分析 data.writeStrongBinder(adaptor.getObserver().asBinder()); //發送請求給遠端的Bn端 mRemote.transact(IContentProvider.QUERY_TRANSACTION, data, reply, 0); DatabaseUtils.readExceptionFromParcel(reply); //③從回復包中得到一個IBulkCursor類型的對象 IBulkCursor bulkCursor = BulkCursorNative.asInterface(reply.readStrongBinder()); if(bulkCursor != null) { int rowCount = reply.readInt(); int idColumnPosition = reply.readInt(); boolean wantsAllOnMoveCalls = reply.readInt() != 0; //④調用adaptor的initialize函數 adaptor.initialize(bulkCursor, rowCount, idColumnPosition, wantsAllOnMoveCalls); } ...... return adaptor; } ...... finally { data.recycle(); reply.recycle(); } } ~~~ 從以上代碼中可發現,ContentProviderProxy query函數中還大有文章,其中一共列出了4個關鍵點。最令人頭疼的是其中新出現的兩個類BulkCursorToCursorAdaptor和IBulkCursor。此處不必急于分析它們。 我們再到服務端去提取query函數的關鍵點。 2. 服務端query關鍵點 根據第2章對Binder的介紹,客戶端發來的請求先在Bn端的onTransact中得到處理,代碼如下: **ContentProviderNative.java::onTransact** ~~~ public boolean onTransact(int code, Parcel data, Parcelreply, int flags) throws RemoteException { try { switch (code) { case QUERY_TRANSACTION://處理query請求 { data.enforceInterface(IContentProvider.descriptor); Uri url = Uri.CREATOR.createFromParcel(data); ......//從請求包中提取參數 //⑤創建ContentObserver Binder通信的Bp端 IContentObserver observer = IContentObserver.Stub.asInterface( data.readStrongBinder()); //⑥調用MediaProvider實現的query函數。Cursor是一個接口類,那么變量 //cursor的真實類型是什么? Cursor cursor = query(url, projection, selection, selectionArgs, sortOrder); if(cursor != null) { //⑦創建一個CursorToBulkCursorAdaptor類型的對象 CursorToBulkCursorAdaptor adaptor = new CursorToBulkCursorAdaptor( cursor,observer, getProviderName()); final IBinder binder = adaptor.asBinder(); //⑧返回結果集所含記錄項的條數,這個函數看起來極不起眼,但卻非常為關鍵 final int count = adaptor.count(); //返回名為"_id"的列在結果集中的索引位置,該列由數據庫在創建表時自動添加 final int index = BulkCursorToCursorAdaptor.findRowIdColumnIndex( adaptor.getColumnNames()); //wantsAllOnMoveCalls一般為false,讀者閱讀完本章后再自行分析它 final boolean wantsAllOnMoveCalls = adaptor.getWantsAllOnMoveCalls(); reply.writeNoException(); //將binder的信息寫到reply回復包中 reply.writeStrongBinder(binder); reply.writeInt(count);//將結果集包含的記錄項行數返回給客戶端 reply.writeInt(index); reply.writeInt(wantsAllOnMoveCalls ? 1 : 0); }...... return true; }......//其他情況處理 ...... } ~~~ 和客戶端對應,服務端的query處理也比較復雜,其中的攔路虎仍是新出現的幾種數據類型。 在掃清這些攔路虎之前,應先把客戶端和服務端query調用的關鍵點總結一下。 3. 提取query關鍵點總結 我們提取query兩端的調用關鍵點,如圖7-5所示。 :-: ![](http://img.blog.csdn.net/20150803130916561?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center) 圖7-5 query調用關鍵點示意 再來總結一下前面提到的幾個攔路虎,它們分別是: - 客戶端創建的BulkCursorToCursorAdaptor、從服務端query后返回的IBulkCursor。 - 服務端創建的CursorToCursorAdaptor,以及從子類query函數返回的Cursor。 從名字上看,這幾個類都和Cursor有關,所以有必要先搞清MediaProviderquery返回的Cursor到底是什么。 * * * * * **注意**:圖7-5借用了UML的序列圖來展示query調用順序,其中ContentProvider框和MediaProviderer框代表同一個對象。另外,圖7-5中的調用函數編號并不完全對應代碼中的關鍵函數調用編號。 * * * * *
                  <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>

                              哎呀哎呀视频在线观看