欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android垃圾回收機制解決內(nèi)存泄露問題

 更新時間:2016年02月04日 10:28:21   投稿:lijiao  
這篇文章主要介紹了Android垃圾回收機制解決內(nèi)存泄露問題的相關資料,需要的朋友可以參考下

在android編碼中,會有一些簡便的寫法和編碼習慣,會導致我們的代碼有很多內(nèi)存泄露的問題,在這里做一個已知錯誤的總結:
1、編寫單例的時候常出現(xiàn)的錯誤。

錯誤方式:

 public class Foo{

   private static Foo foo;

   private Context mContext;

   private Foo(Context mContext){

    this.mContext = mContext;

   }

   // 普通單例,非線程安全

   public static Foo getInstance(Context mContext){

    if(foo == null)

     foo = new Foo(mContext);

    return foo;

   }

   public void otherAction(){

    mContext.xxxx();

    ….

   }

  }

錯誤原因:

     如果我們在Activity A中或者其他地方使用Foo.getInstance()時,我們總是會順手寫一個『this』或者『mContext』(這個變量也是指向this)。試想一下,當前我們所用的Foo是單例,意味著被初始化后會一直存在與內(nèi)存中,以方便我們以后調(diào)用的時候不會在此次創(chuàng)建Foo對象。但Foo中的『mContext』變量一直都會持有Activity A中的『Context』,導致Activity A即使執(zhí)行了onDestroy方法,也不能夠?qū)⒆约轰N毀。但『applicationContext』就不同了,它一直伴隨著我們應用存在(中途也可能會被銷毀,但也會自動reCreate),所以就不用擔心Foo中的『mContext』會持有某Activity的引用,讓其無法銷毀。

正確方式:   

 public class Foo{

   private static Foo foo;

   private Context mContext;

   private Foo(Context mContext){

    this.mContext = mContext;

   }

   // 普通單例,非線程安全

   public static Foo getInstance(Context mContext){

    if(foo == null)

     foo = new Foo(mContext.getApplicationContext());

    return foo;

   }

   public void otherAction(){

    mContext.xxxx();

    ….

   }

  }

  

2、使用匿名內(nèi)部類的時候經(jīng)常出現(xiàn)的錯誤

錯誤方式:

 public class FooActivity extends Activity{

   private TextView textView;   



   private Handler handler = new Handler(){

    @override

    public void handlerMessage(Message msg){

     

    }

   };

   @override

   public void onCreate(Bundle bundle){

    super.onCreate(bundle);

    setContextView(R.layout.activity_foo_layout);

    

    textView = (TextView)findViewById(R.id.textView);

    

    handler.postDelayed(new Runnable(){

     @override

     public void run(){

       textView.setText(“ok”);

     };

    },1000 * 60 * 10);

   }

  }



錯誤原因:

     當我們執(zhí)行了FooActivity的finish方法,被延遲的消息會在被處理之前存在于主線程消息隊列中10分鐘,而這個消息中又包含了Handler的引用,而Handler是一個匿名內(nèi)部類的實例,其持有外面的FooActivity的引用,所以這導致了FooActivity無法回收,進而導致FooActivity持有的很多資源都無法回收,所以產(chǎn)生了內(nèi)存泄露。

     注意上面的new Runnable這里也是匿名內(nèi)部類實現(xiàn)的,同樣也會持有FooActivity的引用,也會阻止FooActivity被回收。

     一個靜態(tài)的匿名內(nèi)部類實例不會持有外部類的引用。

正確方式:    

 public class FooActivity extends Activity{

   private TextView textView;

   

   private static class MyHandler extends Handler {

   private final WeakReference<FooActivity> mActivity;

   public MyHandler(FooActivity activity) {

    mActivity = new WeakReference<FooActivity>(activity);

   }

   @Override

   public void handleMessage(Message msg) {

    FooActivity activity = mActivity.get();

     if (activity != null) {

       // ...

     }

    }

   }

   private final MyHandler handler = new MyHandler(this);



   @override

   public void onCreate(Bundle bundle){

    super.onCreate(bundle);

    setContextView(R.layout.activity_foo_layout);

    

    textView = (TextView)findViewById(R.id.textView);

    

    handler.postDelayed(new MyRunnable(textView),1000 * 60 * 10);

   }



   private static class MyRunnable implements Runnable{

    private WeakReference<TextView> textViewWeakReference;

    

    public MyRunnable(TextView textView){

     textViewWeakReference = new WeakReference<TextView>(textView);

    }

     @override

     public void run(){

       final TextView textView = textViewWeakReference.get();

       if(textView != null){

        textView.setText("OK");

       }

     };

   }

  }

  

3、在使用handler后,記得在onDestroy里面handler.removeCallbacksAndMessages(object token);

 handler.removeCallbacksAndMessages(null);

  // removeCallbacksAndMessages,當參數(shù)為null的時候,可以清除掉所有跟次handler相關的Runnable和Message,我們在onDestroy中調(diào)用次方法也就不會發(fā)生內(nèi)存泄漏了。

開發(fā)中需要注意的點以免內(nèi)存泄漏:

  •      1.不要讓生命周期長于Activity的對象持有到Activity的引用
  •      2.盡量使用Application的Context而不是Activity的Context
  •      3.盡量不要在Activity中使用非靜態(tài)內(nèi)部類,因為非靜態(tài)內(nèi)部類會隱式持有外部類實例的引用(具體可以查看細話Java:”失效”的private修飾符了解)。如果使用靜態(tài)內(nèi)部類,將外部實例引用作為弱引用持有。
  •      4.垃圾回收不能解決內(nèi)存泄露,了解Android中垃圾回收機制

