"Android from zero single row development diary"--android four components of the ContentProvider

Source: Internet
Author: User
Tags message queue name database

Data Source Component ContentProvider Unlike other components, the data source component does not include specific functional logic. It is only the interface that provides data access for the application. Many of the data built into Android are used in the form of contentprovider for developers to invoke (such as video, audio, images, contacts, etc.). If a third-party application is likened to a black box, the ContentProvider is like a pipeline extending from the inside, from which the application can share some data, and we can also transport the data inside. But we can't see what we can do with the data. And this pipe is a standard, not the data you plug into this pipeline.

First, the characteristics of ContentProvider
  1. Why do we use ContentProvider? There are several ways to read data across applications, such as those written in the last few blogs, but the ContentProvider feature is more than that. First it is one of the four components of Android, (we all know that component information is managed by Android), provides seamless access to data across processes, and provides a local cache in the process . cross-process calls require time and resource consumption, and caching can effectively improve efficiency. Moreover contentprovider the data access structure, rigorous is not prone to error. Then, when the Invoke interface is applied to operate, it is a synchronous process, that is, all data operations in the data Source Component object are executed serially in the message queue, and our developers do not need to consider complex concurrency scenarios. Finally, there is no limit to the way data is stored in data source components, which can be implemented in any way, such as databases, files, and so on.
  2. How do you find the contentprovider you want? It is positioned by URI. A URI is a global unified positioning flag that uniquely identifies the address information of a data source through a structured string, and each data source component has a unique URI identifier.

    ContentProvider's scheme has been set by Android, scheme: content://
    The hostname (or authority) is used to uniquely identify the contentprovider, and the external caller can find it based on the identity.
    Path can be used to represent the data we want to manipulate, and the path should be built according to the business, as follows:
    To manipulate records with ID 10 in the person table, you can build such a path:/PERSON/10
    To manipulate the name field of the record with ID 10 in the person table, Person/10/name
    To manipulate all the records in the person table, you can build such a path:/person
    To manipulate records in the XXX table, you can build such a path:/xxx
    Of course, the data you want to manipulate does not necessarily come from a database or other storage methods, such as files, XML, or networks, as follows:
    To manipulate the name node under the person node in the XML file, you can build such a path:/person/name
    If you want to convert a string to a URI, you can use the parse () method in the Uri class, as follows:
    Uri uri = uri.parse ("Content://com.ljq.provider.personprovider/person")

Ii. Examples of ContentProvider

