In the second article, "How touse handler to implement message distribution mechanism in Android (i)", we talked about the main thread of the Looper is the Android system in the launch of the app, it has helped us to create a good, And if you need to use handler in a child thread, we need to explicitly call Looper's prepare method and the loop method to create its unique looper for the child thread.
The specific code is as follows:
Class Looperthread extends Thread {public Handler Mhandler; public void Run () { looper.prepare (); Mhandler = new Handler () {public void Handlemessage (Message msg) { log.v ("Test", "Id of Looperthread:" + Thread . CurrentThread (). GetId ()); ... } } }; Looper.loop (); } }
In fact, the Android SDK already provides such an implementation, a class called Handlerthread, which inherits threads and calls the Looper.prepare () and Looper.loop () methods in its Run method. This creates a thread that already has a looper, as shown in the following code:
@Override public Void Run () { Mtid = Process.mytid (); Looper.prepare (); Synchronized (this) { mlooper = Looper.mylooper (); Notifyall (); } Process.setthreadpriority (mpriority); Onlooperprepared (); Looper.loop (); Mtid =-1; }
We define in the main thread of the handler corresponding to the Looper, or belong to the main thread, then in fact, it is only implemented in the main thread asynchronous processing only.
In daily development, when we need to use handler to implement business processing in sub-threads, we can use handlerintent to achieve our needs.
In general, we will create a class to inherit the Handlerthread, as follows:
public class Myhandlerthread extends Handlerthread {public myhandlerthread (String name) { super (name); } } protected void OnCreate (Bundle savedinstancestate) { super.oncreate (savedinstancestate); LOG.V ("Test", "Id of Mainthread:" + thread.currentthread (). GetId ()); Myhandlerthread myhandlerthread = new Myhandlerthread ("Myhandlerthread"); Myhandlerthread.start (); Handler Handler = new Handler (Myhandlerthread.getlooper (), new Callback () { @Override public Boolean Handlemessage (Message msg) { log.v ("Test", "ID of Thread by Callback:" + thread.currentthread (). GetId ()); return false; } }); Handler.sendemptymessage (0); }
In the example, a Myhandlerthead object is created, remembering that it is a thread, so it needs to call its Start method and let the thread run up.
Next, you need to use one of the handler constructors handler (Looper, Callback) to assign Handlerthread in the Looper thread to handler, and with it, is the Handler.callback interface implementation class, as shown in the preceding code.
Finally call the SendMessage method, the corresponding result is as follows:
10-28 17:24:50.438:v/test (31694): ID of mainthread:110-28 17:24:50.448:v/test (31694): ID of Thread by callback:91617
As can be seen, Handlemessage's processing logic is already running in another thread.
In general, when we create handlerthread, we also implement the Handler.callback interface, encapsulating the code logic we want to implement in this thread, making the code more readable, as follows:
public class Myhandlerthread extends Handlerthread implements callback{public myhandlerthread (String name) { Super (name); } @Override Public Boolean handlemessage (Message msg) { log.v ("Test", "ID of the Thread by Callback:" + thread.current Thread (). GetId ()); return true; } } protected void OnCreate (Bundle savedinstancestate) { super.oncreate (savedinstancestate); LOG.V ("Test", "Id of Mainthread:" + thread.currentthread (). GetId ()); Myhandlerthread myhandlerthread = new Myhandlerthread ("Myhandlerthread"); Myhandlerthread.start (); Handler Handler = new Handler (Myhandlerthread.getlooper (), myhandlerthread); Handler.sendemptymessage (0); }
When it comes to readability of code, sometimes we value the level of code or the modularity, coupling, and so on.
Different business logic, different functions, should be implemented in different modules, and modules and modules can be communicated through a message, and this way of message communication, we can use handler and handlerthread to achieve.
For example, a recent small demo of a browser, its class diagram is as follows:
In which we use the MessageDispatcher to store the handler of each module, which is structured as follows:
private static MessageDispatcher Mmsgdispatcher; Private sparsearray
In different module implementations, we can call the Registerhandler method, register the handler of its object in MessageDispatcher, and then specify the corresponding target through the SendMessage method, If the corresponding target module is also messagedispatcher, it can obtain its handler, and then use its handler to send the message and handle it.For example, we send a message to Bookmarkmanager in Bookmarkactivity, as follows:
Mmessagedispatcher.sendmessage (Messageconstant.target_bookmark_mgr, Messageconstant.target_bookmark_activity, Messageconstant.msg_bookmark_get_all_dir, Sparsearray);
In Bookmarkmanager, when the handler receives the corresponding message, it will do the corresponding processing, as follows: Class Bookmarkhandlerthread extends Handlerthread implements callback{public bookmarkhandlerthread (String name) { super (name); } @SuppressWarnings ("unchecked") public Boolean handlemessage (Message msg) { switch (msg.what) { case Messageconstant.msg_bookmark_get_all_dir: //do Something
In this way, we are able to separate the business logic from the data operation and implement the functional programming.Although it is not a very mature idea, but still want to share with you, in the design of the code architecture, can be based on functional, business requirements or infrastructure framework for layering, chunking, to achieve the loose coupling of code.
End.
Using handler to implement message distribution mechanism in Android (iii)