FlutterActivity MethodChannel 和 FlutterView
Posted
技术标签:
【中文标题】FlutterActivity MethodChannel 和 FlutterView【英文标题】:FlutterActivity MethodChannel and FlutterView 【发布时间】:2020-04-06 23:04:43 【问题描述】:所以我大约 4 个月前写了一个 Flutter 应用程序。现在我想做一个小改动,但是我不能再编译应用程序了,因为 GeneratedPluginRegistrant.registerWith(this) 不再起作用了,我没有更改 Kotlin 代码,只更改了 Dart 代码。
“GeneratedPluginRegistrant.registerWith(this)”中的“this”向我显示了这个错误:
Type mismatch.
Required: FlutterEngine!
Found: MainActivity
MainActivity 类:
import android.os.Bundle
import io.flutter.app.FlutterActivity
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugins.GeneratedPluginRegistrant
import io.flutter.view.FlutterMain
class MainActivity : FlutterActivity()
override fun onCreate(savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
GeneratedPluginRegistrant.registerWith(this) // here is the error: Type mismatch. Required: FlutterEngine! Found: MainActivity
MethodChannel(flutterView, CHANNEL).setMethodCallHandler call, result ->
if (call.method == "helloFromNativeCode")
val greetings = helloFromNativeCode()
result.success(greetings)
private fun helloFromNativeCode(): String
return "Hello from Native Android Code"
companion object
private const val CHANNEL = "flutter.native/helper"
如果是使用:
import io.flutter.embedding.android.FlutterActivity
而不是
import io.flutter.app.FlutterActivity
我可以使用
override fun configureFlutterEngine(flutterEngine: FlutterEngine)
GeneratedPluginRegistrant.registerWith(flutterEngine);
但有问题:
MethodChannel(flutterView, CHANNEL).setMethodCallHandler call, result ->
if (call.method == "helloFromNativeCode")
val greetings = helloFromNativeCode()
result.success(greetings)
因为我在 flutterView 上遇到错误:
Unresolved reference: flutterView
代码如下所示:
import android.os.Bundle
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugins.GeneratedPluginRegistrant
import io.flutter.view.FlutterMain
class MainActivity : FlutterActivity()
override fun configureFlutterEngine(flutterEngine: FlutterEngine)
GeneratedPluginRegistrant.registerWith(flutterEngine);
override fun onCreate(savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
MethodChannel(flutterView, CHANNEL).setMethodCallHandler call, result -> // here is the error
if (call.method == "helloFromNativeCode")
val greetings = helloFromNativeCode()
result.success(greetings)
private fun helloFromNativeCode(): String
return "Hello from Native Android Code"
companion object
private const val CHANNEL = "flutter.native/helper"
我希望有人可以帮助我。
【问题讨论】:
我遇到了同样的问题。看起来这在最新的 Flutter 中被打破了,因为他们正在切换到 io.flutter.embedding.android.FlutterActivity 【参考方案1】:使用flutterEngine.getDartExecutor()代替flutterView。
【讨论】:
【参考方案2】:我花了几天时间试图弄清楚如何将 Flutter UI 添加到我现有的 Android 应用程序中。最大的挑战是让 MethodChannel 与从 MainActivity 调用的 FlutterActivity 一起工作。我知道这与这里提出的问题有点不同,但是当我搜索“Android FlutterActivity MethodChannel”时,返回了这篇文章。在浏览了很多关于如何做到这一点的资源之后,我终于在这里找到了我的解决方案: https://github.com/flutter/samples/tree/master/add_to_app/android_using_plugin/app/src/main/java/dev/flutter/example/androidusingplugin
最初,在 Android Studio 中,打开现有应用程序后,我依次点击 File、New、New Module、Flutter Module。我收到一个错误,必须执行手动步骤。
我的目标是在 MainActivity - onCreate 中启动 FlutterActivity(在 flutter_module 中打开 main.dart),然后利用尽可能多的原生 Flutter 代码开发 Flutter“屏幕”,并使用 MethodChannel 进行有限的平台调用。在开发替代 Flutter 代码时,我将继续评论现有的 Android 代码。
这是最终对我有用的方法:
../App_Project/Android/Existing_Android_App/settings.gradle
include ':app'
setBinding(new Binding([gradle: this]))
evaluate(new File(settingsDir.parentFile, '../flutter_module/.android/include_flutter.groovy'))
include ':flutter_module’
project(':flutter_module’).projectDir = new File('../../flutter_module’)
rootProject.name=‘existing_android_app’
../App_Project/Android/Existing_Android_App/app/build.gradle
dependencies
…
implementation project(':flutter')
../App_Project/Android/Existing_Android_App/app/src/main/AndroidManifest.xml
<activity
android:name="io.flutter.embedding.android.FlutterActivity"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize" />
../App_Project/Android/Existing_Android_App/app/src/main/java/com/existing_android_app/MainActivity.java
package com.existing_android_app;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import io.flutter.embedding.android.FlutterActivity;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.embedding.engine.FlutterEngineCache;
import io.flutter.embedding.engine.dart.DartExecutor;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
public class MainActivity extends AppCompatActivity
final String ENGINE_ID = "1";
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
FlutterEngine flutterEngine = new FlutterEngine(this);
flutterEngine.getDartExecutor().executeDartEntrypoint(DartExecutor.DartEntrypoint.createDefault());
FlutterEngineCache.getInstance().put(ENGINE_ID, flutterEngine);
MethodChannel channel = new MethodChannel(flutterEngine.getDartExecutor(), "com.existing_android_app/myMethodChannel");
channel.setMethodCallHandler(
new MethodChannel.MethodCallHandler()
@Override
public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result)
String url = call.argument("url");
if (call.method.equals("openBrowser"))
openBrowser(url);
else
result.notImplemented();
);
startActivity(FlutterActivity.withCachedEngine(ENGINE_ID).build(this));
void openBrowser(String url)
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(url));
this.startActivity(intent);
../App_Project/flutter_module/lib/home_page.dart
class AppHomePage extends StatefulWidget
@override
_HomePageState createState() => _HomePageState();
class _HomePageState extends State<AppHomePage>
static const platform = const MethodChannel(‘com.existing_android_app/myMethodChannel’);
Future<void> _openBrowser() async
try
final int result = await platform.invokeMethod('openBrowser', <String, String> 'url': "http://bing.com" );
catch (e)
print('***** _openBrowser error: ' + e.toString());
@override
Widget build(BuildContext context)
return SafeArea(
child: Scaffold(
appBar: CustomAppBar(),
body: Column(
children: <Widget>[
RaisedButton(
label: Text('Search',
style: TextStyle(fontSize: 18.0),
),
onPressed: () _openBrowser(); ,
) // RaisedButton.icon
], // Widget
) // Column
) // Scaffold
); // SafeArea
【讨论】:
谢谢你!最后它的工作。我得到了MissingPluginException
。这个答案有帮助,但在 github 上打开的问题没有任何帮助。
如何与您联系?请告诉我,你不和谐吗?还是其他?
你在救我的命,兄弟!
嘿,你也可以看看这里吗?这听起来是一个类似的问题,但我无法关联。 ***.com/questions/65780859/…【参考方案3】:
你应该使用
import io.flutter.embedding.android.FlutterActivity;
并在
中声明您的 patformChannel @Override
public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine)
GeneratedPluginRegistrant.registerWith(flutterEngine);
new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), CHANNEL)
.setMethodCallHandler(
(call, result) ->
// Note: this method is invoked on the main thread.
// TODO
);
有关更多信息,您可以查看文档:https://flutter.dev/docs/development/platform-integration/platform-channels
【讨论】:
【参考方案4】:你可以像这样使用方法通道和颤振引擎。
private val CHANNEL = "adb"
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine)
GeneratedPluginRegistrant.registerWith(flutterEngine)
MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), CHANNEL)
.setMethodCallHandler call, result ->
//You can use your custom function for example:
if (call.method.equals("checkingadb"))
checkingadb(call, result)
else
result.notImplemented()
private fun checkingadb(call: MethodCall, result: MethodChannel.Result)
if (Settings.Secure.getInt(this.getContentResolver(), Settings.Secure.ADB_ENABLED, 0) === 1)
// debugging enabled
result.success(1)
else
// debugging is not enabled
result.success(0)
【讨论】:
这是 2021 年末最简单的解决方案,适合我【参考方案5】:要传递 Flutter Engine 值,我们可以使用 provideFlutterEngine(this) 方法。而对于flutterView,我们可以使用flutterEngine.dartExecutor。这是代码sn-p的url,之前已经回答过了 https://***.com/a/67698834/11887774.
【讨论】:
以上是关于FlutterActivity MethodChannel 和 FlutterView的主要内容,如果未能解决你的问题,请参考以下文章
Flutter Android FlutterActivity
Flutter实践深入分析之——FlutterActivity/Fragment原理流程分析
Flutter实践深入分析之——FlutterActivity/Fragment原理流程分析
无法访问“io.flutter.embedding.android.FlutterActivity”的超类型“android.arch.lifecycle.LifecycleOwner”