Android计费客户端导致内存泄漏

beg*_*ner 6 android memory-leaks in-app-billing leakcanary play-billing-library

MainActivity对于新项目来说很简单

\n
public class MainActivity extends AppCompatActivity {\n  BillingClient billingClient;\n  PurchasesUpdatedListener purchasesUpdatedListener = new PurchasesUpdatedListener() {\n    @Override\n    public void onPurchasesUpdated(@NonNull BillingResult billingResult, @Nullable List<Purchase> list) {\n\n    }\n};\n@Override\nprotected void onCreate(Bundle savedInstanceState) {\n    super.onCreate(savedInstanceState);\n    setContentView(R.layout.activity_main);\n}\n\n\n@Override\nprotected void onStart() {\n    super.onStart();\n    billingClient = BillingClient.newBuilder(this)\n            .enablePendingPurchases()\n            .setListener(purchasesUpdatedListener)\n            .build();\n    billingClient.startConnection(new BillingClientStateListener() {\n        @Override\n        public void onBillingSetupFinished(@NonNull BillingResult billingResult) {\n\n        }\n\n        @Override\n        public void onBillingServiceDisconnected() {\n\n        }\n    });\n}\n\n@Override\nprotected void onStop() {\n    super.onStop();\n    billingClient.endConnection();\n}\n
Run Code Online (Sandbox Code Playgroud)\n

在 Gradle 文件中:

\n
  ....\n  implementation 'com.android.billingclient:billing:3.0.2'\n  debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.5'\n
Run Code Online (Sandbox Code Playgroud)\n

金丝雀输出(1 个不同的泄漏):

\n
\xe2\x94\xac\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\n\xe2\x94\x82 GC Root: Input or output parameters in native code\n\xe2\x94\x82\n\xe2\x94\x9c\xe2\x94\x80 android.os.MessageQueue instance\n\xe2\x94\x82    Leaking: NO (MessageQueue#mQuitting is false)\n\xe2\x94\x82    HandlerThread: "main"\n\xe2\x94\x82    \xe2\x86\x93 MessageQueue.mMessages\n\xe2\x94\x82                   ~~~~~~~~~\n\xe2\x94\x9c\xe2\x94\x80 android.os.Message instance\n\xe2\x94\x82    Leaking: UNKNOWN\n\xe2\x94\x82    Retaining 116109 bytes in 1346 objects\n\xe2\x94\x82    Message.what = 0\n\xe2\x94\x82    Message.when = 104320925 (14773 ms after heap dump)\n\xe2\x94\x82    Message.obj = null\n\xe2\x94\x82    Message.callback = instance @315501888 of com.android.billingclient.api.zzr\n\xe2\x94\x82    \xe2\x86\x93 Message.callback\n\xe2\x94\x82              ~~~~~~~~\n\xe2\x94\x9c\xe2\x94\x80 com.android.billingclient.api.zzr instance\n\xe2\x94\x82    Leaking: UNKNOWN\n\xe2\x94\x82    Retaining 116024 bytes in 1344 objects\n\xe2\x94\x82    \xe2\x86\x93 zzr.zzb\n\xe2\x94\x82          ~~~\n\xe2\x94\x9c\xe2\x94\x80 com.android.billingclient.api.zzag instance\n\xe2\x94\x82    Leaking: UNKNOWN\n\xe2\x94\x82    Retaining 115980 bytes in 1342 objects\n\xe2\x94\x82    \xe2\x86\x93 zzag.zza\n\xe2\x94\x82           ~~~\n\xe2\x94\x9c\xe2\x94\x80 com.android.billingclient.api.zzah instance\n\xe2\x94\x82    Leaking: UNKNOWN\n\xe2\x94\x82    Retaining 115968 bytes in 1341 objects\n\xe2\x94\x82    \xe2\x86\x93 zzah.zza\n\xe2\x94\x82           ~~~\n\xe2\x94\x9c\xe2\x94\x80 com.android.billingclient.api.BillingClientImpl instance\n\xe2\x94\x82    Leaking: UNKNOWN\n\xe2\x94\x82    Retaining 115939 bytes in 1339 objects\n\xe2\x94\x82    zze instance of android.app.Application\n\xe2\x94\x82    zzf instance of android.app.Application\n\xe2\x94\x82    \xe2\x86\x93 BillingClientImpl.zzd\n\xe2\x94\x82                        ~~~\n\xe2\x94\x9c\xe2\x94\x80 com.android.billingclient.api.zze instance\n\xe2\x94\x82    Leaking: UNKNOWN\n\xe2\x94\x82    Retaining 115881 bytes in 1338 objects\n\xe2\x94\x82    zza instance of android.app.Application\n\xe2\x94\x82    \xe2\x86\x93 zze.zzb\n\xe2\x94\x82          ~~~\n\xe2\x94\x9c\xe2\x94\x80 com.android.billingclient.api.zzd instance\n\xe2\x94\x82    Leaking: UNKNOWN\n\xe2\x94\x82    Retaining 115865 bytes in 1337 objects\n\xe2\x94\x82    \xe2\x86\x93 zzd.zzb\n\xe2\x94\x82          ~~~\n\xe2\x94\x9c\xe2\x94\x80 com.example.billingclientleak.MainActivity$1 instance\n\xe2\x94\x82    Leaking: UNKNOWN\n\xe2\x94\x82    Retaining 115841 bytes in 1336 objects\n\xe2\x94\x82    Anonymous class implementing com.android.billingclient.api.\n\xe2\x94\x82    PurchasesUpdatedListener\n\xe2\x94\x82    this$0 instance of com.example.billingclientleak.MainActivity with\n\xe2\x94\x82    mDestroyed = true\n\xe2\x94\x82    \xe2\x86\x93 MainActivity$1.this$0\n\xe2\x94\x82                     ~~~~~~\n\xe2\x95\xb0\xe2\x86\x92 com.example.billingclientleak.MainActivity instance\n\xe2\x80\x8b     Leaking: YES (ObjectWatcher was watching this because com.example.\n\xe2\x80\x8b     billingclientleak.MainActivity received Activity#onDestroy() callback and\n\xe2\x80\x8b     Activity#mDestroyed is true)\n\xe2\x80\x8b     Retaining 115829 bytes in 1335 objects\n\xe2\x80\x8b     key = d55540b8-a7aa-4fa1-9eb1-ed14135a9a8d\n\xe2\x80\x8b     watchDurationMillis = 5135\n\xe2\x80\x8b     retainedDurationMillis = 133\n\xe2\x80\x8b     mApplication instance of android.app.Application\n\xe2\x80\x8b     mBase instance of androidx.appcompat.view.ContextThemeWrapper, not\n\xe2\x80\x8b     wrapping known Android context\n\nMETADATA\n\nBuild.VERSION.SDK_INT: 27\nBuild.MANUFACTURER: Google\nLeakCanary version: 2.5\nApp process name: com.example.billingclientleak\nStats: LruCache[maxSize=3000,hits=634,misses=23227,hitRate=2%]\nRandomAccess[bytes=1191354,reads=23227,travel=6396792403,range=8851265,size=1152\n9733]\nAnalysis duration: 7997 ms```\n
Run Code Online (Sandbox Code Playgroud)\n