Android cainiao study notes 22 ---- ContentProvider (2) simple use of ContentObserver, contentobserver
Currently, application A provides its own data to other applications through ContentProvider. Application B obtains the data provided by application A through ContentResolver and displays it in ListView, application C modifies the data in application A through ContentResolver, or adds new data. The problem is that after applying C to modify the data in A, the historical data displayed in ListView of application B is still ......
The specific procedure is as follows:
The ContentProvider and the data inserted Application Reuse the two applications in the previous article respectively, and then create a new application to obtain the data in the ContentProvider, and display the following in a ListView:
Add a ListView in the layout file activity _ main. xml:
1 <ListView2 3 android:id="@+id/lv"4 5 android:layout_width="match_parent"6 7 android:layout_height="wrap_content"></ListView>
The layout file item_layout.xml is used to display entries in ListView:
1 <?xml version="1.0" encoding="utf-8"?> 2 3 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 4 5 android:layout_width="match_parent" 6 7 android:layout_height="match_parent" 8 9 android:orientation="horizontal" >10 11 <TextView12 13 android:id="@+id/tv_id"14 15 android:layout_width="wrap_content"16 17 android:layout_height="wrap_content"18 19 android:layout_weight="1"/>20 21 <TextView22 23 android:id="@+id/tv_name"24 25 android:layout_width="wrap_content"26 27 android:layout_height="wrap_content"28 29 android:layout_weight="1"/>30 31 <TextView32 33 android:id="@+id/tv_gender"34 35 android:layout_width="wrap_content"36 37 android:layout_height="wrap_content"38 39 android:layout_weight="1"/>40 41 <TextView42 43 android:id="@+id/tv_age"44 45 android:layout_width="wrap_content"46 47 android:layout_height="wrap_content"48 49 android:layout_weight="1"/>50 </LinearLayout>
Add the code for retrieving data and displaying it to ListView in MainActivity:
1 protected void onCreate(Bundle savedInstanceState) { 2 3 super.onCreate(savedInstanceState); 4 5 setContentView(R.layout.activity_main); 6 7 uri = Uri.parse("content://cn.csc.content_provider/t_student"); 8 9 Cursor cursor = getContentResolver().query(uri, new String[]{"id as _id","name","gender","age"}, null, null, null);10 11 lv = (ListView) findViewById(R.id.lv);12 13 lv.setAdapter(new SimpleCursorAdapter(this,R.layout.item_layout,cursor,14 15 new String[]{"_id","name","gender","age"},new int[]{R.id.tv_id,R.id.tv_name,R.id.tv_gender,R.id.tv_age}));16 17 }
Running result:
The Adapter class SimpleCursorAdapter is used above, and its construction parameters are described as follows:
The first parameter specifies the application context instance.
The second parameter specifies the layout id displayed for each entry in the ListView.
The third parameter specifies the Cursor result set object for storing the data to be displayed.
The fourth and fifth parameters jointly specify the control in which each field in the Cursor result set is placed in the layout file. The elements in these two arrays correspond one by one in order. The fourth parameter is of the String [] type. Each element is the field name in the result set, the fifth parameter is of the int [] type, and each parameter is the resource id of each control in the layout file.
Note that SimpleCursorAdapter requires that a field named _ id exists in the table; otherwise, an error is reported to stop running properly.
However, the table I created previously does not have the _ id field, but the id field does not want to change the table definition. In this case, you can use the query () method, the second parameter used to specify the field to be queried uses the alias:
Cursor cursor = getContentResolver (). query (uri, new String [] {"id as _ id", "name", "gender", "age"}, null );
In this way, the field name in the result set is changed from id to _ id, and SimpleCursorAdapter can be used normally.
However, in this case, the application that acts as application C adds data through the insert () method. The ListView in the current application does not change, but the historical data is incomplete !!!
To solve this problem, android provides a class named ContentObserver, which is used to observe whether the data of a specific uri has changed. When there is a change, you can perform corresponding processing as needed.
Use of ContentObserver:
Step 1: Register ContentObserver in application B, declare the uri to be observed, and rewrite the onChange method to complete the required business logic..
The Code is as follows:
1 uri = Uri. parse ("content: // cn. csc. content_provider/t_student "); 2 3 getContentResolver (). registerContentObserver (uri, true, new ContentObserver (new Handler () {4 5 @ Override 6 7 public void onChange (boolean selfChange) {8 9 // TODO Auto-generated method stub10 11 super. onChange (selfChange); 12 13 Log. I ("Test", "changed"); 14 15 Cursor cursor = getContentResolver (). query (uri, new String [] {"id as _ id", "name", "gender", "age"}, null ); 16 17 lv = (ListView) findViewById (R. id. lv); 18 19 lv. setAdapter (new SimpleCursorAdapter (MainActivity. this, R. layout. item_layout, cursor, 20 21 new String [] {"_ id", "name", "gender", "age"}, new int [] {R. id. TV _id, R. id. TV _name, R. id. TV _gender, R. id. TV _age}); 22 23 Toast. makeText (MainActivity. this, "the data has changed and the ListView display has been refreshed", Toast. LENGTH_SHORT ). show (); 24 25} 26 27 28 29 });
Step 2: In the insert (), update (), and delete () methods in application A, notify the observer of the content of these Uris, and notify the data to change, it will trigger the corresponding onChange method to complete the business of data changes.
The Code is as follows:
1 getContext (). getContentResolver (). policychange (uri, null );
Current ListView status:
Test the addition, deletion, and modification method in application C and observe the operation in application B:
Add:
1 public void testInsert(){ 2 3 Uri uri = Uri.parse("content://cn.csc.content_provider/t_student"); 4 5 ContentValues values = new ContentValues(); 6 7 values.put("name", "csc"); 8 9 values.put("gender", "male");10 11 values.put("age", 25);12 13 Uri uri2 = getContext().getContentResolver().insert(uri, values);14 15 Log.i("Test",uri2.toString());16 17 }
Running result:
Delete:
1 public void testDelete(){2 3 Uri uri = Uri.parse("content://cn.csc.content_provider/t_student");4 5 int i = getContext().getContentResolver().delete(uri, "id>?", new String[]{"7"});6 7 Log.i("Test",i+"");8 9 }
Running result:
Change:
1 public void testUpdate(){ 2 3 Uri uri = Uri.parse("content://cn.csc.content_provider/t_student"); 4 5 ContentValues values = new ContentValues(); 6 7 values.put("name", "dqrcsc"); 8 9 values.put("gender", "male");10 11 values.put("age", 24);12 13 int i = getContext().getContentResolver().update(uri, values, "id>?", new String[]{"3"});14 15 Log.i("Test",i+"");16 17 }
Running result:
The above is the simple use of ContentObserver.