Closed cah-aamir closed 4 months ago
hybrid native view in main.dart using PlatformViewLink
We haven't yet considered more advanced types of embedding (Flutter views in native app or native views in flutter app).
I suspect this error is double initialization in same thread. JNI has quite a few problems with Flutter's threading model. :(
Is jnigen/ffigen the right path to go about a plugin like this or should I just use MethodChannel to do it.
Unfortunately I think you have to go with methodchannel for now. pigeon
may be slightly helpful.
Part of the problem is this library is in alpha, and many build system or runtime quirks still have to be handled. (I take the full blame here).
Thanks for being an early user and reporting bugs.
@mahesh-hegde No problem at all, thanks for the quick response. Perhaps my approach wasn't completely right but as you mentioned there are issues with flutter's threading model and you guys are still ironing out some quirks, I will switch to using MethodChannel and thanks for suggesting "Pigeon", I think it will be helpful. Regardless, jnigen/ffigen is pretty exciting and I can't wait to try out more advanced use-cases once it's more stable, you guys are doing a great job 👍
I think this error can be solved by call the Jni.initDLApi()
method.
But I found another issue when I call Android native methods that marks with @MainThread
, even if I use the runOnUiThread
or MainExecutor.execute
on dart side:
@override
void bindToLifecycle() {
Jni.initDLApi();
final runnable = jni.Runnable.implement(
jni.$RunnableImpl(
run: () => jController.bindToLifecycle(currentActivity),
),
);
jni.ContextCompat.getMainExecutor(currentActivity).execute(runnable);
}
The code above will throw errors
Launching lib\main.dart on V2136A in debug mode...
√ Built build\app\outputs\flutter-apk\app-debug.apk.
W/Choreographer( 5359): Frame time is 9.2E-4 ms in the future! Check that graphics HAL is generating vsync timestamps using the correct timebase.
Connecting to VM Service at ws://127.0.0.1:63961/MYCg_X3gwRA=/ws
I/amera_x_example( 5359): Compiler allocated 5703KB to compile void android.view.ViewRootImpl.performTraversals()
I/CameraManagerGlobal( 5359): Connecting to camera service
D/CameraRepository( 5359): Added camera: 0
I/Camera2CameraInfo( 5359): Device Level: INFO_SUPPORTED_HARDWARE_LEVEL_3
D/CameraRepository( 5359): Added camera: 1
I/Camera2CameraInfo( 5359): Device Level: INFO_SUPPORTED_HARDWARE_LEVEL_3
D/CameraValidator( 5359): Verifying camera lens facing on PD2136, lensFacingInteger: null
D/AndroidRuntime( 5359): Shutting down VM
E/AndroidRuntime( 5359): FATAL EXCEPTION: main
E/AndroidRuntime( 5359): Process: dev.hebei.camera_x_example, PID: 5359
E/AndroidRuntime( 5359): java.lang.reflect.UndeclaredThrowableException
E/AndroidRuntime( 5359): at $Proxy3.run(Unknown Source)
E/AndroidRuntime( 5359): at android.os.Handler.handleCallback(Handler.java:942)
E/AndroidRuntime( 5359): at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime( 5359): at android.os.Looper.loopOnce(Looper.java:223)
E/AndroidRuntime( 5359): at android.os.Looper.loop(Looper.java:324)
E/AndroidRuntime( 5359): at android.app.ActivityThread.main(ActivityThread.java:8546)
E/AndroidRuntime( 5359): at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime( 5359): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:582)
E/AndroidRuntime( 5359): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1061)
E/AndroidRuntime( 5359): Caused by: com.github.dart_lang.jni.PortProxy$DartException: Exception in Java code called through JNI: java.lang.IllegalStateException: Not in application's main thread
E/AndroidRuntime( 5359):
E/AndroidRuntime( 5359): java.lang.IllegalStateException: Not in application's main thread
E/AndroidRuntime( 5359): at androidx.core.util.Preconditions.checkState(Preconditions.java:151)
E/AndroidRuntime( 5359): at androidx.camera.core.impl.utils.Threads.checkMainThread(Threads.java:50)
E/AndroidRuntime( 5359): at androidx.camera.view.LifecycleCameraController.bindToLifecycle(LifecycleCameraController.java:88)
2
E/AndroidRuntime( 5359):
V/ActivityThread( 5359): updateVmProcessStateForGc sceneId =1 state=196608
I/amera_x_example( 5359): Close vivo delay for GC JIT .
Lost connection to device.
Exited.
I can resolve this error if I create a kotlin wrapper class and call the runOnUiThread
or MainExecutor.execute
on the Android side,
then use jnigen to generate dart bindings to the wrapper classs. Then call the method through dart bindings is OK.
I don't know why, but It will be excellent if we can run methods on Android UI thread form dart side.
Now that https://github.com/flutter/engine/pull/48551 has landed, you can do
runOnPlatformThread(() {
final runnable = jni.Runnable.implement(
jni.$RunnableImpl(
run: () => jController.bindToLifecycle(currentActivity),
),
);
// ...
runnable.run();
});
Edit: It seems to now be runOnPlatformThread
.
Wow, I'll look at this and try it right now!
I can't find this api with flutter master channel, seems it will take some time to be available.
I can't find this api with flutter master channel, seems it will take some time to be available.
Yes, it was only merged two days ago.
I think https://github.com/engine-flutter-autoroll/flutter/commit/f31a81a3185440c862010b4662c756aa26c03cdf was rolled into flutter/flutter in https://github.com/flutter/flutter/commit/b7b289cddb92ea5887dc4e29a6791186e5c6513b and should be available on flutter/flutter's master/main channel
I think engine-flutter-autoroll/flutter@f31a81a was rolled into flutter/flutter in flutter/flutter@b7b289c and should be available on flutter/flutter's master/main channel
I can find the platform_isolate.dart
part define in ui.dart file
But I can't find it in the ui folder
I am trying to create a plugin for a 3rd party library, somewhat like zoom. I was able to generate bindings for the library and I can even call class methods e.g. I can call initialize method of native sdk in dart and I get the expected response back.
However, once I render a hybrid native view in main.dart using PlatformViewLink, if I try to call anything from the library or even just try to call Jni.getCachedApplicationContext() the app crashes.
Is jnigen/ffigen the right path to go about a plugin like this or should I just use MethodChannel to do it the conventional way? I was hoping it would be easier using jnigen/ffigen to call native sdk methods from the generated bindings while using the native android & iOS view.
Here's the log from the crash: