Android framework Handler \ HandlerThread \ logoff \ Message \ MessageQueue \

Source: Internet
Author: User

Logoff and Handler Analysis]

As far as application programs are concerned, Java applications in the Android system are the same as those in other systems, and work by messaging. Their general working principles are as follows:

A. There is a message queue column that can be used to send messages to this queue.

B. There is a message cycle. If you do not retrieve the message from the Message Queue column, the message will be processed later.

 

In the Android system, these tasks are mainly implemented by logoff and Handler:

A. logoff type is used to block messages and has a message queue column.

B. Handler is a bit like a helper class. It blocks APIs such as message projection and message processing.

Logoff is the relationship among them.

 

Through analysis, we can see that logoff is used:

A. a message response column is blocked.

B. The prepare function of Loopers binds the Loopers and threads with the prepare Statement (that is, the most appropriate processing Statement.

C. Handle messages in the response column by using the loop function.

 

Logoff, Message, and Handler

Loaning, Message, and Handler are also irrelevant: You can clear them in two sentences:

A. There is a Message queue column in logoff, which contains a Message to be processed.

B. There is a Handler in the Message, which is used to handle the Message.

 

Handler sets the target of the Message as himself, because Handler has completed the Message processing interface in addition to the function of adding messages to messages.

================================================ Low.used Sample ==== ======================================

* <P> This is a typical example of the implementation of a low.thread,
* Using the separation of {@ link # prepare} and {@ link # loop} to create
* Initial Handler to communicate with the logoff.
*
* <Pre>
* Class LooperThread extends Thread {
* Public Handler mHandler;
*
* Public void run (){
* Logoff. prepare ();
*
* MHandler = new Handler (){
* Public void handleMessage (Message msg ){
* // Process incoming messages here
*}
*};
*
* Logoff. loop ();
*}
*} </Pre>

====================================== HandlerThread ==== ==================================

Public void run (){
MTid = Process. myTid ();
Logoff. prepare ();
Synchronized (this ){
Mlogoff = logoff. mylogoff ();
Policyall ();
}
Process. setThreadPriority (mPriority );
OnLooperPrepared ();
Logoff. loop ();
MTid =-1;
}

/**
* This method returns the Looper associated with this thread. If this thread not been started
* Or for any reason is isAlive () returns false, this method will return null. If this thread
* Has been started, this method will block until the loginhas been initialized.
* @ Return The logoff.
*/
Public Looper getLooper (){
If (! IsAlive ()){
Return null;
}

// If the thread has been started, wait until the looper has been created.
Synchronized (this ){
While (isAlive () & mlogoff = null ){
Try {
Wait ();
} Catch (InterruptedException e ){
}
}
}
Return mLooper;
}

 

======================================== Resource Code ==== ====================================

Privatized Logoff:

 

    private Looper() {
mQueue = new MessageQueue();
mRun = true;
mThread = Thread.currentThread();
}

 

Examples of Logoff:

     /** Initialize the current thread as a looper.
* This gives you a chance to create handlers that then reference
* this looper, before actually starting the loop. Be sure to call
* {@link #loop()} after calling this method, and end it by calling
* {@link #quit()}.
*/
public static final void prepare() {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper());
}

Logoff cycle:

    /** Returns the application's main looper, which lives in the main thread of the application.
*/
public synchronized static final Looper getMainLooper() {
return mMainLooper;
}
/**
* Run the message queue in this thread. Be sure to call
* {@link #quit()} to end the loop.
*/
public static final void loop() {
Looper me = myLooper();
MessageQueue queue = me.mQueue;
while (true) {
Message msg = queue.next(); // might block
//if (!me.mRun) {
// break;
//}
if (msg != null) {
if (msg.target == null) {
// No target is a magic identifier for the quit message.
return;
}
if (me.mLogging!= null) me.mLogging.println(
">>>>> Dispatching to " + msg.target + " "
+ msg.callback + ": " + msg.what
);
msg.target.dispatchMessage(msg);
if (me.mLogging!= null) me.mLogging.println(
"<<<<< Finished to " + msg.target + " "
+ msg.callback);
msg.recycle();
}
}
}
/**
* Return the Looper object associated with the current thread. Returns
* null if the calling thread is not associated with a Looper.
*/
public static final Looper myLooper() {
return (Looper)sThreadLocal.get();
}
    public void quit() {
Message msg = Message.obtain();
// NOTE: By enqueueing directly into the message queue, the
// message is left with a null target. This is how we know it is
// a quit message.
mQueue.enqueueMessage(msg, 0);
}

 

We can see that the Handler instance should be behind the logoff instance through the following generation.

    /**
* Default constructor associates this handler with the queue for the
* current thread.
*
* If there isn't one, this handler won't be able to receive messages.
*/
public Handler() {
if (FIND_POTENTIAL_LEAKS) {
final Class<? extends Handler> klass = getClass();
if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
(klass.getModifiers() & Modifier.STATIC) == 0) {
Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
klass.getCanonicalName());
}
}

