Handler詳解系列(五)——Handler的post()方法詳解,handlerpost
MainActivity如下:
package cc.testui1;import android.os.Bundle;import android.os.Handler;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.TextView;import android.app.Activity;/** * Demo描述: * 在子線程中更改UI的方式一 * * 在子線程中利用主線程的Handler的post()方法 * 更改UI這個在子線程中sendMessage()原理和形式都很類似. * * 詳細分析: * 在Handler調用其post()方法時,方法的調用順序如下: * Handler的post()方法--->Handler的sendMessageDelayed()方法---> * Handler的sendMessageAtTime()方法. * 至此又回到了前面熟悉的sendMessageAtTime() * * 詳細的代碼如下: * public final boolean post(Runnable r){ * return sendMessageDelayed(getPostMessage(r), 0); * } * * * private final Message getPostMessage(Runnable r) { * Message m = Message.obtain(); * m.callback = r; * return m; * } * * * public final boolean sendMessageDelayed(Message msg, long delayMillis){ * if (delayMillis < 0) { * delayMillis = 0; * } * return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis); * } * * * 在這個詳細的過程中可以看到在post(Runnable r)中利用該方法的輸入參數r調用了getPostMessage(r) * 將r封裝成了一個Message. * 重點是getPostMessage(r)方法中的 m.callback = r * 將r賦值給了Message的callback!!!!! * * 回顧一下出隊時調用的dispatchMessage()方法 * 下面接著看Handler的dispatchMessage(Message msg)方法: * public void dispatchMessage(Message msg) { * //1 message的callback * if (msg.callback != null) { * handleCallback(msg); * } else { * //2 handler的callback * if (mCallback != null) { * if (mCallback.handleMessage(msg)) { * return; * } * } * //3 Handler的handleMessage() * handleMessage(msg); * } * } * * * 在1處就判斷出該Message的callback不為null,於是調用 handleCallback(msg); * 詳細代碼如下: * private static void handleCallback(Message message) { * message.callback.run(); * } * 該方法比較簡單:就是直接調用post(Runnable r)的輸入參數(Runnable對象)的run()方法. * * 小結: * 1 在子線程中利用post(Runnable r)更新UI,原理和sendMessage()類似. * 2 注意: * 在下面的樣本中mHandler是主線程的Handler. * 所以“在子線程中利用post(Runnable r)更新UI”這個說法不是特別準確. * 確切地說還是在子線程中發送了訊息到主線程的訊息佇列從而更新了UI. * 3 調用post(Runnable r)不會開啟一個新的線程,UI的更新是在主線程中完成的!!!!!!!!!! * 在下面的樣本中可在兩個地方輸出線程ID發現兩個值是一樣的. * 所以在post方法中勿做耗時操作 * * * * 參考資料: * http://blog.csdn.net/guolin_blog/article/details/9991569 * Thank you very much */public class MainActivity extends Activity { private TextView mTextView; private Handler mHandler; private Button mButton;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);init();} private void init(){ mHandler=new Handler(); mTextView=(TextView) findViewById(R.id.textView); mButton=(Button) findViewById(R.id.button); mButton.setOnClickListener(new OnClickListenerImpl()); System.out.println("UI線程ID="+Thread.currentThread().getId()); } private class OnClickListenerImpl implements OnClickListener{@Overridepublic void onClick(View v) {new Thread(){ public void run() { mHandler.post(new Runnable() {@Overridepublic void run() {System.out.println("post(Runnable r)裡的run()方法中線程ID="+Thread.currentThread().getId());mTextView.setText("My number is 007");}}); }; }.start();} }}
main.xml如下:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="test" android:layout_centerHorizontal="true" android:layout_marginTop="50dip" /> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button" android:layout_centerHorizontal="true" android:layout_marginTop="120dip" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="測試在子線程中更新UI" android:layout_centerInParent="true" /></RelativeLayout>
有關Android的Handler的post方法
Android裡邊確實是有這個Handler類,但是你這裡是自己定義了一個Handler類,所以你用的是自己設計的Handler類,所以會報出上面的錯
android中Handler的post方法的作用是什
一般來說在背景工作執行緒中執行耗時任務,當任務完成時,會返回UI線程,一般是更新UI。這時有兩種方法可以達到目的。
一種是handler.sendMessage。發一個訊息,再根據訊息,執行相關任務代碼。
另一種是handler.post(r)。r是要執行的任務代碼。意思就是說r的代碼實際是在UI線程執行的。可以寫更新UI的代碼。(背景工作執行緒是不能更新UI的)