Вызвать код Flutter (Dart) из родного виджета домашнего экрана Android
Я добавил собственный виджет домашнего экрана Android в свое приложение Flutter.
В моей реализации AppWidgetProvider
я хотел бы вызвать код dart в моем onUpdate()
используя канал платформы.
Это возможно? Если да, то как этого достичь?
Мой текущий код Android (Java):
package com.westy92.checkiday;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.util.Log;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.view.FlutterNativeView;
public class HomeScreenWidget extends AppWidgetProvider {
private static final String TAG = "HomeScreenWidget";
private static final String CHANNEL = "com.westy92.checkiday/widget";
private static FlutterNativeView backgroundFlutterView = null;
private static MethodChannel channel = null;
@Override
public void onEnabled(Context context) {
Log.i(TAG, "onEnabled!");
backgroundFlutterView = new FlutterNativeView(context, true);
channel = new MethodChannel(backgroundFlutterView, CHANNEL);
}
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
Log.i(TAG, "onUpdate!");
if (channel != null) {
Log.i(TAG, "channel not null, invoking dart method!");
channel.invokeMethod("foo", "extraJunk");
Log.i(TAG, "after invoke dart method!");
}
}
}
Код дротика:
void main() {
runApp(Checkiday());
}
class Checkiday extends StatefulWidget {
@override
_CheckidayState createState() => _CheckidayState();
}
class _CheckidayState extends State<Checkiday> {
static const MethodChannel platform = MethodChannel('com.westy92.checkiday/widget');
@override
void initState() {
super.initState();
platform.setMethodCallHandler(nativeMethodCallHandler);
}
Future<dynamic> nativeMethodCallHandler(MethodCall methodCall) async {
print('Native call!');
switch (methodCall.method) {
case 'foo':
return 'some string';
default:
// todo - throw not implemented
}
}
@override
Widget build(BuildContext context) {
// ...
}
}
Когда я добавляю виджет на домашний экран, я вижу:
I/HomeScreenWidget(10999): onEnabled!
I/HomeScreenWidget(10999): onUpdate!
I/HomeScreenWidget(10999): channel not null, invoking dart method!
I/HomeScreenWidget(10999): after invoke dart method!
Однако мой код дротика, похоже, не получает вызов.
Ответы
Ответ 1
Сначала убедитесь, что вы вызываете FlutterMain.startInitialization()
а затем FlutterMain.ensureInitializationComplete()
прежде чем пытаться выполнить любой код Dart. Эти звонки необходимы для начальной загрузки Flutter.
Во-вторых, можете ли вы попробовать эту же цель с помощью нового экспериментального встраивания Android?
Вот руководство по выполнению кода Dart с использованием нового встраивания: https://github.com/flutter/flutter/wiki/Experimental:-Reuse-FlutterEngine-across-screens
Если ваш код все еще не работает должным образом с новым встраиванием Android, тогда должно быть легче отладить, в чем проблема. Пожалуйста, отправьте обратно с успехом, или любую новую информацию об ошибке.
Ответ 2
может быть, вы можете использовать invokeMethod(String method, @Nullable Object arguments, MethodChannel.Result callback)
и использовать обратный вызов, чтобы получить причину сбоя.
Ответ 3
Вам нужно передать getFlutterView() из MainActivity вместо создания нового BackgroundFlutterView:
channel = new MethodChannel(MainActivity.This.getFlutterView(), CHANNEL);
"Это" как:
public class MainActivity extends FlutterActivity {
public static MainActivity This;
@Override
protected void onCreate(Bundle savedInstanceState) {
This = this;
...
}