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

OnSharedPreferenceChangeListener詳解及出現(xiàn)不觸發(fā)解決辦法

 更新時(shí)間:2016年08月31日 16:24:43   作者:技術(shù)小黑屋  
本文主要介紹 Android OnSharedPreferenceChangeListener的知識(shí),在Android應(yīng)用開發(fā)過(guò)程中會(huì)遇到監(jiān)聽器不觸發(fā)事件問(wèn)題,這里介紹了相應(yīng)的解決辦法

之前使用OnSharedPreferenceChangeListener,遇到了點(diǎn)小問(wèn)題,就是有些時(shí)候OnSharedPreferenceChangeListener沒(méi)有被觸發(fā)。最近花了點(diǎn)時(shí)間研究了一下,小做整理。本文將會(huì)介紹監(jiān)聽器不被觸發(fā)的原因,解決方法,以及其中隱含的一些技術(shù)細(xì)節(jié)。

問(wèn)題再現(xiàn)

OnSharedPreferenceChangeListener是Android中SharedPreference文件發(fā)生變化的監(jiān)聽器。通常我們想要進(jìn)行監(jiān)聽,會(huì)實(shí)現(xiàn)如下的代碼。

protected void onCreate(Bundle savedInstanceState) {
 PreferenceManager.getDefaultSharedPreferences(getApplicationContext())
  .registerOnSharedPreferenceChangeListener(new OnSharedPreferenceChangeListener() {
  @Override
  public void onSharedPreferenceChanged(
   SharedPreferences sharedPreferences, String key) {
   Log.i(LOGTAG, "testOnSharedPreferenceChangedWrong key =" + key);
  }
 });
}

這種寫法看上去沒(méi)有什么問(wèn)題,而且很多時(shí)候開始幾次onSharedPreferenceChanged方法也可以被調(diào)用。但是過(guò)一段時(shí)間(簡(jiǎn)單demo不容易出現(xiàn),但是使用DDMS中的gc會(huì)立刻導(dǎo)致接下來(lái)的問(wèn)題),你會(huì)發(fā)現(xiàn)前面的方法突然不再被調(diào)用,進(jìn)而影響到程序的處理。

原因剖析

簡(jiǎn)而言之,就是你注冊(cè)的監(jiān)聽器被移除掉了。
首先我們先了解一下registerOnSharedPreferenceChangeListener注冊(cè)的實(shí)現(xiàn)。

private final WeakHashMap<OnSharedPreferenceChangeListener, Object> mListeners =
   new WeakHashMap<OnSharedPreferenceChangeListener, Object>();
//some code goes here
public void More ...registerOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) {
 synchronized(this) {
  mListeners.put(listener, mContent);
 }
}

從上面的代碼可以得知,一個(gè)OnSharedPreferenceChangeListener對(duì)象實(shí)際上是放到了一個(gè)WeakHashMap的容器中,執(zhí)行完示例中的onCreate方法,這個(gè)監(jiān)聽器對(duì)象很快就會(huì)成為垃圾回收的目標(biāo),由于放在WeakHashMap中作為key不會(huì)阻止垃圾回收,所以當(dāng)監(jiān)聽器對(duì)象被回收之后,這個(gè)監(jiān)聽器也會(huì)從mListeners中移除。所以就造成了onSharedPreferenceChanged不會(huì)被調(diào)用。

關(guān)于WeakHashMap相關(guān),請(qǐng)閱讀譯文:理解Java中的弱引用進(jìn)而更多了解。

如何解決

改為對(duì)象成員變量(推薦)

將監(jiān)聽器作為Activity的一個(gè)成員變量,在Activity的onResume進(jìn)行注冊(cè),在onPause時(shí)進(jìn)行注銷。推薦在這兩個(gè)Activity生命周期中進(jìn)行處理,尤其是當(dāng)SharedPreference值發(fā)生變化后,對(duì)Activity展示的UI進(jìn)行處理操作的情況。這種方法是最推薦的解決方案。

private OnSharedPreferenceChangeListener mListener = new OnSharedPreferenceChangeListener() {

 @Override
 public void onSharedPreferenceChanged(
  SharedPreferences sharedPreferences, String key) {
  Log.i(LOGTAG, "instance variable key=" + key);
 }
};

@Override
protected void onResume() {
 PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).registerOnSharedPreferenceChangeListener(mListener);
 super.onResume();
}

@Override
protected void onPause() {
 PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).unregisterOnSharedPreferenceChangeListener(mListener);
 super.onPause();
}

改為靜態(tài)變量(不推薦)

如下,將一個(gè)指向匿名的內(nèi)部類對(duì)象的變量sListener使用static修飾,這個(gè)內(nèi)部類對(duì)象則不會(huì)持有外部類的引用。
但是這種做法并不推薦,因?yàn)橐粋€(gè)靜態(tài)變量和與外部實(shí)例不相關(guān),我們很難和外部實(shí)例進(jìn)行一些操作。

private static OnSharedPreferenceChangeListener sListener = new OnSharedPreferenceChangeListener() {
 @Override
 public void onSharedPreferenceChanged(
  SharedPreferences sharedPreferences, String key) {
  Log.i(LOGTAG, "static variable key=" + key);
 }
};

為什么這樣設(shè)計(jì)

可能會(huì)有人認(rèn)為這是系統(tǒng)設(shè)計(jì)的貓膩或者bug,其實(shí)不然,這正是Android設(shè)計(jì)人員的高明之處。

正如我們示例的代碼一樣,將一個(gè)(隱式的)局部變量添加到監(jiān)聽器容器中,如果該容器只是一個(gè)普通的HashMap,這樣會(huì)導(dǎo)致內(nèi)存泄露,因?yàn)樵撊萜鬟€有局部變量指向的對(duì)象,該對(duì)象又隱式持有外部Activity的對(duì)象,導(dǎo)致Activity無(wú)法被銷毀。關(guān)于非靜態(tài)內(nèi)部類持有隱式持有外部類引用,請(qǐng)參考細(xì)話Java:”失效”的private修飾符

除此之外,因?yàn)榫植孔兞繜o(wú)法在其所在方法外部訪問(wèn),這樣就導(dǎo)致了我們只可以使用方法中使用局部變量就行注冊(cè),在合適的時(shí)機(jī)卻無(wú)法使用局部變量進(jìn)行注銷。

以上就是對(duì) Android OnSharedPreferenceChangeListener的介紹,以及出現(xiàn)問(wèn)題解決辦法,謝謝大家對(duì)本站的支持!

相關(guān)文章

  • Android中方法數(shù)超限問(wèn)題與啟動(dòng)優(yōu)化詳解

    Android中方法數(shù)超限問(wèn)題與啟動(dòng)優(yōu)化詳解

    這篇文章主要給大家介紹了Android中方法數(shù)超限問(wèn)題與啟動(dòng)優(yōu)化的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-11-11
  • 使用ViewPager實(shí)現(xiàn)android軟件使用向?qū)Чδ軐?shí)現(xiàn)步驟

    使用ViewPager實(shí)現(xiàn)android軟件使用向?qū)Чδ軐?shí)現(xiàn)步驟

    現(xiàn)在的大部分android軟件,都是使用說(shuō)明,就是第一次使用該軟件時(shí),會(huì)出現(xiàn)向?qū)?,可以左右滑?dòng),然后就進(jìn)入應(yīng)用的主界面了,下面我們就實(shí)現(xiàn)這個(gè)功能
    2013-11-11
  • Android組合控件自定義標(biāo)題欄

    Android組合控件自定義標(biāo)題欄

    這篇文章主要為大家詳細(xì)介紹了Android組合控件自定義標(biāo)題欄,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-11-11
  • Android自定義View原理(實(shí)戰(zhàn))

    Android自定義View原理(實(shí)戰(zhàn))

    這篇文章主要介紹了Android自定義View原理,由于Android系統(tǒng)內(nèi)置的View不滿足我們的業(yè)務(wù)需求,變產(chǎn)生了需要自定義View的原因,關(guān)于自定義詳情,需要的小伙伴可以參考下面文章具體詳情
    2022-05-05
  • Android 設(shè)置主題實(shí)現(xiàn)點(diǎn)擊波紋效果的示例

    Android 設(shè)置主題實(shí)現(xiàn)點(diǎn)擊波紋效果的示例

    本篇文章主要介紹了Android 設(shè)置主題實(shí)現(xiàn)點(diǎn)擊波紋效果的示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-11-11
  • Android 四種獲取屏幕寬度的方法總結(jié)

    Android 四種獲取屏幕寬度的方法總結(jié)

    這篇文章主要介紹了Android 四種獲取屏幕寬度的方法總結(jié)的相關(guān)資料,這里對(duì)四種方法進(jìn)行了一一介紹,需要的朋友可以參考下
    2017-01-01
  • Retrofit網(wǎng)絡(luò)請(qǐng)求框架之注解解析和動(dòng)態(tài)代理

    Retrofit網(wǎng)絡(luò)請(qǐng)求框架之注解解析和動(dòng)態(tài)代理

    這篇文章主要介紹了Retrofit網(wǎng)絡(luò)請(qǐng)求框架之注解解析和動(dòng)態(tài)代理,Retrofit是目前Android平臺(tái)上比較流行的網(wǎng)絡(luò)請(qǐng)求框架之一,它提供了一種簡(jiǎn)潔、靈活的方式來(lái)處理HTTP請(qǐng)求和響應(yīng)
    2023-03-03
  • 史上最全Android build.gradle配置詳解(小結(jié))

    史上最全Android build.gradle配置詳解(小結(jié))

    這篇文章主要介紹了史上最全Android build.gradle配置詳解(小結(jié)),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-04-04
  • 詳解Android自定義權(quán)限使用總結(jié)

    詳解Android自定義權(quán)限使用總結(jié)

    這篇文章主要介紹了詳解Android自定義權(quán)限使用總結(jié),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-07-07
  • Android性能優(yōu)化之弱網(wǎng)優(yōu)化詳解

    Android性能優(yōu)化之弱網(wǎng)優(yōu)化詳解

    這篇文章主要為大家介紹了Android性能優(yōu)化之弱網(wǎng)優(yōu)化示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10

最新評(píng)論

恩平市| 环江| 岳阳县| 江门市| 龙口市| 龙游县| 廊坊市| 织金县| 霞浦县| 无极县| 分宜县| 行唐县| 宁化县| 株洲县| 阿坝| 崇义县| 西安市| 仁化县| 乌拉特前旗| 营口市| 建阳市| 岳阳县| 景洪市| 新竹市| 读书| 偏关县| 瓦房店市| 巨野县| 浦江县| 辽中县| 宽甸| 斗六市| 铜梁县| 福鼎市| 潍坊市| 杨浦区| 青海省| 株洲县| 新河县| 灵川县| 大兴区|