使用导航器时,如何解决方法'ancestorStateOfType'在null上调用?

时间:2019-08-08 08:08:11

标签: flutter dart firebase-dynamic-links

我正在使用firebase_dynamic_links:^ 0.5.0在我的flutter应用程序中实现设置密码功能。由管理员创建用户时,用户会收到一封电子邮件。这封电子邮件中有一个动态链接。单击后,用户将被重定向到 1.应用商店/游戏商店(如果他/她没有应用)。 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):返回中继: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:中继返回: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:中继返回: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:中继返回:oldFrame = [0,0] [1440,2560] newFrame = [0,0] [1440,2560] result = 0x1 surface = {isValid = false 0} surfaceGenerationChanged = false D / SurfaceView(25703):返回中继: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 *,EGLBoolean)返回0x3000,[1440x2560] -format:1 I / Flutter(25703):querParam = e144efdbd666e615a47ebe18e25a556d D / ViewRootImpl @ 5c26021MainActivity:中继返回:oldFrame = [0,0] [1440,2560] newFrame = [0,0] [1440,2560] result = 0x7 surface = {isValid = true 542519654912} surfaceGenerationChanged = 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,[1440x2560] -format: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 = 93

E / flutter(25703):[错误:flutter / lib / ui / ui_dart_state.cc(148)]未处理的异常:NoSuchMethodError:方法'ancestorStateOfType'被调用为null。 E / flutter(25703):接收者:null E / flutter(25703):尝试调用:ancestorStateOfType(“ TypeMatcher”的实例) E / flutter(25703):#0 Object.noSuchMethod(dart:core-patch / object_patch.dart:50:5)

1 个答案:

答案 0 :(得分:0)

这是库本身的问题。由于您当前无法访问context,因此无法访问。因此,我建议您在MaterialAppCupertinoApp

内创建全局导航器状态
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(),
    );
  }
}