Flutter 实现统一处理Token过期后跳转登录页面
1 方式一:使用全局GlobalKey
1.1 创建全局GlobalKey
配置路由 并设置 globalNavigatorKey
final GlobalKey<NavigatorState> globalNavigatorKey = GlobalKey();
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
// 配置路由 并设置 globalNavigatorKey
return MaterialApp(
initialRoute: "/",
navigatorKey: globalNavigatorKey,
onGenerateRoute: (settings) {
final routeName = settings.name;
switch (routeName) {
case "/":
return ...
case "/login":
return MaterialPageRoute(
builder: (context) => const LoginPage(),
);
case "/tabPage":
return MaterialPageRoute(builder: (context) => const TabPage());
default:
return ...;
}
},
);
}
}
1.2 网络请求拦截器中检测到Token过期则跳转页面
此处使用网络请求框架是 dio
,添加拦截器,并使用 globalNavigatorKey 跳转登录页面。
// 添加拦截器
final dio = Dio()..interceptors.add(ApiInterceptor());
class ApiInterceptor extends InterceptorsWrapper {
@override
void onError(DioError err, ErrorInterceptorHandler handler) {
super.onError(err, handler);
int? statusCode = err.response?.statusCode;
if (statusCode == 401) {
// 跳转登录页面并清空栈
globalNavigatorKey.currentState
?.pushNamedAndRemoveUntil('/login', (route) => false);
}
}
}
1.3 可能出现的问题
当同时存在多个网络请求时,拦截器中跳转登录页面的操作可能会同时调用几次,出现多次跳转登录页面的情况。
2 方式二:使用事件总线
2.1 创建事件总线
class EventBus {
//私有构造函数
EventBus._internal();
static EventBus? _instance;
static EventBus get instance => _getInstance();
static EventBus _getInstance() {
return _instance ??= EventBus._internal();
}
// 存储事件回调方法
final Map<String, Function> _events = {};
// 设置事件监听
void addListener(String eventKey, Function callback) {
_events[eventKey] = callback;
}
// 移除监听
void removeListener(String eventKey) {
_events.remove(eventKey);
}
// 提交事件
void commit(String eventKey) {
_events[eventKey]?.call();
}
}
class EventKeys {
static const String logout = "Logout";
}
2.2 监听登出事件
登录成功后,在主页面设置登出事件监听,事件响应后立即移除监听。
class TabPage extends StatefulWidget {
const TabPage({Key? key}) : super(key: key);
@override
State<TabPage> createState() => _TabPageState();
}
class _TabPageState extends State<TabPage> {
@override
void initState() {
super.initState();
EventBus.instance.addListener(EventKeys.logout, () {
// 移除事件监听
EventBus.instance.removeListener(EventKeys.logout);
// 跳转登录页面
Navigator.of(context).pushNamedAndRemoveUntil('/login', (route) => false);
});
}
@override
void dispose() {
// 移除事件监听
EventBus.instance.removeListener(EventKeys.logout);
super.dispose();
}
@override
Widget build(BuildContext context) {
return ...
}
}
2.3 网络请求拦截器中触发登出事件
final dio = Dio()..interceptors.add(ApiInterceptor());
class ApiInterceptor extends InterceptorsWrapper {
@override
void onError(DioError err, ErrorInterceptorHandler handler) {
super.onError(err, handler);
int? statusCode = err.response?.statusCode;
if (statusCode == 401) {
// 触发登出事件
EventBus.instance.commit(EventKeys.logout);
}
}
}
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgbjihc
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
怎样阻止微信小程序自动打开
PHP中文网 06-13