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

Android中檢測(cè)當(dāng)前是否為主線程最可靠的解決方法

 更新時(shí)間:2015年01月17日 10:28:21   投稿:junjie  
這篇文章主要介紹了Android中檢測(cè)當(dāng)前是否為主線程最可靠的解決方法,本文先是給出了最可靠的方法,然后給出了幾個(gè)實(shí)驗(yàn)例子,需要的朋友可以參考下

如果在Android中判斷某個(gè)線程是否是主線程?對(duì)于這個(gè)問題,你可能說根據(jù)線程的名字,當(dāng)然這個(gè)可以解決問題,但是這樣是最可靠的么?萬一某天Google一下子將線程的名字改稱其他神馬東西呢。

方法揭曉

下面的方法是最可靠的解決方案。

復(fù)制代碼 代碼如下:

public static boolean isInMainThread() {
      return Looper.myLooper() == Looper.getMainLooper();
}

實(shí)際上,寫到這里就基本解決了文章標(biāo)題的問題了,但是僅僅研究到這里太膚淺了,刨的不夠深,所以需要繼續(xù),希望你也可以繼續(xù)讀下去。

刨根問底

實(shí)驗(yàn)一

好,現(xiàn)在,我們對(duì)這個(gè)穩(wěn)定的方法做一些測(cè)試,首先,下面的方法會(huì)增加一些調(diào)試打印信息。

復(fù)制代碼 代碼如下:

private boolean isInMainThread() {
    Looper myLooper = Looper.myLooper();
  Looper mainLooper = Looper.getMainLooper();
  Log.i(LOGTAG, "isInMainThread myLooper=" + myLooper
      + ";mainLooper=" + mainLooper);
  return myLooper == mainLooper;
}

好,然后我們?cè)谥骶€程中運(yùn)行一個(gè)測(cè)試,調(diào)用上述方法。比如我們這樣調(diào)用。

復(fù)制代碼 代碼如下:

Log.i(LOGTAG, "testInMainThread inMainThread=" + isInMainThread());

OK,我們看一下輸出日志。驗(yàn)證OK。

復(fù)制代碼 代碼如下:

I/TestInMainThread(32028): isInMainThread myLooper=Looper{40d35ef8};mainLooper=Looper{40d35ef8}
I/TestInMainThread(32028): testInMainThread inMainThread=true

實(shí)驗(yàn)二

現(xiàn)在我們繼續(xù)在一個(gè)沒有消息循環(huán)的非主線程,進(jìn)行驗(yàn)證。

復(fù)制代碼 代碼如下:

new Thread() {
    @Override
    public void run() {
      Log.i(LOGTAG, "testIn NOT in MainThread isMainThread="
          + isInMainThread());
      super.run();
  }
}.start();

正如我們看到的如下日志結(jié)果,主線程的Looper(翻譯成循環(huán)泵,不是很好聽)已經(jīng)被初始化賦值。但是我們新創(chuàng)建的線程的looper還是null。這是因?yàn)锳ndroid中的線程默認(rèn)沒有一個(gè)和它綁定了的消息循環(huán)(Threads by default do not have a message loop associated with them. Of course, the method works)

復(fù)制代碼 代碼如下:

I/TestInMainThread(32028): isInMainThread myLooper=null;mainLooper=Looper{40d35ef8}
I/TestInMainThread(32028): testIn NOT in MainThread isMainThread=false

實(shí)驗(yàn)三

繼續(xù),我們創(chuàng)建一個(gè)綁定了消息循環(huán)的線程,根據(jù)Android開發(fā)者文檔說明,以下是一個(gè)典型的創(chuàng)建消息循環(huán)線程的示例,使用單獨(dú)prepare()方法和loop()方法來創(chuàng)建一個(gè)綁定到Looper的Handler。

復(fù)制代碼 代碼如下:

