Android Content Provider Analysis of how data is shared between applications

Source: Internet
Author: User

This article refers to the principles of the Android application component content provider sharing data between applications http://blog.csdn.net/luoshengyang/article/details/6967204 and the Android System source code scenario analysis, author Luo Shenyang.

0, the general diagram flowchart is as follows:

Overall class Diagram:



1. Mainactivity process sends icontentprovider.query_transaction to Ariticlesprovider process



The first step

~/android/frameworks/base/core/java/android/content

----Contentprovidernative.java

Final class Contentproviderproxy implements Icontentprovider {... public Cursor query (Uri URL, string[] projection, Str ing selection,string[] selectionargs, String sortOrder) throws RemoteException {//todo make a pool of windows so we can re Use memory dealerscursorwindow window = new Cursorwindow (false/* window would be used remotely */); Bulkcursortocursoradaptor adaptor = new Bulkcursortocursoradaptor (); Ibulkcursor bulkcursor = bulkqueryinternal (URL, Projection, selection, Selectionargs, Sortorder,adaptor.getobserver (), window,adaptor); if (bulkcursor = = null) {return null;} return adaptor;} ......
(1) The Cursorwindow object is created.

(2) Create a class Bulkcursortocursoradaptor object.
(3) Call bulkqueryinternal.


~/android/frameworks/base/core/java/android/content

----Contentprovidernative.java

Final class Contentproviderproxy implements Icontentprovider{......private ibulkcursor bulkqueryinternal (Uri URL, String[] projection,string selection, string[] Selectionargs, String sortorder,icontentobserver Observer, Cursorwindow Window,bulkcursortocursoradaptor adaptor) throws RemoteException {Parcel data = Parcel.obtain (); Parcel reply = Parcel.obtain ();d Ata.writeinterfacetoken (icontentprovider.descriptor); url.writetoparcel (data, 0); int length = 0;if (projection! = null) {length = Projection.length;} Data.writeint (length); for (int i = 0; i < length; i++) {data.writestring (projection[i]);} Data.writestring (selection); if (Selectionargs! = null) {length = Selectionargs.length;} else {length = 0;} Data.writeint (length); for (int i = 0; i < length; i++) {data.writestring (selectionargs[i]);} Data.writestring (SortOrder);d Ata.writestrongbinder (Observer.asbinder ()); Window.writetoparcel (data, 0);//Flag for Whether or not we want the number of rows in the//cursor and the position of the "_ID "column index (or-1 if//non-existent). Only to is returned if binder! = null.final Boolean wantscursormetadata = (adaptor! = null);d Ata.writeint (Wantscursormetad Ata? 1:0); Mremote.transact (icontentprovider.query_transaction, data, reply, 0);D Atabaseutils.readexceptionfromparcel ( Reply); Ibulkcursor bulkcursor = Null;ibinder Bulkcursorbinder = Reply.readstrongbinder (); if (bulkcursorbinder! = null) { Bulkcursor = Bulkcursornative.asinterface (Bulkcursorbinder); if (wantscursormetadata) {int rowCount = Reply.readint (); int idcolumnposition = Reply.readint (); if (bulkcursor! = null) {Adaptor.set (Bulkcursor, RowCount, idcolumnposition);}}} Data.recycle (); reply.recycle (); return bulkcursor;} ......}
We are only interested in Window.writetoparcel (data, 0). For a detailed explanation please see the corresponding blog or book.

The second step, omit the binder_transaction transfer process, because the above has been analyzed it's over.


Step Three

~/android/frameworks/base/core/java/android/content

----Contentprovidernative.java

Abstract public class Contentprovidernative extends Binder implements Icontentprovider {... @Overridepublic boolean Ontransact (int code, PARCEL data, Parcel reply, int flags) throws RemoteException {try {switch (code) {Case Query_transacti On:{data.enforceinterface (Icontentprovider.descriptor); Uri URL = Uri.CREATOR.createFromParcel (data);//string[] Projectionint num = Data.readint ();  string[] projection = null;if (num > 0) {projection = new String[num];for (int i = 0; i < num; i++) {Projection[i] = Data.readstring ();}} String selection, string[] Selectionargs ... String selection = data.readstring (); num = Data.readint (); string[] Selectionargs = null;if (num > 0) {Selectionargs = new String[num];for (int i = 0; i < num; i++) {Selection Args[i] = data.readstring ();}} String SortOrder = data.readstring (); Icontentobserver observer = IContentObserver.Stub.asInterface ( Data.readstrongbinder ()); Cursorwindow window = CursorWindow.CREATOR.createFromParcel (data);//Flag for whether callEr wants the number of//rows in the cursor and the position of the//"_id" column index (or-1 if non-existent)//only to be returned if binder! = Null.boolean Wantscursormetadata = Data.readint ()! = 0;ibulkcursor bulkcursor = bulkquery (URL, p Rojection, Selection,selectionargs, SortOrder, observer, window); reply.writenoexception (); if (bulkcursor! = null) { Reply.writestrongbinder (Bulkcursor.asbinder ()); if (wantscursormetadata) {Reply.writeint (BulkCursor.count ()); Reply.writeint (Bulkcursortocursoradaptor.findrowidcolumnindex (Bulkcursor.getcolumnnames ()));}} else {reply.writestrongbinder (null);} return true;} ......}} catch (Exception e) {databaseutils.writeexceptiontoparcel (reply, E); return true;} Return Super.ontransact (Code, data, reply, flags);} ......}
Among them, Cursorwindow window = CursorWindow.CREATOR.createFromParcel (data); Please read the blog or the book for detailed explanations.


Fourth Step
~/android/frameworks/base/core/java/android/content

----Contentprovider.java

Public abstract class ContentProvider implements Componentcallbacks {... class Transport extends contentprovidernative {... public ibulkcursor bulkquery (Uri Uri, string[] projection,string selection, string[] Selectionargs, String sortorder,icontentobserver Observer, Cursorwindow window) {... cursor cursor = ContentProvider.this.query (URI, Projection,selection, Selectionargs, SortOrder), ... return new Cursortobulkcursoradaptor (cursor, Observer,contentprovider.this.getclass (). GetName (), Haswritepermission (URI), window);} ......} ......}
The following are the main things to do:

(1) Call the Ariticlesprovider query method and get the Sqlitecursor object.

(2) A Cursortobulkcursoradaptor object is formed by the cursor and window objects.


, the fifth step

if (bulkcursor! = null) {Reply.writestrongbinder (Bulkcursor.asbinder ()), if (wantscursormetadata) {Reply.writeint ( Bulkcursor.count ()); Reply.writeint (Bulkcursortocursoradaptor.findrowidcolumnindex (BulkCursor.getColumnNames ()) );}}
Pass Cursortobulkcursoradaptor objects, such as:

Sixth step, omit the binder_transaction transmission process, because the above has been analyzed .


Seventh Step

~/android/frameworks/base/core/java/android/content

----Contentprovidernative.java

Ibulkcursor Bulkcursor = Null;ibinder Bulkcursorbinder = Reply.readstrongbinder (); if (bulkcursorbinder! = null) { Bulkcursor = Bulkcursornative.asinterface (Bulkcursorbinder); if (wantscursormetadata) {int rowCount = Reply.readint (); int idcolumnposition = Reply.readint (); if (bulkcursor! = null) {Adaptor.set (Bulkcursor, RowCount, idcolumnposition);}}}
Bulkcursor is the Bulkcursorproxy object as follows:

Adaptor.set (Bulkcursor, RowCount, idcolumnposition);
Put the Bulkcursorproxy object into the handle variable mbulkcursor of the Bulkcursortocursoradaptor object.


Eighth step

return new Cursorwrapperinner (qcursor, provider);
Finally, the object is returned, Qcursor isthe Bulkcursortocursoradaptor object, provider as the Contentproviderproxy object.

So far, we have formed:



interprocess communication is over, and below we analyze how to apply anonymous shared memory to transfer data .

In a previous article on Android Content provider the boot process source code Analysis http://blog.csdn.net/jltxgcy/article/details/ 37725749, finally obtains the Contentproviderproxy object, passes the data through the inter-process communication .

public class Articlesadapter {... private contentresolver resolver = Null;public Articlesadapter (context context) { Resolver = Context.getcontentresolver ();} ... public article getarticlebypos (int pos) {uri uri = Contenturis.withappendedid (Articles.content_pos_uri, POS); string[] projection = new string[] {articles.id,articles.title,articles.abstract,articles.url}; cursor cursor = resolver.query (URI, projection, null, NULL, Articles.default_sort_order), if (!cursor.movetofirst ()) { return null;} int id = cursor.getint (0); String title = cursor.getstring (1); String ABS = cursor.getstring (2); String url = cursor.getstring (3); return new article (ID, title, ABS, URL);}}
  

We do not analyze the detailed process, first bulkcursortocursoradaptor the member variables inside the object mbulkcursor through interprocess communication, find Cursortobulkcursoradaptor object, The data is queried through the member function mcursor inside, and the anonymous shared memory pointed to by Mwindows is saved.

Instead, Bulkcursortocursoradaptor accesses the same anonymous shared memory through the member variable Mwindow. This mainactivity gets the data.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.