googleads / googleads-mobile-flutter

A Flutter plugin for the Google Mobile Ads SDK
Apache License 2.0
344 stars 285 forks source link

Attempt to invoke virtual method 'int java.lang.Integer.intValue()' on a null object reference #1096

Open shijianan201 opened 6 months ago

shijianan201 commented 6 months ago

Plugin Version

ad sdk: 5.1.0 flutter:3.19.1

Steps to Reproduce

firebase crashlytics record some crash throws by GoogleMobileAdsPlugin.java.

Logs ``` Fatal Exception: io.flutter.plugins.firebase.crashlytics.FlutterError: PlatformException(error, Attempt to invoke virtual method 'int java.lang.Integer.intValue()' on a null object reference, null, java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.Integer.intValue()' on a null object reference at io.flutter.plugins.googlemobileads.i0.onMethodCall(GoogleMobileAdsPlugin.java:559) at jk.j$a.a(MethodChannel.java:18) at yj.c.l(DartMessenger.java:19) at yj.c.m(DartMessenger.java:42) at yj.c.i(DartMessenger.java:1) at yj.b.run(R8$$SyntheticClass:13) at android.os.Handler.handleCallback(Handler.java:942) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loopOnce(Looper.java:211) at android.os.Looper.loop(Looper.java:300) at android.app.ActivityThread.main(ActivityThread.java:8315) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:581) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1028) ) at StandardMethodCodec.decodeEnvelope(message_codecs.dart:651) at MethodChannel._invokeMethod(platform_channel.dart:334) ``` ``` ``` ``` ```
malandr2 commented 5 months ago

Hi @shijianan201, can you provide any reproducible steps?

shijianan201 commented 5 months ago

Hi @shijianan201, can you provide any reproducible steps?

It only occurs in release mode, I cannot reproduce from debug. but It appears when I upgrade sdk from 5.0.0 to 5.1.0.

malandr2 commented 5 months ago

@shijianan201 got it, I'll escalate to engineering to take a closer look. If you have any other information from Crashlytics please share to help with the debugging process. Thanks

malandr2 commented 5 months ago

@shijianan201 engineering is unable to reproduce the crash. Do you have any more information you can share so we can take a closer look?

shijianan201 commented 5 months ago

@shijianan201 engineering is unable to reproduce the crash. Do you have any more information you can share so we can take a closer look?

I forked this project modify the code like below.

GoogleMobileAdsPlugin.java

public class GoogleMobileAdsPlugin implements FlutterPlugin, ActivityAware, MethodCallHandler {

   ......
    //make sure no exception throw
    public static <T> T safeArgument(MethodCall call,String key){
        try {
          return call.<T>argument(key);
        }catch (Exception e){
          return null;
        }
      }

    public void onMethodCall(@NonNull MethodCall call, @NonNull final Result result) {
        ......
        case "setImmersiveMode":
        Integer adId = safeArgument(call,"adId");
        if(adId == null){
          result.error(NullPointerException.class.getSimpleName(),"getAdSize failed empty params",null);
        }else{
          Boolean immersiveModeEnabled = safeArgument(call,"immersiveModeEnabled");
          FlutterOverlayAd ad = ((FlutterOverlayAd) instanceManager.adForId(adId));
          if(ad != null && immersiveModeEnabled != null) {
            ad.setImmersiveMode(immersiveModeEnabled);
          }
          result.success(null);
        }
        break;
       .......
   }
   .....
}

Now firebase crashlytics record

          Fatal Exception: io.flutter.plugins.firebase.crashlytics.FlutterError: PlatformException(NullPointerException, getAdSize failed empty params, null, null)
       at StandardMethodCodec.decodeEnvelope(message_codecs.dart:651)
       at MethodChannel._invokeMethod(platform_channel.dart:334)

Then I read the setImmersiveMode code in dart, I found no try catch block use in this function. so I think it because sometimes adId is null when setImmersiveMode function called from dart to java, then java throws exception,but dart doesn't catch it. And I think not only setImmersiveMode function produce this problem, all function in GoogleMobileAdsPlugin'onMethodCall can produce.

LTPhantom commented 5 months ago

Thank you, @shijianan201. I see the issue now, it definitely needs some more handling on the dart layer. Will work on this for the next release.