Use Handler in Android to implement message delivery mechanism (3)

Source: Internet
Author: User

Use Handler in Android to implement message delivery mechanism (3)

In the second article "using Handler in Android to implement message distribution mechanism (I)", we mentioned that the Logoff of the main thread is when the Android system starts the App, we have already created the Handler for us. If Handler needs to be used in the child thread, We need to explicitly call The logoff prepare method and loop method, to create a unique logoff for the sub-thread.

The 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 has provided such an implementation, a class called HandlerThread, which inherits the thread and calls logoff in its run method. prepare () and logoff. loop () method to create a thread with logoff, 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;    }

The logoff corresponding to the Handler defined in the main thread still belongs to the main thread. In fact, it only implements asynchronous processing in the main thread.

In daily development, HandlerIntent can be used to implement business processing in sub-threads.

Generally, we create a class to inherit HandlerThread, as shown below:

   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 this example, a MyHandlerThead object is created. Remember, it is a thread, so you need to call its start method to run the thread.

Next, we need to use one of Handler's constructor Handler (loler, Callback) to assign the Looper in the HandlerThread to handler, and then pass in the Handler. callback interface implementation class, as shown in the code above.

Finally, call the sendMessage method. The 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

It can be seen that the processing logic of handleMessage is already running in another thread.

Generally, Handler is also implemented when handlerThread is created. the Callback interface encapsulates the code logic to be implemented in this thread to make the code more readable, as shown below:

    public class MyHandlerThread extends HandlerThread implements Callback{        public MyHandlerThread(String name) {                        super(name);        }        @Override        public boolean handleMessage(Message msg) {            Log.v("Test", "id of Thread by Callback : " + Thread.currentThread().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 code readability, sometimes we pay more attention to the hierarchy or modularity and coupling between codes.

Different business logic and functions should be implemented in different modules, and the module and module can communicate with each other through a message, we can use Handler and HandlerThread.

For example, the class diagram of a small browser Demo recently made is as follows:


MessageDispatcher is used to store the Handler of each module. Its structure is as follows:

   private static MessageDispatcher mMsgDispatcher;          private SparseArray
 
   mHandlers;       ...    public void sendMessage(int target, int from, int msgWhat, Object obj){        Handler handler = mHandlers.get(target);        if(handler == null){            Logger.v("There is no Handler registered by target " + target);            return;        }        Message msg = handler.obtainMessage();                msg.what = msgWhat;        msg.obj = obj;        msg.arg1 = from;        handler.sendMessage(msg);            };        public void registerHanlder(int key, Handler handler){        mHandlers.put(key, handler);            }            public void unregisterHanlder(int key){        if(mHandlers.get(key) != null){            mHandlers.delete(key);        }    }        public void destroy(){        mHandlers = null;    }
 

In different module implementations, we can call the registerHandler method to register the Handler of the object to MessageDispatcher, and then specify the target through the sendMessage method, if the target module also sends a message to MessageDispatcher, the Handler can be obtained, and then the Handler can be used to send messages and process them.

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 process the corresponding message 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 can separate the business logic and data operations to implement functional programming.

Although it's just not a very mature idea, I still want to share with you the hope that when designing the code architecture, we can layer and block it based on functions, business needs, or basic frameworks, implement loose coupling of code.

End.





Related Article

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.