flutter - 使用 Navigator 时,如何解决在 null 上调用了“ancestorStateOfType”方法?
问题描述
我正在使用 firebase_dynamic_links: ^0.5.0 在我的颤振应用程序中实现设置密码功能。当管理员创建用户时,用户会收到一封电子邮件。在这封电子邮件中有一个动态链接。点击它后,如果他/她没有应用程序,用户将被重定向到 1.App 商店/Play 商店。2.如果应用程序已经安装,在应用程序中打开设置密码屏幕。firebase_dynamic_links 提供了两种方法:- 1.getInitialLink 未来检索打开应用程序的链接。2.onLink 一个回调来监听应用程序处于活动状态或后台时打开的链接。
当应用程序处于终止状态并按下链接时一切顺利,但是当应用程序处于后台时,导航不起作用。
void main() => runApp(MaterialApp(
theme: new ThemeData(
primaryColor: Colours.appThemeColour,
),
onGenerateRoute: (RouteSettings settings) {
switch (settings.name) {
case '/': return new MyCustomRoute(
builder: (_) => new SplashScreen(),
settings: settings,
);
case '/setpassword': return new MyCustomRoute(
builder: (_) => new SetPassword(settings.arguments),
settings: settings,
);
...
}
}
)
);
class SplashScreen extends StatefulWidget {
@override
_SplashScreenState createState() => new _SplashScreenState();
}
class _SplashScreenState extends State<SplashScreen> {
Uri deepLink;
_handleDeepLink(Uri deepLink) async{
if (deepLink != null) {
print("querParam=${deepLink.queryParameters["token"]}");
if(deepLink.queryParameters["otp"].toString()=="1"){
if(deepLink.queryParameters["token"]!=null){
String _status =await _networkUtil.verifyUser(deepLink.queryParameters["token"].toString());
Navigator.of(context).pushReplacementNamed('/setpassword',arguments: _status );
}else{
Navigator.of(context).pushReplacementNamed('/setpassword',arguments: "unknownError" );
}
}
else{
if(deepLink.queryParameters["token"]!=null){
String _status =await _networkUtil.verifyUser(deepLink.queryParameters["token"].toString());
SchedulerBinding.instance.addPostFrameCallback((_) {
Navigator.of(context).pushReplacementNamed('/resetpassword');
});
}else{
Navigator.of(context).pushReplacementNamed('/resetpassword');
}
}
}
}
}
initDynamicLinks() async {
final PendingDynamicLinkData data = await FirebaseDynamicLinks.instance.getInitialLink();
final Uri deepLink = data?.link;
if (deepLink != null) {
_handleDeepLink(deepLink);
}
FirebaseDynamicLinks.instance.onLink(
onSuccess: (PendingDynamicLinkData dynamicLink) async {
final Uri deepLink = dynamicLink?.link;
_handleDeepLink(deepLink);
},
onError: (OnLinkErrorException e) async {
print('onLinkError');
print(e.message);
}
);
}
@override
initState(){
initDynamicLinks().then((){
...
});
}
当应用程序在后台并单击链接时,它应该导航到设置密码屏幕,但它(通过我在下面提到的一个例外)进入当应用程序移动到后台时打开的那个屏幕。
D/ViewRootImpl@5c26021MainActivity:MSG_WINDOW_FOCUS_CHANGED 0 D/SurfaceView(25703):Relayout 返回:oldFrame=[0,0][1440,2560] newFrame=[0,0][1440,2560] result=0x5 surface={Surface( name=null)/@0x54b5e07 isValid=false 0} D/ViewRootImpl@5c26021MainActivity:mHardwareRenderer.destroy()#1 D/ViewRootImpl@5c26021MainActivity:Relayout 返回:oldFrame=[0,0][1440,2560] newFrame=[0 ,0][1440,2560] result=0x5 surface={isValid=false 0} surfaceGenerationChanged=true D/InputTransport(25703): 输入通道被破坏: fd=92 D/ViewRootImpl@5c26021MainActivity: mHardwareRenderer.destroy()#1 D /ViewRootImpl@5c26021MainActivity:Relayout 返回:oldFrame=[0,0][1440,2560] newFrame=[0,0][1440,2560] result=0x1 surface={isValid=false 0} surfaceGenerationChanged=false D/ViewRootImpl@ 5c26021MainActivity:mHardwareRenderer。destroy()#1 D/ViewRootImpl@5c26021MainActivity:Relayout 返回:oldFrame=[0,0][1440,2560] newFrame=[0,0][1440,2560] result=0x1 surface={isValid=false 0} surfaceGenerationChanged =false D/SurfaceView(25703): Relayout 返回: oldFrame=[0,0][1440,2560] newFrame=[0,0][1440,2560] result=0x7 surface={Surface(name=null)/@ 0x54b5e07 isValid=true 543154356736} D/mali_winsys(25703): EGLint new_window_surface(egl_winsys_display*, void*, EGLSurface, EGLConfig, egl_winsys_surface**, egl_color_buffer_format*, EGLBolean) 返回 0x3000, [1440x2560]-3:1/70 格式): querParam=e144efdbd666e615a47ebe18e25a556d D/ViewRootImpl@5c26021MainActivity: Relayout 返回: oldFrame=[0,0][1440,2560] newFrame=[0,0][1440,2560] result=0x7 surface={isValid=true 542519654912} surfaceGeneration =true D/ViewRootImpl@5c26021MainActivity:mHardwareRenderer。initialize() mSurface={isValid=true 542519654912} hwInitialized=true D/mali_winsys(25703): EGLint new_window_surface(egl_winsys_display*, void*, EGLSurface, EGLConfig, egl_winsys_surface**, egl_color_buffer_format*, EGLBoolean) 返回 0x3000, [1440x2]-5格式:1 D/ViewRootImpl@5c26021MainActivity:MSG_WINDOW_FOCUS_CHANGED 1 D/ViewRootImpl@5c26021MainActivity:mHardwareRenderer.initializeIfNeeded()#2 mSurface={isValid=true 542519654912} V/InputMethodManager(25703):开始输入:tba=android.view.inputmethod。 EditorInfo@6fb193a nm:com.root.amployee ic=null I/InputMethodManager(25703):[IMM] startInputInner - mService.startInputOrWindowGainedFocus D/InputTransport(25703):输入通道构造:fd=93EGLSurface, EGLConfig, egl_winsys_surface**, egl_color_buffer_format*, EGLBolean) 返回 0x3000, [1440x2560]-format:1 D/ViewRootImpl@5c26021MainActivity: MSG_WINDOW_FOCUS_CHANGED 1 D/ViewRootImpl@5c26021MainActivity: mHardwareRenderer.initialize={mHardwareRenderer.initializeIfisValided=true) 542519654912} V/InputMethodManager(25703): 开始输入: tba=android.view.inputmethod.EditorInfo@6fb193a nm: com.root.amployee ic=null I/InputMethodManager(25703): [IMM] startInputInner - mService.startInputOrWindowGainedFocus D/ InputTransport(25703):输入通道构造:fd=93EGLSurface, EGLConfig, egl_winsys_surface**, egl_color_buffer_format*, EGLBolean) 返回 0x3000, [1440x2560]-format:1 D/ViewRootImpl@5c26021MainActivity: MSG_WINDOW_FOCUS_CHANGED 1 D/ViewRootImpl@5c26021MainActivity: mHardwareRenderer.initialize={mHardwareRenderer.initializeIfisValided=true) 542519654912} V/InputMethodManager(25703): 开始输入: tba=android.view.inputmethod.EditorInfo@6fb193a nm: com.root.amployee ic=null I/InputMethodManager(25703): [IMM] startInputInner - mService.startInputOrWindowGainedFocus D/ InputTransport(25703):输入通道构造:fd=93initializeIfNeeded()#2 mSurface={isValid=true 542519654912} V/InputMethodManager(25703):开始输入:tba=android.view.inputmethod.EditorInfo@6fb193a nm:com.root.amployee ic=null I/InputMethodManager(25703) :[IMM] startInputInner - mService.startInputOrWindowGainedFocus D/InputTransport(25703):输入通道构造:fd=93initializeIfNeeded()#2 mSurface={isValid=true 542519654912} V/InputMethodManager(25703):开始输入:tba=android.view.inputmethod.EditorInfo@6fb193a nm:com.root.amployee ic=null I/InputMethodManager(25703) :[IMM] startInputInner - mService.startInputOrWindowGainedFocus D/InputTransport(25703):输入通道构造:fd=93
E/flutter(25703):[错误:flutter/lib/ui/ui_dart_state.cc(148)]未处理的异常:NoSuchMethodError:方法'ancestorStateOfType'被调用为null。E/flutter(25703):接收者:null E/flutter(25703):尝试调用:ancestStateOfType('TypeMatcher'的实例) E/flutter(25703):#0 Object.noSuchMethod(dart:core-patch/object_patch.dart :50:5)
解决方案
这是图书馆本身的问题。因为context
目前无法访问您访问的内容。所以我建议你在你的MaterialApp
or中创建全局导航器状态CupertinoApp
class MyApp extends StatefulWidget {
@override
State<StatefulWidget> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final _navigatorKey = GlobalKey<NavigatorState>();
@override
Widget build(BuildContext context) {
return MaterialApp(
key: _navigatorKey,
home: Container(),
);
}
}
推荐阅读
- github - 将多个现有的 git 存储库移动到一个新的父存储库中
- angular - Angular 2.0.0 的文本编辑器
- flutter - 有没有办法让firebase实时数据库存在系统更快地检测到断开连接?
- bash - 如何在 Linux 的命令中插入单词?
- python - Python正在输出带有字符串引号的json
- excel - 图像控制用户窗体替代
- ios - 列表未在 SwiftUI 中显示来自 API 的数据?
- amazon-web-services - 命名 AWS EC2 安全组
- python-2.7 - 在python2.7中导入jwcrypto时出错
- c# - 使用 ClosedXML.Excel C# 更改列样式