Flutter类微信小程序,InAppWebview关闭后保持状态KeepAlive
最近接到一个需求,Flutter应用中用户打开一些Web3的网页游戏加载比较耗时,希望临时退出的时候可以像微信小程序一样,网页可以恢复退出前的状态,最好可以做到后台挂机。
实现方式
恰好前几个月更新InAppWebview6.0版本插件的时候,看到一个新特KeepAlive 。官方解释是:该功能用于在从布局树中移除与之对应的 Flutter 组件后,使原生 WebView 继续在后台运行,而不是将其销毁。
关键属性keepAlive 的值是一个InAppWebViewKeepAlive实例,所有使用相同实例的其它 InAppWebView 都将以相同的设置渲染相同的原生 WebView。
每个 InAppWebViewKeepAlive 实例只能有一个活跃的 InAppWebView 。 试图将同一个 InAppWebViewKeepAlive 实例用于两个活跃的 InAppWebView 会导致崩溃。
示例
下面是一个使用相同的 InAppWebViewKeepAlive 在两个不同的页面中渲染相同WebView的例子。 当你从页面A切换到页面B或反之亦然时, InAppWebView 会重新加载相同的原生WebView而不会重新加载,并保持当前WebView的原生状态(当前URL、滚动位置等),就好像你从未从Flutter组件树中删除它一样。
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
final keepAlive = InAppWebViewKeepAlive();
Future main() async {
WidgetsFlutterBinding.ensureInitialized();
if (!kIsWeb && defaultTargetPlatform == TargetPlatform.android) {
await InAppWebViewController.setWebContentsDebuggingEnabled(kDebugMode);
}
runApp(const MaterialApp(home: PageA()));
}
class PageA extends StatelessWidget {
const PageA({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Page A - Keep Alive Example'),
actions: [
ElevatedButton(
onPressed: () {
Navigator.of(context).pushReplacement(
MaterialPageRoute(
builder: (context) => const PageB(),
),
);
},
child: const Text('Go To Page B'))
],
),
body: Column(children: <Widget>[
Expanded(
child: InAppWebView(
keepAlive: keepAlive,
initialUrlRequest:
URLRequest(url: WebUri("http://github.com/flutter")),
initialSettings: InAppWebViewSettings(
isInspectable: kDebugMode,
),
),
)
]),
);
}
}
class PageB extends StatelessWidget {
const PageB({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Page B - Keep Alive Example'),
actions: [
ElevatedButton(
onPressed: () {
Navigator.of(context).pushReplacement(
MaterialPageRoute(
builder: (context) => const PageA(),
),
);
},
child: const Text('Go To Page A'))
],
),
body: Column(children: <Widget>[
Expanded(
child: InAppWebView(
keepAlive: keepAlive,
),
)
]),
);
}
}
结合咱们的需求,只需要首次创建Webview的时候创建InAppWebViewKeepAlive 实例,退出页面后保存该实例,恢复页面的时候使用保存的实例恢复。
注意事项
恢复WebView的时候无需设置initialUrlRequest ,即使设置了也不会生效。
使用同一个InAppWebViewKeepAlive 实例的页面,只有一个能处于活跃状态,否则会引发崩溃。
由于我的需求要求很低,没做过多测试。目前发现网页进入后台,似乎计数器还在工作,音乐停止了。更多细节比如内存占用等需要自行研究,这里只是提供一个思路。
这点非常重要!保持状态只能保持InAppWebview这个Widget的状态,页面内部的其他自定义的状态并不会保存,需要自己处理,建议页面和状态分离比较好操作。
- 1
- 0
-
赞助
微信支付宝 -
分享