mLooper = Looper.myLooper();
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}
mQueue = mLooper.mQueue;
mCallback = null;
}

 

If we put lorule. prepare () after the Handler example, what else will happen ??? [You can use the following token generator to perform a failover]

This section is taken from: http://blog.csdn.net/dengxiayehu
D. Create a New thread and create a logoff in the new thread. The main thread calls the message sending method in the subthread and sends the message to the Message Queue of the subthread.

Java code collection code

Package com. dxyh. test;

Import android. app. Activity;
Import android. OS. Bundle;
Import android. OS. Handler;
Import android. OS. logoff;
Import android. OS. Message;
Import android. util. Log;

Public class MainActivity extends Activity {
Private final static String TAG = "HandlerTest ";

Private final static int TASK_BEGIN = 1;
Private final static int TASK_1 = 2;
Private final static int TASK_2 = 3;
Private final static int TASK_END = 4;

Private Handler workHandler = null;

/** Called when the activity is first created .*/
@ Override
Public void onCreate (Bundle savedInstanceState ){
Super. onCreate (savedInstanceState );
SetContentView (R. layout. main );

Log. I (TAG, "[M_TID:" + Thread. currentThread (). getId () + "]" +
"This is in main thread .");

LooperThread testThread = new LooperThread ();
TestThread. start ();

// Note: Please wait to prevent null pointer exceptions.
While (null = workHandler ){
}

TestThread. sendMessageTodoYourWork ();
}

Class LooperThread extends Thread {
@ Override
Public void run (){
Logoff. prepare ();

WorkHandler = new Handler (){
// Now after each case, you can perform any time-consuming operations
@ Override
Public void handleMessage (Message msg ){
Switch (msg. what ){
Case TASK_BEGIN:
Log. I (TAG, "[H_TID:" +
Thread. currentThread (). getId () + "] Get TASK_BEGIN ");
Break;

Case TASK_1:
Log. I (TAG, "[H_TID:" +
Thread. currentThread (). getId () + "] Get TASK_1 ");
Break;

Case TASK_2:
Log. I (TAG, "[H_TID:" +
Thread. currentThread (). getId () + "] Get TASK_2 ");
Break;

Case TASK_END:
Log. I (TAG, "[H_TID:" +
Thread. currentThread (). getId () + "] Get TASK_END ");
Loband. myloband (). quit ();
Finish ();
Break;
}
Super. handleMessage (msg );
}
};

Logoff. loop ();
}

Public void sendMessageTodoYourWork (){
Log. I (TAG, "[S_ID:" + Thread. currentThread (). getId () + "]" +
"Send TASK_START to handler .");
// Start the task (the message is only identified and delivered immediately)
WorkHandler. sendEmptyMessage (TASK_BEGIN );

Log. I (TAG, "[S_ID:" + Thread. currentThread (). getId () + "]" +
"Send TASK_1 to handler .");
// Start Task 1 (get a Message object in the Message queue of workHandler to avoid repeated construction)
Message msg1 = workHandler. obtainMessage (TASK_1 );
Msg1.obj = "This is task1 ";
WorkHandler. sendMessage (msg1 );

Log. I (TAG, "[S_ID:" + Thread. currentThread (). getId () + "]" +
"Send TASK_2 to handler .");
// Enable Task 2 (similar to above)
Message msg2 = Message. obtain ();
Msg2.arg1 = 10;
Msg2.arg2 = 20;
Msg2.what = TASK_2;
WorkHandler. sendMessage (msg2 );

Log. I (TAG, "[S_ID:" + Thread. currentThread (). getId () + "]" +
"Send TASK_END to handler .");
// End the task (empty message body, delayed 2 S delivery)
WorkHandler. sendEmptyMessageDelayed (TASK_END, 2000 );
}
}
}

 

 

 

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.