Skip to content

Platform view hasn't been initialized from the platform view channel. #108429

@artem-2024

Description

@artem-2024

I have this problem too.

You need to test in the release build. It doesn't crash in the debug build.

I'm trying to rewrite the video player by replacing Texture with SurfaceView for Android.

Everything works, but when I start to quickly change the PlatformViewLink or switch to PIP, the application crashes:

Log:

E/flutter (14136): [ERROR:flutter/fml/platform/android/jni_util.cc(204)] java.lang.IllegalStateException: Platform view hasn't been initialized from the platform view channel.
E/flutter (14136): 	at h9.m.I(Unknown Source:100)
E/flutter (14136): 	at h9.m.Q(Unknown Source:3)
E/flutter (14136): 	at io.flutter.embedding.engine.FlutterJNI.onDisplayPlatformView(Unknown Source:19)
E/flutter (14136): 	at android.os.MessageQueue.nativePollOnce(Native Method)
E/flutter (14136): 	at android.os.MessageQueue.next(MessageQueue.java:337)
E/flutter (14136): 	at android.os.Looper.loopOnce(Looper.java:168)
E/flutter (14136): 	at android.os.Looper.loop(Looper.java:299)
E/flutter (14136): 	at android.app.ActivityThread.main(ActivityThread.java:8103)
E/flutter (14136): 	at java.lang.reflect.Method.invoke(Native Method)
E/flutter (14136): 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:556)
E/flutter (14136): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1045)

Flutter doctor -v

[✓] Flutter (Channel stable, 3.0.3, on macOS 12.2.1 21D62 darwin-x64)
[✓] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 13.3.1)
[✓] Chrome - develop for the web
[!] Android Studio
    ✗ Unable to find bundled Java version.
[✓] Android Studio (version 2021.2)
[✓] VS Code (version 1.68.1)
[✓] Connected device (3 available)
[✓] HTTP Host Availability

Dart code

return PlatformViewLink(
          viewType: 'my_view_type',
          surfaceFactory: (BuildContext context, PlatformViewController controller) {
            return AndroidViewSurface(
              controller: controller as AndroidViewController,
              gestureRecognizers: const <Factory<OneSequenceGestureRecognizer>>{},
              hitTestBehavior: PlatformViewHitTestBehavior.transparent,
            );
          },
          onCreatePlatformView: (PlatformViewCreationParams params) {
            final ExpensiveAndroidViewController controller = PlatformViewsService.initExpensiveAndroidView(
              id: params.id,
              viewType: params.viewType,
              layoutDirection: TextDirection.ltr,
              creationParams: {'textureId': textureId},
              creationParamsCodec: const StandardMessageCodec(),
            );
            controller
              ..addOnPlatformViewCreatedListener(params.onPlatformViewCreated)
              ..create();

            return controller;
          },
        );

Kotlin code

internal class PlayerViewFactory(private val videoPlayers: LongSparseArray<Player>) :
    PlatformViewFactory(StandardMessageCodec.INSTANCE) {
    override fun create(context: Context?, viewId: Int, args: Any?): PlatformView {
        val layout = LinearLayout(context)
        
        val creationParams = args as Map<String?, Any?>?
        val textureId = (creationParams!!["textureId"] as Int).toLong()
        val player = videoPlayers[textureId]

        val surfaceView = player.surfaceView()

        if (surfaceView.parent != null) {
            (surfaceView.parent as ViewGroup).removeView(surfaceView)
        }

        layout.addView(surfaceView)

        return NativeView(layout)
    }
}

internal class NativeView(private val view: View) :
    PlatformView {
    override fun getView(): View {
        return view
    }

    override fun dispose() {
    }
}

You can test code

internal class PlayerViewFactory(private val videoPlayers: LongSparseArray<Player>) :
    PlatformViewFactory(StandardMessageCodec.INSTANCE) {
    override fun create(context: Context?, viewId: Int, args: Any?): PlatformView {
        val layout = LinearLayout(context)
        
        val view = View(context)
        view.setBackgroundColor(Color.GREEN)
        layout.addView(view)

        return NativeView(layout)
    }
}

internal class NativeView(private val view: View) :
    PlatformView {
    override fun getView(): View {
        return view
    }

    override fun dispose() {
    }
}

Originally posted by @FlutterSu in #104797 (comment)

Metadata

Metadata

Assignees

No one assigned

    Labels

    r: fixedIssue is closed as already fixed in a newer version

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions