Android 3.0 SDK introduces many new APIs, such as loader. Similar to fragment (compiling fragment compatible with android1.6), this API can also be executed in Android 1.6 or later versions.
The following describes how to compile loader to asynchronously load listview. Effect
In this example, a background thread updates the Yangtze River record of the database every 3 seconds and changes the record to "Yangtze River" or "Long River ". Listview does not need to monitor database changes. It is automatically updated based on loader. In fact, this is the observer mode, which is nothing more than the built-in system. You only need to call it, and you do not need to construct the observer yourself.
This example is complete.SQLite + content provider + cursor adapter + listview + LoaderCombination example.
The preparations before writing are similar to compiling fragment compatible with android1.6. You need to import the jar package.
In addition, the previous 2.3 activity class did not provide some loader help methods, so you need to make your own activity implementation class inherit fragmentactivity:
Public class listviewactivity extendsFragmentactivity
In this example, theme is used in view display.
The activity class and the rivercontentprovider class have been modified.
Activity Class:
Public class listviewactivity extends fragmentactivity {
Private listview riverlistview;
Private simplecursoradapter adapter;
/** Called when the activity is first created .*/
@ Override
Public void oncreate (bundle savedinstancestate ){
Super. oncreate (savedinstancestate );
Setcontentview (R. layout. Main );
Initloader ();
Setriverlistviewadapter ();
}
Private void initloader (){
Getsupploadloadermanager (). initloader (0, null,
New loadercallbacks <cursor> (){
@ Override
Public loader <cursor> oncreateloader (int id, bundle ARGs ){
Log. D ("list", "On create loader ");
Cursorloader = new cursorloader (listviewactivity. This,
Rivercontentprovider. content_uri, new string [] {
Rivercontentprovider. _ id,
Rivercontentprovider. Name,
Rivercontentprovider. introduction },
Null, null, null );
// Cursorloader. setupdatethrottle (1000 );
Return cursorloader;
}
@ Override
Public void onloadfinished (loader <cursor> loader,
Cursor cursor ){
Log. D ("list", "On loader finished ");
Adapter. swapcursor (cursor );
}
@ Override
Public void onloaderreset (loader <cursor> loader ){
Log. D ("list", "On loader RESET ");
Adapter. swapcursor (null );
}
});
}
Private void setriverlistviewadapter (){
Riverlistview = (listview) This. findviewbyid (R. Id. riverlist );
Cursor cursor = managedquery (rivercontentprovider. content_uri, null,
Null, null, null );
Adapter = new simplecursoradapter (this, R. layout. Row, cursor,
New String [] {rivercontentprovider. Name,
Rivercontentprovider. introduction}, new int [] {
R. Id. rivername, R. Id. riverintroduction}, cursoradapter. flag_register_content_observer );
Riverlistview. setadapter (adapter );
}
The initloader method is added. The loadercallbacks interface is implemented here. Where:
- Oncreateloader, which will be called once after oncreate during activity Creation
- Onloadfinished, called once every time the database record related to loader is changed
- Onloaderreset, called when activity is disabled to release resources
Then, in the content provider, you need to call methods similar to those notified in the Observer mode, that is, notify the observer record changes in the update method, and register the observer in the query method, in this way, the notification can be received and processed.
Update method:
@ Override
Public int Update (URI Uri, contentvalues values, string selection,
String [] selectionargs ){
Int returnvalue = database. Update ("rivers", values, selection,
Selectionargs );
Getcontext (). getcontentresolver (). policychange (Uri, null );
Return returnvalue;
}
Query Method:
Public cursor query (URI Uri, string [] projection, string selection,
String [] selectionargs, string sortorder ){
Cursor cursor = database. Query ("rivers", projection, selection,
Selectionargs, null, null, sortorder );
Cursor. setnotificationuri (getcontext (). getcontentresolver (), Uri );
Return cursor;
}
Note that this observer mode is available from SDK Level 1. That is to say, cursor can receive notifications to perceive content provider data changes, but cannot asynchronously refresh the interface. This loader mechanism has implemented this function through official support.
In addition, this example shows that after the activity is closed, the content provider continues to work, and its background thread keeps updating records.
For the source code, see:
Http://easymorse.googlecode.com/svn/tags/CustomListViewDemo-0.4/