Handler系列之使用

  做爲一個Android開發者,咱們確定熟悉並使用過Handler機制。最經常使用的使用場景是「在子線程更新ui」,實際上咱們知道上面的說話是錯誤的。由於Android中只有主線程才能更新ui,那麼當咱們在子線程獲得更新ui通知的時候怎麼辦?此刻Handler存在的意義就體現出來了。咱們在子線程用handler發送一個消息通知給主線程,而後讓主線程更新ui,這樣問題就解決了。下面讓咱們看看handler怎麼使用的吧!!!ide

 

<一>Handler的基本使用源碼分析

public class HandlerActivity extends Activity 

    private final String TAG = "HandlerActivity.class";

    private Handler mHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            Log.d(TAG,"arg1------"+msg.arg1); --- 1
            Log.d(TAG,"arg2------"+msg.arg2); --- 2
            Person person = (Person) msg.obj;
            if (person != null ){
                Log.d(TAG,"person.age------"+person.getAge()); --- 555
                Log.d(TAG,"person.name------"+person.getName()); --- Liu
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_handler);

        new Thread(new Runnable() {
            @Override
            public void run() {
                /**
                 * 傳遞簡單Integer類型消息
                 */
                Message message = new Message();
                message.arg1 = 1;
                message.arg2 = 2;

                /**
                 * 傳遞複雜消息
                 */
                Person person = new Person();
                person.setAge(555);
                person.setName("Liu");
                message.obj = person;

                mHandler.sendMessage(message);
            }
        }).start();
    }
}

 

    由上可見,咱們在使用handler發送消息的時候,而且能夠傳遞一些數據信息。在傳遞消息的時候咱們用到了Message,並經過new的方式實例化。下面讓咱們看一下獲取Message的第二種方法。ui

 

<二>獲取Message的另外一種方式以及源碼分析this

                Message message = mHandler.obtainMessage();
                message.sendToTarget();

同第一種方式相比,獲取Message和發送Message的方法都不同了。其實若是跟進源碼你能夠發現,這種方式其實就是把第一種方式封裝了一下,跟隨我看一下源碼吧!!!spa

首先先來看一下獲取Message的方法,入口是在Handler的obtainMessage方法:線程

    public final Message obtainMessage(){
        return Message.obtain(this);
    }

繼續跟Message的obtain方法code

   public static Message obtain(Handler h) {
        Message m = obtain();
        m.target = h;
        return m;
    }

  在這裏咱們看到有兩步操做,一個是調用本類的obtain方法,另外一個是將Handler引用賦值給Message的target對象。接下來看一下obtain方法對象

    public static Message obtain() {
        synchronized (sPoolSync) {
            if (sPool != null) {
                Message m = sPool;
                sPool = m.next;
                m.next = null;
                m.flags = 0; // clear in-use flag
                sPoolSize--;
                return m;
            }
        }
        return new Message();
    }

  咱們看到最後實例化的方式和第一種意義,都是經過new的方法。好了!!!消息獲取到了,下面看看它是怎麼發送消息的吧!!!,直接看Message的sendToTarget方法。blog

    public void sendToTarget() {
        target.sendMessage(this);
    }

還記得咱們以前給target賦值的是什麼嗎?沒錯,就是handler,因此第二種方式其實就是對第一種方式的封裝。隊列

 

<三>Handler的七種發信息的方法

  上面咱們是經過Handler的sendMessage(Message msg)發送消息的,下面在來看看Handler的其餘六種發送消息方式。這六種方法又分爲兩類:

    (一) 攜帶消息Message

      1> sendMessageAtTime(Message msg, long uptimeMillis)     在指定時間發送消息到隊列

      2> sendMessageAtFrontOfQueue(Message msg)  當即發送Message到隊列,並且是放在隊列的最前面

      3> sendMessageDelayed(Message msg, long delayMillis)  延遲delayMillis時間發送消息到隊列

    (二) 不攜帶消息Message

      4> sendEmptyMessage(int what)   發送空消息到隊列

      5> sendEmptyMessageAtTime(int what, long uptimeMillis)  在指定時間發送空消息到隊列

      6> sendEmptyMessageDelayed(int what, long delayMillis) 延遲delayMillis發送空消息到隊列

  跟蹤源碼你會發現,這幾個方法最終調用的都是 sendMessageAtTime,以下圖:

  

相關文章
相關標籤/搜索