[Android personal understanding (1)] using the relationship between logoff and Handle, we can understand the logoff mechanism and androidlogoff.
Logoff and Handle are new concepts unique to Android, but they are often learned separately. In fact, they are inseparable.
Relationship between logoff and Handle:
Logoff is a class that establishes a message loop in the thread, including preparing, starting, and stopping the entire message cycle. Handle is a class responsible for messages between different threads, including the life cycle of messages such as message sending, receiving, and clearing.
Handle is used only when there is a logoff thread. Without Handle, logoff cannot receive messages and thus cannot implement functions.
We analyze the following through logoff and Handle source code:
Logoff. java
private static final ThreadLocal sThreadLocal = new ThreadLocal(); public static final void prepare() { if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(new Looper()); }
Here, we use prepare () to create a logoff object. At the same time, Android also stipulates that a thread can have only one loose.
From new logoff (), we can see the logoff constructor.
final MessageQueue mQueue; private Looper() { mQueue = new MessageQueue(); mRun = true; mThread = Thread.currentThread(); }
We can see that a message queue object mQueue is created in the logoff constructor. At this time, the thread that calls logoff. prepare () creates a message loop object.
Now let's look at the Handle source code:
Handle. java
final MessageQueue mQueue; final Looper mLooper; 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; }
The last line "Can't create handler inside thread that has not called logoff. prepare () "indicates that the use of Handle must have logoff. prepare (), that is, the information queue must exist so that Handle can find the information. Handler is bound to the local variable Logoff of the thread through mLooper = Looper. myLooper (), and Handler obtains the thread Message Queue through mQueue = mloue. mQueue.
Without Handle, handleMessage (Message msg) {} is used. Only logoff information queues are in the loop, so there is no value for information.
While we usually use Handle, but do not declare logoff in the UI thread, because the UI thread itself contains the logoff mechanism by default. We often see "logoff" when reporting errors in this program ".
The final work principle is summarized as follows:
1. initialize logoff and start the message loop.
2. Bind handler to The logoff object of the CustomThread instance
3. In a loose loop, send messages through Handle or wait for messages all the time.
4. Handle gets the message through logoff and processes the message.
Code example and more logoff Implementation Mechanism source code:
Package com. zhuozhuo; import android. app. activity; import android. OS. bundle; import android. OS. handler; import android. OS. logoff; import android. OS. message; import android. util. log; import android. view. view; import android. view. view. onClickListener; public class LooperThreadActivity extends Activity {/** Called when the activity is first created. */private final int MSG_HELLO = 0; private Handler mHandler; @ Override public void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. main); new CustomThread (). start (); // create and start the finmthread instance findViewById (R. id. send_btn ). setOnClickListener (new OnClickListener () {@ Override public void onClick (View v) {// send the message String str = "hello"; Log when you click the interface. d ("Test", "MainThread is ready to send msg:" + str); mHandler. obtainMessage (MSG_HELLO, str ). sendToTarget (); // send a message to the CustomThread instance});} class CustomThread extends Thread {@ Override public void run () {// create a message loop. prepare (); // 1. initialize lovesmhandler = new Handler () {// 2. Bind The lovesobject public void handleMessage (Message msg) to the CustomThread instance) {// 3. Define the Message Processing Method switch (msg. what) {case MSG_HELLO: Log. d ("Test", "CustomThread receive msg:" + (String) msg. obj) ;}}; logoff. loop (); // 4. Start the message loop }}}
Google source code:
private class Worker implements Runnable { private final Object mLock = new Object(); private Looper mLooper; /** * Creates a worker thread with the given name. The thread * then runs a {@link android.os.Looper}. * @param name A name for the new thread */ Worker(String name) { Thread t = new Thread(null, this, name); t.setPriority(Thread.MIN_PRIORITY); t.start(); synchronized (mLock) { while (mLooper == null) { try { mLock.wait(); } catch (InterruptedException ex) { } } } } public Looper getLooper() { return mLooper; } public void run() { synchronized (mLock) { Looper.prepare(); mLooper = Looper.myLooper(); mLock.notifyAll(); } Looper.loop(); } public void quit() { mLooper.quit(); } }