Previously wrote an article "Android Learning Small demo (Android) on the use of Contentobserver ", in which the use of Contentoberver to monitor the text message URI content changes. Let's take a look at how contentoberver is used to monitor the changes in SMS content.
1) to customize a class such as Smscontentobserver, inherit Contentobserver, and implement its OnChange method.
2) in the OnChange method to query the corresponding URI, such as the contents of the message Inbox, and the corresponding record using handler sent to the main interface.
3) in the main interface activity, create a smscontentobserver and register it with Contentreslover.
4) in the main interface activity in the handler to get the message changed in Smscontentobserver, update the main interface.
In general, the process is probably the case, we are interested to have a look at this article.
This article introduces another method, using loader to achieve almost the effect, since it can say the effect is similar, then it shows that loader has a character with Contentobserver, yes, it can detect the corresponding content changes.
Let's briefly say what is loader.
Loader is a class introduced by Android after 3.0, its main purpose is to make the interaction between Android and data more simple and efficient, summed up, I think its function has the following two points:
1) Dynamic monitoring of the changes in the state of the processed objects, in most cases, the processing of data, but I think it is only one aspect.
2) When the interface changes and needs to be recreated, they will be able to load back to the previous data without having to re-query.
Of course, it is still asynchronous, it means that it will not block the display of the main interface, but this feature many other auxiliary classes have, it is not a feature.
And it is the 1th feature that gives us the opportunity to implement a contentobserver without the hassle and instead to use loader to achieve the same functionality.
This time we do a demo of displaying text messages. When we open the SMS app in the phone, if there is a new text message coming in, we will see the new text message immediately displayed on the interface, and we this demo is exactly the effect, see (Big Point, Mo Strange).
As you can see, when we click the Send button, the text message is sent over and the ListView immediately displays the text message that was just sent.
So how to use loader, let's look at the code below.
1) since the loader is 3.0 after the introduction, so before 3.0, if we want to use loader, the main activity must inherit fragmentactivity to be able to get loadermanager.
2) To implement the internal interface of the Loadermanager Loadercallbacks<d>, this is a generic interface, which is defined as follows:
Public interface Loadercallbacks<d> {/** * Instantiate and return a new Loader for the given ID. * * @param ID The ID whose loader is created. * @param args Any arguments supplied by the caller. * @return return a new Loader instance that's ready to start loading. */Public loader<d> oncreateloader (int id, Bundle args); /** * ... * @param loader the loader that have finished. * @param data The data generated by the Loader. */public void onloadfinished (loader<d> Loader, D data); /** * Called when a previously created loader are being reset, and thus * making its data unavailable. The application should at this point * remove any references it have to the Loader ' s data. * * @param loader the loader is being reset. */public void Onloaderreset (loader<d> Loader); }
So, the first step in our code is to implement this interface, as follows:
public class Mainactivity extends fragmentactivity implements loadercallbacks<cursor>{ ... Private URI uri = Uri.parse ("Content://sms/inbox"); ... @Overridepublic loader<cursor> oncreateloader (int arg0, Bundle arg1) {string[] projection = new string[] {"_id", "ad Dress "," body "," type "};return new Cursorloader (this, URI, projection, null, NULL," date desc ");} @Overridepublic void onloadfinished (loader<cursor> Loader, cursor cursor) {madapter.swapcursor (cursor);} @Overridepublic void Onloaderreset (loader<cursor> arg0) {//TODO auto-generated method stub}
3) to define a URI, because loader it has to load data from somewhere, and in this demo, we're going to get a text message from the Inbox, so here's the sms/inbox.
4) in the Oncreateloader method, create a cursorloader. Cursorloader is a subclass of Asynctaskloader, so it is an asynchronous loader that does not affect the presentation of the main interface.
5) in the Onloadfinished method, the data that is stored in the cursor after the load is returned is processed.
The above interface is just the way it is implemented, and when the following method is called, loader only starts to really work. In the OnCreate method,
@Overrideprotected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate); Setcontentview ( R.layout.activity_main); Lvlistview = (ListView) Findviewbyid (r.id.lvlistview); madapter = new Simplecursoradapter ( This, Android. R.layout.simple_list_item_2, NULL, new string[] {"Address", "Body"}, new int[] {Android. R.id.text1, Android. R.ID.TEXT2}); Lvlistview.setadapter (Madapter); Getsupportloadermanager (). Initloader (loader_id, NULL, this);}
Since we are using the support package, we need to use the Getsupportloadermanager class to invoke the Initloader method, which has three parameters:
A) ID, since an activity or fragment has only one loadermanager, but a loadermanager can have multiple loader to handle different data, so the ID can uniquely determine which loader it is here.
b) Bundle, which is a collection of parameters passed to Loadermanager.
c) This is a Loadercallbacks implementation class, which is the activity in this demo, so this is this.
6) when calling the Getsupportloadermanager (). Initloader () method, Android will first determine whether such a loader is already present, and if so, it will use the existing loader directly, Instead of creating a new one, that is, it does not call the Oncreateloader method in the interface method. If there is no loader for the corresponding ID, then the Oncreateloader method is called and a new loader is instantiated.
And when the corresponding ID loader already exists, Android will load the data directly, and the interface method onloadfinished will be called immediately after the data load, so there is a situation, If the variable used in the Onloadfinished method is initialized in Oncreateloader, then this variable is not initialized at all, it is used, the program will error, so in the actual development, to take into account the existence of such a situation, in In the Onloadfinished method, some judgments should be done.
Finally there is a Onloaderreset method, not used, this method is mainly in the loader is no longer used, is closed, and so on, to release the use of loader, such as in this demo, if loader no longer use, Then our adpater should not be associated with the corresponding cursor, then you can judge here.
End! source code download.