new Thread() {
  private Handler mHandler;
  @Override
  public void run() {
      Looper.prepare();
      mHandler = new Handler() {
            public void handleMessage(Message msg) {
              // process incoming messages here
          }
      };
      Log.i(LOGTAG, "testInNonMainLooperThread isMainThread="
            + isInMainThread());
      Looper.loop();
  }
     
}.start();

OK,現(xiàn)在再次檢查以下日志,

復(fù)制代碼 代碼如下:

I/TestInMainThread(32028): isInMainThread myLooper=Looper{40d72c58};mainLooper=Looper{40d35ef8}
I/TestInMainThread(32028): testInNonMainLooperThread isMainThread=false

兩個(gè)Looper都被初始化賦值了,但是他們是不同的對(duì)象。

原理發(fā)掘

但是,這是為什么呢,這里面有什么奧秘呢? 好,讓我們看以下Looper.class

復(fù)制代碼 代碼如下:

// sThreadLocal.get() will return null unless you've called prepare().
static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
private static Looper sMainLooper;  // guarded by Looper.class

/**
 * Initialize the current thread as a looper, marking it as an
 * application's main looper. The main looper for your application
 * is created by the Android environment, so you should never need
 * to call this function yourself.  See also: {@link #prepare()}
 */
public static void prepareMainLooper() {
    prepare(false);
    synchronized (Looper.class) {
        if (sMainLooper != null) {
            throw new IllegalStateException("The main Looper has already been prepared.");
        }
        sMainLooper = myLooper();
    }
}

private static void prepare(boolean quitAllowed) {
    if (sThreadLocal.get() != null) {
        throw new RuntimeException("Only one Looper may be created per thread");
    }
    sThreadLocal.set(new Looper(quitAllowed));
}

/**
 * Return the Looper object associated with the current thread. 
 * Returns null if the calling thread is not associated with a Looper.
 */
public static Looper myLooper() {
    return sThreadLocal.get();
}

 /** Returns the application's main looper, which lives in the main thread of the application.
 */
public static Looper getMainLooper() {
    synchronized (Looper.class) {
        return sMainLooper;
    }
}

對(duì)于主線程來說,prepareMainLooper這個(gè)方法會(huì)被Android運(yùn)行環(huán)境調(diào)用,而不是程序顯式調(diào)用。通過這個(gè)方法,主線程的looper被創(chuàng)建,并且將對(duì)象引用傳遞給sMainLooper。所以保證了主線程myLooper()獲取到的引用和getMainLooper()獲取到的都是同一個(gè)引用。

對(duì)于沒有消息循環(huán)的非主線程,默認(rèn)的當(dāng)前線程的looper是null,因?yàn)槟銖膩頉]有手動(dòng)地調(diào)用prepare(),所以它和主線程的looper不一樣。

對(duì)于綁定了消息循環(huán)的非主線程,當(dāng)調(diào)用Looper.prepare方法時(shí),主線程的Looper已經(jīng)由Android運(yùn)行環(huán)境創(chuàng)建,當(dāng)調(diào)用prepare方法后,綁定到這個(gè)非主線程的looper被創(chuàng)建,當(dāng)然,這不可能和主線程的Looper一樣。

綜上所述,這個(gè)方法是可靠的。

