Simple MainActivity
for a new project
public class MainActivity extends AppCompatActivity {
BillingClient billingClient;
PurchasesUpdatedListener purchasesUpdatedListener = new PurchasesUpdatedListener() {
@Override
public void onPurchasesUpdated(@NonNull BillingResult billingResult, @Nullable List<Purchase> list) {
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
protected void onStart() {
super.onStart();
billingClient = BillingClient.newBuilder(this)
.enablePendingPurchases()
.setListener(purchasesUpdatedListener)
.build();
billingClient.startConnection(new BillingClientStateListener() {
@Override
public void onBillingSetupFinished(@NonNull BillingResult billingResult) {
}
@Override
public void onBillingServiceDisconnected() {
}
});
}
@Override
protected void onStop() {
super.onStop();
billingClient.endConnection();
}
in Gradle file:
....
implementation 'com.android.billingclient:billing:3.0.2'
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.5'
canary output (1 distinct leak):
┬───
│ GC Root: Input or output parameters in native code
│
├─ android.os.MessageQueue instance
│ Leaking: NO (MessageQueue#mQuitting is false)
│ HandlerThread: "main"
│ ↓ MessageQueue.mMessages
│ ~~~~~~~~~
├─ android.os.Message instance
│ Leaking: UNKNOWN
│ Retaining 116109 bytes in 1346 objects
│ Message.what = 0
│ Message.when = 104320925 (14773 ms after heap dump)
│ Message.obj = null
│ Message.callback = instance @315501888 of com.android.billingclient.api.zzr
│ ↓ Message.callback
│ ~~~~~~~~
├─ com.android.billingclient.api.zzr instance
│ Leaking: UNKNOWN
│ Retaining 116024 bytes in 1344 objects
│ ↓ zzr.zzb
│ ~~~
├─ com.android.billingclient.api.zzag instance
│ Leaking: UNKNOWN
│ Retaining 115980 bytes in 1342 objects
│ ↓ zzag.zza
│ ~~~
├─ com.android.billingclient.api.zzah instance
│ Leaking: UNKNOWN
│ Retaining 115968 bytes in 1341 objects
│ ↓ zzah.zza
│ ~~~
├─ com.android.billingclient.api.BillingClientImpl instance
│ Leaking: UNKNOWN
│ Retaining 115939 bytes in 1339 objects
│ zze instance of android.app.Application
│ zzf instance of android.app.Application
│ ↓ BillingClientImpl.zzd
│ ~~~
├─ com.android.billingclient.api.zze instance
│ Leaking: UNKNOWN
│ Retaining 115881 bytes in 1338 objects
│ zza instance of android.app.Application
│ ↓ zze.zzb
│ ~~~
├─ com.android.billingclient.api.zzd instance
│ Leaking: UNKNOWN
│ Retaining 115865 bytes in 1337 objects
│ ↓ zzd.zzb
│ ~~~
├─ com.example.billingclientleak.MainActivity$1 instance
│ Leaking: UNKNOWN
│ Retaining 115841 bytes in 1336 objects
│ Anonymous class implementing com.android.billingclient.api.
│ PurchasesUpdatedListener
│ this$0 instance of com.example.billingclientleak.MainActivity with
│ mDestroyed = true
│ ↓ MainActivity$1.this$0
│ ~~~~~~
╰→ com.example.billingclientleak.MainActivity instance
Leaking: YES (ObjectWatcher was watching this because com.example.
billingclientleak.MainActivity received Activity#onDestroy() callback and
Activity#mDestroyed is true)
Retaining 115829 bytes in 1335 objects
key = d55540b8-a7aa-4fa1-9eb1-ed14135a9a8d
watchDurationMillis = 5135
retainedDurationMillis = 133
mApplication instance of android.app.Application
mBase instance of androidx.appcompat.view.ContextThemeWrapper, not
wrapping known Android context
METADATA
Build.VERSION.SDK_INT: 27
Build.MANUFACTURER: Google
LeakCanary version: 2.5
App process name: com.example.billingclientleak
Stats: LruCache[maxSize=3000,hits=634,misses=23227,hitRate=2%]
RandomAccess[bytes=1191354,reads=23227,travel=6396792403,range=8851265,size=1152
9733]
Analysis duration: 7997 ms```