Android应用程序组件Content Provider在应用程序之间共享数据的原理分析(2)
16lz
2021-12-04
Step 7.ContentProviderProxy.query 这个函数定义在frameworks/base/core/java/android/content/ContentProviderNative.java文件中:
- finalclassContentProviderProxyimplementsIContentProvider{
- ......
- publicCursorquery(Uriurl,String[]projection,Stringselection,
- String[]selectionArgs,StringsortOrder)throwsRemoteException{
- //TODOmakeapoolofwindowssowecanreusememorydealers
- CursorWindowwindow=newCursorWindow(false/*windowwillbeusedremotely*/);
- BulkCursorToCursorAdaptoradaptor=newBulkCursorToCursorAdaptor();
- IBulkCursorbulkCursor=bulkQueryInternal(
- url,projection,selection,selectionArgs,sortOrder,
- adaptor.getObserver(),window,
- adaptor);
- if(bulkCursor==null){
- returnnull;
- }
- returnadaptor;
- }
- ......
- }
- publicclassCursorWindowextendsSQLiteClosableimplementsParcelable{
- ......
- privateintnWindow;
- ......
- publicCursorWindow(booleanlocalWindow){
- ......
- native_init(localWindow);
- }
- ......
- }
- staticJNINativeMethodsMethods[]=
- {
- /*name,signature,funcPtr*/
- {"native_init","(Z)V",(void*)native_init_empty},
- ......
- };
- staticvoidnative_init_empty(JNIEnv*env,jobjectobject,jbooleanlocalOnly)
- {
- ......
- CursorWindow*window;
- window=newCursorWindow(MAX_WINDOW_SIZE);
- ......
- if(!window->initBuffer(localOnly)){
- ......
- }
- ......
- SET_WINDOW(env,object,window);
- }
- #defineSET_WINDOW(env,object,window)(env->SetIntField(object,gWindowField,(int)window))
- staticjfieldIDgWindowField;
- ......
- intregister_android_database_CursorWindow(JNIEnv*env)
- {
- jclassclazz;
- clazz=env->FindClass("android/database/CursorWindow");
- ......
- gWindowField=env->GetFieldID(clazz,"nWindow","I");
- ......
- }
- boolCursorWindow::initBuffer(boollocalOnly)
- {
- ......
- sp<MemoryHeapBase>heap;
- heap=newMemoryHeapBase(mMaxSize,0,"CursorWindow");
- if(heap!=NULL){
- mMemory=newMemoryBase(heap,0,mMaxSize);
- if(mMemory!=NULL){
- mData=(uint8_t*)mMemory->pointer();
- if(mData){
- mHeader=(window_header_t*)mData;
- mSize=mMaxSize;
- ......
- }
- }
- ......
- }else{
- ......
- }
- }
这个函数有点长,不过它的逻辑很简单,就是把查询参数都写到一个Parcel对象data中去,然后通过下面Binder进程间通信机制把查询请求传给Content Provider处理:
- finalclassContentProviderProxyimplementsIContentProvider
- {
- ......
- privateIBulkCursorbulkQueryInternal(
- Uriurl,String[]projection,
- Stringselection,String[]selectionArgs,StringsortOrder,
- IContentObserverobserver,CursorWindowwindow,
- BulkCursorToCursorAdaptoradaptor)throwsRemoteException{
- Parceldata=Parcel.obtain();
- Parcelreply=Parcel.obtain();
- data.writeInterfaceToken(IContentProvider.descriptor);
- url.writeToParcel(data,0);
- intlength=0;
- if(projection!=null){
- length=projection.length;
- }
- data.writeInt(length);
- for(inti=0;i<length;i++){
- data.writeString(projection[i]);
- }
- data.writeString(selection);
- if(selectionArgs!=null){
- length=selectionArgs.length;
- }else{
- length=0;
- }
- data.writeInt(length);
- for(inti=0;i<length;i++){
- data.writeString(selectionArgs[i]);
- }
- data.writeString(sortOrder);
- data.writeStrongBinder(observer.asBinder());
- window.writeToParcel(data,0);
- //Flagforwhetherornotwewantthenumberofrowsinthe
- //cursorandthepositionofthe"_id"columnindex(or-1if
- //non-existent).Onlytobereturnedifbinder!=null.
- finalbooleanwantsCursorMetadata=(adaptor!=null);
- data.writeInt(wantsCursorMetadata?1:0);
- mRemote.transact(IContentProvider.QUERY_TRANSACTION,data,reply,0);
- DatabaseUtils.readExceptionFromParcel(reply);
- IBulkCursorbulkCursor=null;
- IBinderbulkCursorBinder=reply.readStrongBinder();
- if(bulkCursorBinder!=null){
- bulkCursor=BulkCursorNative.asInterface(bulkCursorBinder);
- if(wantsCursorMetadata){
- introwCount=reply.readInt();
- intidColumnPosition=reply.readInt();
- if(bulkCursor!=null){
- adaptor.set(bulkCursor,rowCount,idColumnPosition);
- }
- }
- }
- data.recycle();
- reply.recycle();
- returnbulkCursor;
- }
- ......
- }
- mRemote.transact(IContentProvider.QUERY_TRANSACTION,data,reply,0);
- adaptor.set(bulkCursor,rowCount,idColumnPosition);
- window.writeToParcel(data,0);
- //Flagforwhetherornotwewantthenumberofrowsinthe
- //cursorandthepositionofthe"_id"columnindex(or-1if
- //non-existent).Onlytobereturnedifbinder!=null.
- finalbooleanwantsCursorMetadata=(adaptor!=null);
- data.writeInt(wantsCursorMetadata?1:0);
更多相关文章
- 箭头函数的基础使用
- 类和 Json对象
- Python技巧匿名函数、回调函数和高阶函数
- Android的UI两大基石
- Android(安卓)Touch事件
- android 一直在最前面的浮动窗口效果
- Android(安卓)Json解析工具类
- android连接mysql数据库
- android 如何判断去电或来电已经接通