相關(guān)文章

  • Android仿360市場(chǎng)下載按鈕的實(shí)現(xiàn)方法

    Android仿360市場(chǎng)下載按鈕的實(shí)現(xiàn)方法

    這篇文章主要給大家介紹了關(guān)于利用Android實(shí)現(xiàn)360市場(chǎng)下載按鈕效果的方法,文中給出了詳細(xì)的示例代碼供大家參考學(xué)習(xí),并在文末給出了源碼供大家下載,需要的朋友們下面跟著小編一起來學(xué)習(xí)學(xué)習(xí)吧。
    2017-05-05
  • Android控件BottomSheet實(shí)現(xiàn)底邊彈出選擇列表

    Android控件BottomSheet實(shí)現(xiàn)底邊彈出選擇列表

    這篇文章主要介紹了Android控件BottomSheet實(shí)現(xiàn)底邊彈出選擇列表,比較常用的選擇條件或跳轉(zhuǎn)方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • Android第三方文件選擇器aFileChooser使用方法詳解

    Android第三方文件選擇器aFileChooser使用方法詳解

    這篇文章主要介紹了Android第三方文件選擇器aFileChooser的使用方法詳解,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • Android 通過Intent使用Bundle傳遞對(duì)象詳細(xì)介紹

    Android 通過Intent使用Bundle傳遞對(duì)象詳細(xì)介紹

    這篇文章主要介紹了Android 通過Intent使用Bundle傳遞對(duì)象詳細(xì)介紹的相關(guān)資料,并附實(shí)例代碼講解,具有一定的參考價(jià)值,需要的朋友可以參考下
    2016-11-11
  • Android 為L(zhǎng)istView添加分段標(biāo)頭的方法

    Android 為L(zhǎng)istView添加分段標(biāo)頭的方法

    下面小編就為大家?guī)硪黄狝ndroid 為L(zhǎng)istView添加分段標(biāo)頭的方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-04-04
  • Kotlin中使用Dagger2可能遇到的坑解決

    Kotlin中使用Dagger2可能遇到的坑解決

    在Android上創(chuàng)建去耦以及容易測(cè)試代碼的幾乎每位遲早都要訴諸Dagger,在Kotlin中設(shè)置Dagger有一些不同,所以下面這篇文章主要給大家介紹了關(guān)于Kotlin中使用Dagger2可能遇到的坑的解決方法,需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-11-11
  • android Listview模擬聊天界面

    android Listview模擬聊天界面

    這篇文章主要為大家詳細(xì)介紹了android Listview模擬聊天界面的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-03-03
  • Android實(shí)現(xiàn)qq列表式的分類懸浮提示

    Android實(shí)現(xiàn)qq列表式的分類懸浮提示

    工作中遇到了一個(gè)需求,讓應(yīng)用中的一個(gè)列表按照分類顯示,并且能提示當(dāng)前是在哪個(gè)分類,度娘了一番,參考了前輩們的博客后實(shí)現(xiàn)了,現(xiàn)在分享給大家,有需要的可以參考借鑒。
    2016-09-09
  • 詳解Android應(yīng)用開發(fā)--MP3音樂播放器代碼實(shí)現(xiàn)(一)

    詳解Android應(yīng)用開發(fā)--MP3音樂播放器代碼實(shí)現(xiàn)(一)

    這篇文章主要介紹了詳解Android應(yīng)用開發(fā)--MP3音樂播放器代碼實(shí)現(xiàn)(一),非常具有實(shí)用價(jià)值,需要的朋友可以參考下 。
    2017-01-01
  • Android自定義ViewGroup嵌套與交互實(shí)現(xiàn)幕布全屏滾動(dòng)

    Android自定義ViewGroup嵌套與交互實(shí)現(xiàn)幕布全屏滾動(dòng)

    這篇文章主要為大家介紹了Android自定義ViewGroup嵌套與交互實(shí)現(xiàn)幕布全屏滾動(dòng)效果示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01

最新評(píng)論

河南省| 吉林省| 宁远县| 涟水县| 淮阳县| 蒙自县| 峨眉山市| 呼伦贝尔市| 永和县| 扶沟县| 凌云县| 柯坪县| 和平区| 明光市| 宜昌市| 四川省| 昌宁县| 尉犁县| 辉县市| 濮阳县| 乌恰县| 兴宁市| 乐清市| 平果县| 锡林浩特市| 张家界市| 和静县| 兴山县| 水城县| 和林格尔县| 郸城县| 台中市| 耿马| 吉首市| 巴青县| 资中县| 东辽县| 洛阳市| 无为县| 清河县| 孝感市|