獲取context的方法,以及使用上context和applicationContext的區(qū)別:

  •      1.View.getContext,返回當前View對象的Context對象,通常是當前正在展示的Activity對象。
  •      2.Activity.getApplicationContext,獲取當前Activity所在的(應用)進程的Context對象,通常我們使用Context對象時,要優(yōu)先考慮這個全局的進程Context。
  •      3,ContextWrapper.getBaseContext():用來獲取一個ContextWrapper進行裝飾之前的Context,可以使用這個方法,這個方法在實際開發(fā)中使用并不多,也不建議使用。
  •      4.Activity.this 返回當前的Activity實例,如果是UI控件需要使用Activity作為Context對象,但是默認的Toast實際上使用ApplicationContext也可以。

 大家注意看到有一些NO上添加了一些數(shù)字,其實這些從能力上來說是YES,但是為什么說是NO呢?下面一個一個解釋:

     數(shù)字1:啟動Activity在這些類中是可以的,但是需要創(chuàng)建一個新的task。一般情況不推薦。

     數(shù)字2:在這些類中去layout inflate是合法的,但是會使用系統(tǒng)默認的主題樣式,如果你自定義了某些樣式可能不會被使用。

     數(shù)字3:在receiver為null時允許,在4.2或以上的版本中,用于獲取黏性廣播的當前值。(可以無視)

     注:ContentProvider、BroadcastReceiver之所以在上述表格中,是因為在其內(nèi)部方法中都有一個context用于使用。

     好了,這里我們看下表格,重點看Activity和Application,可以看到,和UI相關的方法基本都不建議或者不可使用Application,并且,前三個操作基本不可能在Application中出現(xiàn)。實際上,只要把握住一點,凡是跟UI相關的,都應該使用Activity做為Context來處理;其他的一些操作,Service,Activity,Application等實例都可以,當然了,注意Context引用的持有,防止內(nèi)存泄漏。

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助。

相關文章

  • Android 第三方庫lottie、mmkv的使用詳解

    Android 第三方庫lottie、mmkv的使用詳解

    lottie是Airbnb開源的一個面向 iOS、Android、React Native 的動畫庫,能實現(xiàn)精美、復雜的動畫效果,本文通過實例代碼給大家介紹Android 第三方庫lottie、mmkv的使用,感興趣的的朋友一起看看吧
    2021-04-04
  • Android異步方法以同步方式實現(xiàn)

    Android異步方法以同步方式實現(xiàn)

    這篇文章主要為大家詳細介紹了Android異步方法以同步方式進行的實現(xiàn)方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-07-07
  • Android無需權限調(diào)起系統(tǒng)相機

    Android無需權限調(diào)起系統(tǒng)相機

    在進行一些小型APP的開發(fā),或者是對拍照界面沒有自定義要求時,我們可以用調(diào)起系統(tǒng)相機的方式快速完成拍照需求
    2023-03-03
  • Android?Gradle?插件自定義Plugin實現(xiàn)注意事項

    Android?Gradle?插件自定義Plugin實現(xiàn)注意事項

    這篇文章主要介紹了Android?Gradle?插件自定義Plugin實現(xiàn)注意事項,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的朋友可以參考一下
    2022-06-06
  • Android NDK開發(fā)的環(huán)境搭建與簡單示例

    Android NDK開發(fā)的環(huán)境搭建與簡單示例

    本文主要介紹Android NDK的知識,這里整理了相關資料,來說明如何搭建相應環(huán)境和簡單實例,幫助大家理解,有興趣的小伙伴可以參考下
    2016-09-09
  • Android 實現(xiàn)旋轉(zhuǎn)木馬的音樂效果

    Android 實現(xiàn)旋轉(zhuǎn)木馬的音樂效果

    大家一定在百度音樂上在線聽過歌,有沒有注意到那個旋轉(zhuǎn)的唱片,本篇文章主要介紹在Android上如何實現(xiàn)這樣的功能,有需要的小伙伴可以參考下
    2016-07-07
  • Android實現(xiàn)背景顏色滑動漸變效果的全過程

    Android實現(xiàn)背景顏色滑動漸變效果的全過程

    在Android開發(fā)中,經(jīng)常需要設置控件的背景顏色或者圖片的src顏色,下面這篇文章主要給大家介紹了關于Android實現(xiàn)背景顏色滑動漸變效果的相關資料,本文通過示例代碼介紹的非常詳細,需要的朋友可以參考下
    2021-09-09
  • Android ProgressBar 模擬進度條效果的實現(xiàn)

    Android ProgressBar 模擬進度條效果的實現(xiàn)

    這篇文章主要介紹了Android ProgressBar 模擬進度條效果的實現(xiàn),本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-04-04
  • Kotlin使用靜態(tài)變量與靜態(tài)方法詳解

    Kotlin使用靜態(tài)變量與靜態(tài)方法詳解

    kotlin定義靜態(tài)變量、方法可以采用伴生對象companion object的方式。 下面這篇文章主要給大家介紹了關于Kotlin使用靜態(tài)變量與靜態(tài)方法的相關資料,需要的朋友可以參考下
    2018-12-12
  • Android View的事件分發(fā)機制深入分析講解

    Android View的事件分發(fā)機制深入分析講解

    事件分發(fā)從手指觸摸屏幕開始,即產(chǎn)生了觸摸信息,被底層系統(tǒng)捕獲后會傳遞給Android的輸入系統(tǒng)服務IMS,通過Binder把消息發(fā)送到activity,activity會通過phoneWindow、DecorView最終發(fā)送給ViewGroup。這里就直接分析ViewGroup的事件分發(fā)
    2023-01-01

最新評論