Отправить платформенное сообщение в метод Android из изолята фонового флаттера
Я хочу, чтобы фоновый сервис dart работал вечно (изолирует), который будет взаимодействовать с сервером через веб-сокеты. И у меня есть API для Android, который собирает информацию для отправки на сервер. Как я могу вызвать те методы Android, которые используют обратные вызовы и все из фоновой изоляции?
РЕДАКТИРОВАТЬ
До сих пор в dart я создавал Isolate для периодического вызова метода poolSong в фоновом режиме, даже если пользователь использует другое приложение или экран отключен.
Но это дает мне ошибку ниже... по поводу проблем с github говорят, что я не могу отправить сообщение платформы с другого Isolate, если оно не является основным. Но если я сделаю это из основного изолята, то при выходе пользователя приложение, которое изолирует, тоже прекратит работу.
MainDart
class _MyHomePageState extends State<MyHomePage> {
final GlobalKey<ScaffoldState> scaffoldKey = new GlobalKey<ScaffoldState>();
static const platform = const MethodChannel('mainService');
static _poolSong(SendPort sendPort) async {
const oneSec = const Duration(seconds:1);
new Timer.periodic(oneSec, (Timer t) => platform.invokeMethod('poolSong'));
}
@override
void initState() {
super.initState();
ReceivePort receivePort = ReceivePort();
Isolate.spawn(_poolSong, receivePort.sendPort);
}
·
·
·
MainActivityJava
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GeneratedPluginRegistrant.registerWith(this);
new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler(
(call, result) -> {
if (call.method.equals("startService"))
startService();
if (call.method.equals("poolSong"))
poolSong();
}
);
}
ОШИБКА
E/flutter (25412): [ERROR:flutter/runtime/dart_isolate.cc(717)] Isolate (765499726) 'main.dart:_poolSong()' exited with an error
E/flutter (25412): [ERROR:flutter/shell/common/shell.cc(186)] Dart Error: Unhandled exception:
E/flutter (25412): error: native function 'Window_sendPlatformMessage' (4 arguments) cannot be found
E/flutter (25412): #0 Window.sendPlatformMessage (dart:ui/window.dart:811:9)
E/flutter (25412): #1 BinaryMessages._sendPlatformMessage (package:flutter/src/services/platform_messages.dart:39:15)
E/flutter (25412): #2 BinaryMessages.send (package:flutter/src/services/platform_messages.dart:87:12)
E/flutter (25412): #3 MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:286:49)
E/flutter (25412): <asynchronous suspension>
E/flutter (25412): #4 _MyHomePageState._poolSong.<anonymous closure> (package:musictie/main.dart:37:54)
E/flutter (25412): #5 _Timer._runTimers (dart:isolate/runtime/libtimer_impl.dart:382:19)
E/flutter (25412): #6 _Timer._handleMessage (dart:isolate/runtime/libtimer_impl.dart:416:5)
E/flutter (25412): #7 _RawReceivePortImpl._handleMessage (dart:isolate/runtime/libisolate_patch.dart:171:12)
3 ответа
После прочтения известной статьи, где объясняется, как использовать фоновые сервисы во флаттере, и понимаешь, что это нелепо сложно, я заметил, что весь мой код Android мог быть написан непосредственно в javascript с использованием JS-версии API.
Так что, используя плагин interactive_webview для трепетания, я переведу весь код Android в js... и все. Мне больше не нужно беспокоиться о написании конкретного кода платформы для iOS и Android. Плюс приложение флаттера по умолчанию работает в фоновом режиме (наверное).
Эта ошибка возникает при попытке запустить код дротика, когда приложение находится в мусоре (приложение закрыто). До сих пор лучший способ справиться с фоновой службой - делать то, что вам нужно в собственном коде, и не пытаться запускать что-либо из дротика, когда приложение закрыто.
Поскольку плагины и каналы платформы Flutter 3.7 можно использовать из любого изолята, а не только из корневого.
Использованная литература: