編輯:Android開發教程
之前也是由於周末通宵看TI3比賽,一直沒找到時間寫博客,導致已經有好久沒更新了。慚愧!後面還會 恢復進度,盡量保證每周都寫吧。這裡也是先恭喜一下來自瑞典的Alliance戰隊奪得了TI3的冠軍,希望明年 中國戰隊能夠虎起!
開始進入正題,我們都知道,Android UI是線程不安全的,如果在子線程中嘗試 進行UI操作,程序就有可能會崩潰。相信大家在日常的工作當中都會經常遇到這個問題,解決的方案應該也 是早已爛熟於心,即創建一個Message對象,然後借助Handler發送出去,之後在Handler的handleMessage() 方法中獲得剛才發送的Message對象,然後在這裡進行UI操作就不會再出現崩潰了。
這種處理方式被 稱為異步消息處理線程,雖然我相信大家都會用,可是你知道它背後的原理是什麼樣的嗎?今天我們就來一 起深入探究一下Handler和Message背後的秘密。
首先來看一下如何創建Handler對象。你可能 會覺得挺納悶的,創建Handler有什麼好看的呢,直接new一下不就行了?確實,不過即使只是簡單new一下, 還是有不少地方需要注意的,我們嘗試在程序中創建兩個Handler對象,一個在主線程中創建,一個在子線程 中創建,代碼如下所示:
public class MainActivity extends Activity { private Handler handler1; private Handler handler2; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); handler1 = new Handler(); new Thread(new Runnable() { @Override public void run() { handler2 = new Handler(); } }).start(); } }
如果現在運行一下程序,你會發現,在子線程中創建的Handler是會導致程序崩潰的,提示的錯誤 信息為 Can't create handler inside thread that has not called Looper.prepare() 。說是不能在 沒有調用Looper.prepare() 的線程中創建Handler,那我們嘗試在子線程中先調用一下Looper.prepare()呢 ,代碼如下所示:
new Thread(new Runnable() { @Override public void run() { Looper.prepare(); handler2 = new Handler(); } }).start();
果然這樣就不會崩潰了,不過只滿足於此顯然是不夠的,我們來看下Handler的源碼, 搞清楚為什麼不調用Looper.prepare()就不行呢。Handler的無參構造函數如下所示:
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; }
可以看到,在第10行調用了Looper.myLooper()方法獲取了一個Looper對象,如果Looper對象為空 ,則會拋出一個運行時異常,提示的錯誤正是 Can't create handler inside thread that has not called Looper.prepare()!那什麼時候Looper對象才可能為空呢?這就要看看Looper.myLooper()中的代碼 了,如下所示:
public static final Looper myLooper() { return (Looper)sThreadLocal.get(); }
新浪微博有一部分json數據如下,你會發現這是個數組,但是數組沒有key,數組中的對象也沒有key。怎麼解析呢?fastjson遇到這種無名數組套無名對象也會報異常。所以
一、Service簡介Service是android 系統中的四大組件之一(Activity、Service、BroadcastReceiver、 ContentProv
Android平台, 可以使用本地資源, 也可以使用系統資源;使用靜態R類訪問資源, R類中包含一個靜態子類, R類中每一個子類都把它的相關資源表示為變量的形式;資源表被
使用TimePicker,可以讓用戶去選擇一天中的事件,包括24小時制和AM/PM制。下面的例子將會展示如何 使用TimePicker。1. 創建一個工程:BasicVi