最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android Handler移除Message詳解及實例代碼

 更新時間:2017年02月25日 15:04:28   作者:Jaivne_Kuang  
這篇文章主要介紹了Android Handler移除Message詳解及實例代碼的相關(guān)資料,需要的朋友可以參考下

Android Handler移除Message詳解

問題:

1.removeMessage(what)函數(shù)是否只能移除對應(yīng)what值的Message?

2.對于Delayed發(fā)送的Message,能否提前remove?

代碼測試:

package javine.k.testhandler; 
 
import android.app.Activity; 
import android.os.Bundle; 
import android.os.Handler; 
import android.os.HandlerThread; 
import android.os.Message; 
import android.util.Log; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.Button; 
 
public class TestHandlerActivity extends Activity implements OnClickListener { 
 
  private Button startBtn; 
  private Button endBtn; 
  public Handler threadHandler; //子線程Handler 
 
  private Handler mHandler = new Handler() { 
    public void handleMessage(android.os.Message msg) { 
      threadHandler.sendEmptyMessageDelayed(1, 2000); 
      Log.d("info", "handle main-thread message..."); 
    }; 
  }; 
 
  @Override 
  protected void onCreate(Bundle savedInstanceState) { 
    // TODO Auto-generated method stub 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 
 
    startBtn = (Button) findViewById(R.id.startButton); 
    endBtn = (Button) findViewById(R.id.endButton); 
    startBtn.setOnClickListener(this); 
    endBtn.setOnClickListener(this); 
 
    new Thread(new Runnable() { 
      @Override 
      public void run() { 
        HandlerThread handlerThread = new HandlerThread("handler"); 
        handlerThread.start(); 
        threadHandler = new Handler(handlerThread.getLooper()) { 
          @Override 
          public void handleMessage(Message msg) { 
            //mHandler.sendEmptyMessageDelayed(0, 2000);<span style="font-family: Arial, Helvetica, sans-serif;">         </span> 

<span style="white-space:pre"></span><pre name="code" class="java"><span style="white-space:pre">            </span>mHandler.sendEmptyMessageDelayed(1, 2000); 
Log.d("info", "handle sub-thread message...");}};}}).start();}@Overridepublic void onClick(View v) 
{// TODO Auto-generated method stubswitch (v.getId()) {case R.id.startButton: 
//開始發(fā)送消息mHandler.sendEmptyMessage(1);break;case R.id.endButton:
//移除主線程Handler的消息mHandler.removeMessages(1);break;default:break;}}}

測試結(jié)果:

        1. removeMassage(1)無法移除what=0的Message。

2. 在子線程中執(zhí)行完

<span></span><pre name="code" class="java"><span style="white-space:pre"> 
   </span>mHandler.sendEmptyMessageDelayed(1, 2000); 
Log.d("info", "handle sub-thread message...");

  之后,即可通過removeMesage(1)來移除消息,mHandler將不能接收到該條消息。

源碼分析:

1.Android如何移除一條Message?

查看源碼可知,Handler.removeMessage(int what)內(nèi)部調(diào)用MessageQueue.removeMessage(this, what, null)

查看MessageQueue的removeMessage方法如下:

void removeMessages(Handler h, int what, Object object) { 
    if (h == null) { 
      return; 
    } 
 
    synchronized (this) { 
      Message p = mMessages; 
 
      // Remove all messages at front. 
      while (p != null && p.target == h && p.what == what 
         && (object == null || p.obj == object)) { 
        Message n = p.next; 
        mMessages = n; 
        p.recycle(); 
        p = n; 
      } 
 
      // Remove all messages after front. 
      while (p != null) { 
        Message n = p.next; 
        if (n != null) { 
          if (n.target == h && n.what == what 
            && (object == null || n.obj == object)) { 
            Message nn = n.next; 
            n.recycle(); 
            p.next = nn; 
            continue; 
          } 
        } 
        p = n; 
      } 
    } 
  } 

篩選要移除的Message的條件是:target(handler),what,object

該函數(shù)分兩步來移除Message:

1).移除在前端的符合條件的Message

2).移除后面的符合條件的Message

2.為何延遲發(fā)送的Message在延遲時間到達之前就可以被移除?

Handler.sendEmptyMessageDelayed() ---調(diào)用---> sendMessageAtTime() -----調(diào)用---> enqueueMessage() ----調(diào)用MessageQueue.enqueueMessage()

實際進行處理的就是MessageQueue,源碼如下:

boolean enqueueMessage(Message msg, long when) { 
    if (msg.isInUse()) { 
      throw new AndroidRuntimeException(msg + " This message is already in use."); 
    } 
    if (msg.target == null) { 
      throw new AndroidRuntimeException("Message must have a target."); 
    } 
 
    synchronized (this) { 
      if (mQuitting) { 
        RuntimeException e = new RuntimeException( 
            msg.target + " sending message to a Handler on a dead thread"); 
        Log.w("MessageQueue", e.getMessage(), e); 
        return false; 
      } 
 
      msg.when = when; 
      Message p = mMessages; 
      boolean needWake; 
      if (p == null || when == 0 || when < p.when) { 
        // New head, wake up the event queue if blocked. 
        msg.next = p; 
        mMessages = msg; 
        needWake = mBlocked; 
      } else { 
        // Inserted within the middle of the queue. Usually we don't have to wake 
        // up the event queue unless there is a barrier at the head of the queue 
        // and the message is the earliest asynchronous message in the queue. 
        needWake = mBlocked && p.target == null && msg.isAsynchronous(); 
        Message prev; 
        for (;;) { 
          prev = p; 
          p = p.next; 
          if (p == null || when < p.when) { 
            break; 
          } 
          if (needWake && p.isAsynchronous()) { 
            needWake = false; 
          } 
        } 
        msg.next = p; // invariant: p == prev.next 
        prev.next = msg; 
      } 
 
      // We can assume mPtr != 0 because mQuitting is false. 
      if (needWake) { 
        nativeWake(mPtr); 
      } 
    } 
    return true; 
  } 

由上可知:MessageQueue會對需要延遲發(fā)送的Message排序,按照需要延遲的時間長短(when)。

即,雖然是延遲發(fā)送的消息,其實當(dāng)你調(diào)用發(fā)送函數(shù)之后,Message就已經(jīng)被添加到MessageQueue中去了。

感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!

相關(guān)文章

  • Android簽名文件轉(zhuǎn)化為pk8和pem的實現(xiàn)

    Android簽名文件轉(zhuǎn)化為pk8和pem的實現(xiàn)

    這篇文章主要介紹了Android簽名文件轉(zhuǎn)化為pk8和pem的實現(xiàn),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-03-03
  • Android viewpager在最后一頁滑動之后跳轉(zhuǎn)到主頁面的實例代碼

    Android viewpager在最后一頁滑動之后跳轉(zhuǎn)到主頁面的實例代碼

    這篇文章主要介紹了Android viewpager在最后一頁滑動之后跳轉(zhuǎn)到主頁面的實例代碼的相關(guān)資料,需要的朋友可以參考下
    2016-08-08
  • android 識別U盤以及讀寫文件的方法

    android 識別U盤以及讀寫文件的方法

    今天小編就為大家分享一篇android 識別U盤以及讀寫文件的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-08-08
  • Android開發(fā)之splash界面下詳解及實例

    Android開發(fā)之splash界面下詳解及實例

    這篇文章主要介紹了 Android開發(fā)之splash界面下詳解及實例的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • Android 圖文詳解Binder進程通信底層原理

    Android 圖文詳解Binder進程通信底層原理

    Android系統(tǒng)中,多進程間的通信都是依賴于底層Binder IPC機制,Binder機制是一種RPC方案。例如:當(dāng)進程A中的Activity與進程B中的Service通信時,就使用了binder機制
    2021-10-10
  • Android實現(xiàn)帶附件的郵件發(fā)送功能

    Android實現(xiàn)帶附件的郵件發(fā)送功能

    這篇文章主要介紹了Android實現(xiàn)帶附件的郵件發(fā)送功能的相關(guān)資料,android發(fā)送郵件有兩種方式,本文重點介紹基于JMail實現(xiàn)郵件發(fā)送功能,感興趣的小伙伴們可以參考一下
    2016-01-01
  • Android 實現(xiàn)懸浮窗功能

    Android 實現(xiàn)懸浮窗功能

    這篇文章主要介紹了Android 實現(xiàn)懸浮窗功能,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-09-09
  • Android實現(xiàn)獲取短信驗證碼并自動填寫功能

    Android實現(xiàn)獲取短信驗證碼并自動填寫功能

    這篇文章主要為大家詳細(xì)介紹了Android實現(xiàn)獲取短信驗證碼并自動填寫功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • Android存儲訪問框架的使用小結(jié)

    Android存儲訪問框架的使用小結(jié)

    這篇文章主要介紹了Android存儲訪問框架的使用,存儲訪問框架API和MediaStore?API的差異,在于存儲訪問框架API,是基于系統(tǒng)文件選擇框的,用戶選擇了文件,那么相當(dāng)于授權(quán)了,?可以訪問所有類型的文件,需要的朋友可以參考下
    2022-01-01
  • Android APK反編譯圖文教程

    Android APK反編譯圖文教程

    學(xué)會反編譯比較關(guān)鍵,也是我們美化必須掌握技術(shù),學(xué)會反編譯也是實現(xiàn)制作ROM的起步,ROM高手必然是反編譯高手這里有必要說一下,教程只是給你一個動手的那一個蹺板,教程不是萬能的,給了你基礎(chǔ)與啟發(fā),最重要的是我們能夠自主的進行創(chuàng)新與思考
    2016-04-04

最新評論

林芝县| 博湖县| 五原县| 亚东县| 清新县| 滦平县| 岗巴县| 福安市| 江口县| 壶关县| 天台县| 清新县| 黔西| 双桥区| 屏边| 仪征市| 揭阳市| 福清市| 淄博市| 聊城市| 信丰县| 吴江市| 锡林郭勒盟| 锡林郭勒盟| 弋阳县| 泰顺县| 高邑县| 罗甸县| 吴江市| 蒲江县| 东宁县| 云安县| 陵水| 延长县| 明溪县| 金寨县| 梅州市| 钦州市| 陇川县| 侯马市| 吉安县|