編輯:關於Android編程
Tip:在Activity的啟動代碼中,已經在當前UI線程調用了Looper.prepare()和Looper.loop()方法。創建handler就不用顯示的調用Looper.prepare()和Looper.loop()
觀察者模式
創建一個MessageQueue,輪詢MessageQueue
構造方法private Looper(boolean quitAllowed) { mQueue = new MessageQueue(quitAllowed); mRun = true; mThread = Thread.currentThread(); }
public static final void prepare() { if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(new Looper(true)); }
消息創建者,異步分發
public Handler() { this(null, false); } public Handler(Callback callback, boolean async) { 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 = callback; mAsynchronous = async; }
public final boolean sendMessage(Message msg) { return sendMessageDelayed(msg, 0); }
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) { msg.target = this; if (mAsynchronous) { msg.setAsynchronous(true); } return queue.enqueueMessage(msg, uptimeMillis); }msg.target = this; => msg.target.dispatchMessage(msg); handler發出的消息,最終會保存到消息隊列中去
public void dispatchMessage(Message msg) { if (msg.callback != null) { handleCallback(msg); } else { if (mCallback != null) { if (mCallback.handleMessage(msg)) { return; } } handleMessage(msg); } }
private Handler mHandler = new Handler() { public void handleMessage(android.os.Message msg) { switch (msg.what) { case value: break; default: break; } }; };
mHandler.post(new Runnable() { @Override public void run() { Log.e("TAG", Thread.currentThread().getName()); mTxt.setText("yoxi"); } });
public final boolean post(Runnable r) { return sendMessageDelayed(getPostMessage(r), 0); }
private static Message getPostMessage(Runnable r) { Message m = Message.obtain(); m.callback = r; return m; }在getPostMessage中,得到了一個Message對象,然後將我們創建的Runable對象作為callback屬性,賦值給了此message.
注:
產生一個Message對象,可以new ,也可以使用Message.obtain()Message內部維護了一個Message池用於Message的復用,使用Message.obtain()方法避免使用new 重新分配內存。如果你的message只需要攜帶簡單的int信息,請優先使用Message.arg1和Message.arg2來傳遞信息,這比用Bundle更省內存擅用message.what來標識信息,以便用不同方式處理message如果不為null,則執行callback回調,也就是我們的Runnable對象。
1,使用Handler 是異步的,它會建立新的線程麼? 不會
2,Handler 是在主線程內麼? 一般都會在主線程內,但也可以在子線程中創建Handler
3,Handler 的 post 和 sendMessage 方法,使用的是一個隊列不安是兩個? 一個
4,子線程中建立一個 handler, 然後sendMessage 會怎麼樣? 會崩潰
5,子線程建立 handler ,構造的時候舒心入主線程的 Looper ? yes
之前的博文中有介紹關於圖片輪播的實現方式,分別為(含超鏈接):1、《Android中使用ViewFlipper實現屏幕切換》2、《Android中使用ViewPager實
接到一個新的任務,對現有項目進行代碼混淆。之前對混淆有過一些了解,但是不夠詳細和完整,知道有些東西混淆起來還是比較棘手的。不過幸好目前的項目不是太復雜(針對混淆這塊來說)
本節引言: 本節要講解的Adapter類控件是ExpandableListView,就是可折疊的列表,它是ListView的子類, 在ListVi
Android Studio在打開的文件左側單擊鼠標右鍵,也能像Eclipse一樣設置顯示代碼行數,如圖1。但是這邊跟Eclipse有一個很大的區別,Eclipse設置後