[Android] 非靜態內部類別可能造成記憶體洩漏


Posted by imcloudwu on 2021-09-13

常見用法

public class JavaTester {

    class MyHandler extends Handler {
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
        }
    }
}

This Handler class should be static or leaks might occur (com.example.kotlintest.JavaTester.MyHandler)


非靜態內部類別(包含匿名類別)會保持對外部類別的強引用
若內部類別生命週期長於外部會造成記憶體洩漏

案例整理

Lambda 表達式如果未呼叫外部成員或方法,會被編譯成靜態

Kotlin Java
Capturing lambdas Leak Leak
Non-capturing lambdas No Leak No Leak
Inner class Leak Leak
Anonymous class Leak Leak

解決方向

  1. 確保內部生命週期短於外部
  2. 避免使用非靜態內部類別(包含匿名類別)
  3. 若一定需要呼叫到外部成員或方法,使用弱引用(WeakReference)將外部類別傳遞給內部

內部類別寫法

靜態

Java

public class OuterClass {
   public static class InnerClass {
   }
}

Kotlin

class OuterClass {
    class InnerClass {
    }
}

非靜態

Java

public class OuterClass {
   public class InnerClass {
   }
}

Kotlin

class OuterClass {
    inner class InnerClass {
    }
}

#memory leak #handler #inner class #Android #Kotlin #java







Related Posts

JavaScript 執行環境與作用域

JavaScript 執行環境與作用域

為什麼我們需要使用 Axios

為什麼我們需要使用 Axios

菜比八寫後端(3) - MySQL key與正規化

菜比八寫後端(3) - MySQL key與正規化


Comments