Repository: flutter
Issue: [android] MethodChannel not being recreated upon app relaunch
Labels: platform-android,engine,a: existing-apps,has reproducible steps,P2,found in release: 2.10,found in release: 2.13,a: plugins,team-android,triaged-android

### Problem description:

We are developing Flutter plugin which uses `MethodChannel` to communicate between native (Android in this case) and Dart layer. Upon first app launch, channel is created and communication works without issues. If one exists Android app with back action (either button press or swipe gesture) and reopens the app, `MethodChannel` instance gets `null-ed` at some point making communication between native and Dart layer impossible.

###  More detailed problem description:

Upon initial app launch (which triggers plugin initialisation), `MethodChannel` instance is being created like [this](https://github.com/adjust/flutter_sdk/blob/master/android/src/main/java/com/adjust/sdk/flutter/AdjustSdk.java#L82-L84). During app runtime, we are using this channel to communicate some messages back to Dart layer like [this](https://github.com/adjust/flutter_sdk/blob/master/android/src/main/java/com/adjust/sdk/flutter/AdjustSdk.java#L400), for example. Upon exiting app (detaching from engine), we're cleaning up channel instance as shown in [here](https://github.com/adjust/flutter_sdk/blob/master/android/src/main/java/com/adjust/sdk/flutter/AdjustSdk.java#L90-L94).

If one puts app to background and then back to foreground, things work just fine since everything still lives in memory and channel instance is still there. If one kills the app and opens it after killing, things also work just fine - `MethodChannel` instance is created and lives throughout app runtime. However, if one exists Android app with back action and reopens it, then things become interesting. Here's what seems to be happening:
- Upon exiting the app, channel instance gets [cleaned up](https://github.com/adjust/flutter_sdk/blob/master/android/src/main/java/com/adjust/sdk/flutter/AdjustSdk.java#L90-L94).
- Upon reopening the app, channel instance indeed does get created (I see while debugging that [this](https://github.com/adjust/flutter_sdk/blob/master/android/src/main/java/com/adjust/sdk/flutter/AdjustSdk.java#L82-L84) part gets executed and that `MethodChannel` instance is created.
- However during app runtime when the time comes for message to be communicated from native Android to Dart layer, `channel` is `null` and calls like [this](https://github.com/adjust/flutter_sdk/blob/master/android/src/main/java/com/adjust/sdk/flutter/AdjustSdk.java#L463) cause NPE.
```
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.adjust.examples, PID: 6120
    java.lang.NullPointerException: Attempt to invoke virtual method 'void io.flutter.plugin.common.MethodChannel.invokeMethod(java.lang.String, java.lang.Object)' on a null object reference
        at com.adjust.sdk.flutter.AdjustSdk$4.onFinishedEventTrackingSucceeded(AdjustSdk.java:490)
        at com.adjust.sdk.ActivityHandler$38.run(ActivityHandler.java:1329)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:223)
        at android.app.ActivityThread.main(ActivityThread.java:7660)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
```

### Steps to reproduce:

- `git clone https://github.com/adjust/flutter_sdk.git`
- `cd flutter_sdk/example`
- [make sure you have Android device connected]
- `flutter run`
- make sure app is launched on Android device
- [not needed, but you can hit for example `Track Callback Event` button since this click will trigger attempt of communication from native Android to Dart layer and in first run, it will work without issues]
- exit the app with back action
- reopen the app
- press `Track Callback Event` button (again) and app will crash

### Expected outcome:

`MethodChannel` instance to be instantiated so that message can be sent from native Android layer to Dart.

### Actual outcome:

`MethodChannel` instance is `null`-ed and message can't be sent from native Android to Dart layer. There's also crash involved in here obviously, but `channel` instance `null` check will help with that.

### Random comments:

For the time being, seems like there are two possible "fixes":
- leave implementation as it is and simply add `null` checks before trying to send message via `channel` (but this is not really a fix, it will just prevent NPEs from happening)
- skip [cleanup](https://github.com/adjust/flutter_sdk/blob/master/android/src/main/java/com/adjust/sdk/flutter/AdjustSdk.java#L90-L94) part when detaching from the engine (this doesn't cause crash since instance is not `null`-ed, but when attempted to send the message via `channel`, it reports: **W/FlutterJNI: Tried to send a platform message to Flutter, but FlutterJNI was detached from native C++. Could not send. Channel: com.adjust.sdk/api. Response ID: 0** which also seems to be [known issue](https://github.com/flutter/flutter/issues/28651) to which, from what I understood, there's still no actual fix).

Like said, none of these two suggested approaches are real fixes because they will just make sure that NPEs are not happening, but will still have message sending logic from native Android to Dart layer broken in described use case.

In case you need any additional information, please let me know.

Cheers
Ugi