Let's get to know it through an example. Use ContentProvider to operate on third-party databases.

  1. First weto build a DBHelper classInherit Sqliteopenhelper
    Package Com.example.database;import Android.content.context;import Android.database.sqlite.sqlitedatabase;import Android.database.sqlite.sqliteopenhelper;import Android.database.sqlite.sqlitedatabase.cursorfactory;public    Class DBHelper extends sqliteopenhelper{private static final int version=1; /** * In Sqliteopenhelper subclasses, you must have this constructor * @param context Context Object * @param name Database name * @param facto RY * @param version of the current database, the value must be an integer and an incremented state */public DBHelper (Context context,string name,cursorfactory FA    Ctory,int version) {super (context,name,factory,version);      } public DBHelper (context context, String name, int. version) {this (context,name,null,version);      } public DBHelper (context context, String name) {this (context,name,version); @Override public void OnCreate (Sqlitedatabase db) {////database is first constructed, this function is called, where you can construct tables, indexes, and so on SYSTEM.OUT.P          Rintln ("Create a Database"); The execsql is used to perform sqL Statement db.execsql ("CREATE Table notebook (_id integer primary key autoincrement,title varchar), content text,time L            ONG) "); } @Override public void Onupgrade (sqlitedatabase db, int oldversion, int newversion) {//If the given current database version is higher than the existing database    version, call the function System.out.println ("Upgrade a Database"); }  }

    There is nothing to explain this step, do not understand can take a look at my written on the database operation of the blog post.

  2. Next we are going to create a new MyProvider class inheritance ContentProvider
    Package Com.example.database;import Android.content.contentprovider;import Android.content.contenturis;import Android.content.contentvalues;import Android.content.urimatcher;import Android.database.cursor;import    Android.database.sqlite.sqlitedatabase;import Android.net.uri;public class MyProvider extends ContentProvider {  Private DBHelper DH = null;//Database Management Object Private Sqlitedatabase db;//get the database//urimatcher:creates the root node of the    URI Tree.    According to the official explanation, Urimatcher is a tree of URIs, and then uses the Adduri () method to add branches to it and find the branches through the match () function.    private static final Urimatcher MATCHER = new Urimatcher (urimatcher.no_match);    Set match code private static final int NOTEBOOK = 1;    private static final int notebooks = 2; static {//Add branches and give them a unique matching code to make it easy to find//if the match () method matches the Content://com.example.database/notebook path, the return match code is 1 M        Atcher.adduri ("Com.example.database", "Notebook", notebooks); If the match () method matches the content://com.example.database/notebook/#路径, the return match code is 2//where the # number is a wildcard character.        Matcher.adduri ("Com.example.database", "notebook/#", notebook); @Override public boolean onCreate () {///creates ContentProvider object, this function is called DH = new DBHelper (this.getconte        XT (), "note.db");//Database operation Object db = Dh.getreadabledatabase ();    return false;            }/** * Query, return cursor **/@Override public cursor query (URI URI, string[] projection, String selection,        String[] Selectionargs, String sortOrder) {//through the match function, get the match Code switch (Matcher.match (URI)) {                    Case Notebooks://Returns the result of the database operation return Db.query ("notebook", projection, selection, Selectionargs,        NULL, NULL, sortOrder);            Case NOTEBOOK://Because the ID was added, so the ID should be added to the WHERE condition long id = Contenturis.parseid (URI);            String where = "_id=" + ID; if (selection! = NULL &&! "".            Equals (selection)) {where = Selection + "and" + where; } return Db.query ("nOtebook ", projection, where, Selectionargs, NULL, NULL, sortOrder);        Default:throw new IllegalArgumentException ("Unkwon Uri:" + uri.tostring ()); }}//Gets the type of the URI @Override public String getType (URI uri) {//TODO auto-generated method Stub SWI            TCH (Matcher.match (URI)) {case Notebooks:return "Com.example.database.all/notebook";            Case Notebook:return "Com.example.database.item/notebook";          Default:throw new IllegalArgumentException ("Unkwon Uri:" + uri.tostring ()); }}//Insert data @Override public URI insert (URI uri, contentvalues values) {//TODO auto-generated method s Tub switch (Matcher.match (URI)) {Case Notebooks://Insert function of the call database//Specifically, the second parameter is when the TITL              When the E field is empty, a null is automatically inserted.              Long rowID = Db.insert ("Notebook", "title", values); Uri Inserturi = Contenturis.withappendedid (URI, ROWID);//Gets the URI This.getcontext () that represents the new record. Getcontentresolver (). Notifychange (URI, NULL);            return Inserturi;          Default:throw new IllegalArgumentException ("Unkwon Uri:" + uri.tostring ()); }}//delete data @Override public int Delete (URI Uri, String selection, string[] Selectionargs) {//TODO Aut        o-generated method stub int count; Switch (Matcher.match (URI)) {Case notebooks:count = Db.delete ("Notebook", Selection, Selectionargs              );            return count;              Case Notebook:long id = contenturis.parseid (URI);              String where = "_id=" + ID; if (selection! = NULL &&! "".              Equals (selection)) {where = Selection + "and" + where;              } count = Db.delete ("Notebook", where, Selectionargs);            return count; Default:throw new IllegalArgumentException ("Unkwon Uri:"+ uri.tostring ()); }}//Update data @Override public int update (URI uri, contentvalues values, String selection, string[] se          Lectionargs) {//TODO auto-generated method Stub int count = 0; Switch (Matcher.match (URI)) {Case notebooks:count = db.update ("Notebook", values, selection, Selec              Tionargs);          return count;              Case Notebook:long id = contenturis.parseid (URI);              String where = "_id=" + ID; if (selection! = NULL &&! "".              Equals (selection)) {where = Selection + "and" + where;              } count = Db.update ("Notebook", values, where, Selectionargs);          return count;          Default:throw new IllegalArgumentException ("Unkwon Uri:" + uri.tostring ()); }     }}

    Because the URI represents the data to manipulate, we often need to parse the URI and fetch the data from the URI. The Android system provides two tool classes for manipulating URIs, Urimatcher and Contenturis, respectively. Mastering their use will facilitate our development efforts.
    It looks like the Dbmanager class I wrote last time. In fact, this can be regarded as a very simple data manipulation class, the key point is that it is placed in the ContentProvider "container", so that third-party applications can also access their own data. So you want to thoroughly understand this component, as long as a thorough understanding of what is a URI, how to operate the URI sorta.

  3. Finally, do not forget to register for ContentProvider in the configuration file, because this is also a component, so there is no way to avoid the ~
    <provider android:name= ". MyProvider "android:authorities=" Com.example.database "/>

    The first is your class name, and then the key place, which is to be written in the URI, so don't get it wrong.
    Here, a project that can be accessed by other applications is built, so let's write a test project to check the results.

Third, call ContentProvider

When using the ContentProvider provided for you by other apps, you have to know two points: (1) Its authorities value, in my case "com.example.database"; (2) The structure of the data file, For example, I'm going to use the BookNote table in the database, which has (_id,title,content,time) these fields. Only by knowing this can you operate the ContentProvider.

  1. OK, let's start with a new project, set up the layout file, the effect is as follows

    Activity_main.xml
    Item.xml

  2. Next add code in Mainactivity
    Import Android.view.view;import Android.view.view.onclicklistener;import Android.widget.adapterview;import Android.widget.adapterview.onitemclicklistener;import Android.widget.button;import Android.widget.EditText; Import Android.widget.listview;import Android.widget.simplecursoradapter;import Android.widget.toast;import Android.app.activity;import Android.content.contentresolver;import Android.content.contentvalues;import Android.database.cursor;import Android.net.uri;import Android.os.bundle;public class MainActivity extends Activity    Implements Onclicklistener {private ListView listview;    Private Simplecursoradapter adapter;    Private Button Button_query, Button_insert, Button_delete, button_update;    Private EditText edittext_title, edittext_content;    private int CurItem;        @Override protected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate);                Setcontentview (R.layout.activity_main); Edittext_title = (editText) thiS.findviewbyid (R.ID.EDITTEXT1);                Edittext_content = (editText) This.findviewbyid (R.ID.EDITTEXT2);        ListView = (ListView) This.findviewbyid (R.id.listview1); Listview.setonitemclicklistener (New Onitemclicklistener () {@Override public void Onitemclick (adapte Rview<?> Parent, view view, int position, long id) {ListView LView = (ListView) p                arent;                Cursor data = (cursor) lview.getitematposition (position);                int _id = Data.getint (Data.getcolumnindex ("_id"));                Toast.maketext (mainactivity.this, _id + "", Toast.length_short). Show ();                CurItem = _id;                Edittext_title.settext (Data.getstring (Data.getcolumnindex ("title"));            Edittext_content.settext (Data.getstring (Data.getcolumnindex ("content"));        }        });        Button_query = (Button) This.findviewbyid (R.id.button1); Button_query.setoNclicklistener (this);        Button_insert = (Button) This.findviewbyid (R.id.button2);        Button_insert.setonclicklistener (this);        Button_delete = (Button) This.findviewbyid (R.id.button3);        Button_delete.setonclicklistener (this);        Button_update = (Button) This.findviewbyid (R.ID.BUTTON4);    Button_update.setonclicklistener (this); } @Override public void OnClick (View v) {//contentresolver It is an interface provided by ContentProvider that can invoke all of the ContentProvider        Method.        Contentresolver Contentresolver; TODO auto-generated Method Stub switch (V.getid ()) {Case r.id.button1:contentresolver = GetC            Ontentresolver ();            Uri.parse () Converts a string to a URI format.            Uri Selecturi = Uri.parse ("Content://com.example.database/notebook");            cursor cursor = contentresolver.query (Selecturi, NULL, NULL, NULL, or NULL); adapter = new Simplecursoradapter (this, r.layout.item, cursor, new StrinG[] {"_id", "title", "Content", "Time"}, new int[] {r.id.id, r.id.title, R.id.content, r.id.time},            1);            Listview.setadapter (adapter);        Break            Case r.id.button2:contentresolver = Getcontentresolver ();            Uri Inserturi = URI. Parse ("Content://com.example.database/notebook");            Contentvalues values = new Contentvalues ();            Values.put ("title", Edittext_title.gettext (). toString ());            Values.put ("Content", Edittext_content.gettext (). toString ());            Values.put ("Time", System.currenttimemillis ());            Uri uri = Contentresolver.insert (Inserturi, values);            Toast.maketext (this, uri.tostring () + "add Complete", Toast.length_short). Show ();        Break            Case r.id.button3:contentresolver = Getcontentresolver (); Uri Deleteuri = URI. Parse ("content://com.example.database/notebook/"+curitem);            int d = contentresolver.delete (Deleteuri, null,null);            Toast.maketext (This, curitem+ "Delete complete", Toast.length_short). Show ();        Break            Case r.id.button4:contentresolver = Getcontentresolver ();            Uri Updateuri = URI. Parse ("content://com.example.database/notebook/" +curitem);            Contentvalues updatevalues = new Contentvalues ();            Updatevalues.put ("title", Edittext_title.gettext (). toString ());            Updatevalues.put ("Content", Edittext_content.gettext (). toString ());            Updatevalues.put ("Time", System.currenttimemillis ());            int u = contentresolver.update (Updateuri, updatevalues,null,null);            Toast.maketext (This, curitem+ "update Complete", Toast.length_short). Show ();        Break }    }}

    Two applications between the flow chart is probably the case (hand down, do not abandon ~)

  3. Finally, install the two applications and open the practice. So let's look at the results of the operation.

    Normal operation. So this is the end of the day.

Iv. concluding remarks

In theory, the data source component does not have the so-called life cycle, because the state of the data source component is not the basis for determining the process priority. Therefore, when the system recycles the process resources, it does not tell the developer about the destruction events of the data source component. However, the OnCreate () function is called when the ContentProvider component is constructed. Therefore, do not deploy deferred write optimization policies in the data source components, and when the system is silently recycled, some of the data that is not persisted is lost. Once the data source component is constructed, it remains in a long-running state until the process in which it resides is reclaimed by the system. Therefore, do not cache too much data in the data source component to avoid taking up memory space.

"Android from zero single row development diary"--android four components of the ContentProvider

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.