Android返回键中断启动页计时器导致启动页卡顿问题
启动页倒计时跳转的Android设备异常问题及优化方案
我实现了一个带倒计时的启动页,倒计时结束后自动跳转到首页或登录页。但在Android设备上发现异常:若在倒计时结束前按下硬件返回键,之后重新打开应用,首页会短暂显示,接着启动页重新打开并卡顿,只能彻底关闭应用再重启才能恢复。该问题在iOS设备上用Home键操作时不会出现。
目前我通过在启动页显示期间禁用返回键实现了临时修复,但希望了解更优的启动页与Form管理方式。
复现步骤
- 启动应用进入启动页
- 在启动页倒计时结束前按下Android返回键
- 重新打开应用,首页短暂显示后切换至启动页
- 启动页卡顿
- 仅能通过关闭并重新打开应用恢复
测试代码示例
public class TestCase extends Lifecycle { @Override public void runApp() { Form splash = SplashPage(); splash.show(); new UITimer(() -> { HomePage(); }).schedule(3000, false, splash); } public Form SplashPage(){ Form formSplash = new Form(new BorderLayout()); formSplash.getToolbar().setUIID("Container"); formSplash.getToolbar().hideToolbar(); Container northcnt = new Container(new BoxLayout(BoxLayout.Y_AXIS)); Container centercnt = new Container(new BoxLayout(BoxLayout.Y_AXIS)); centercnt.setScrollableY(true); Container southcnt = new Container(new BoxLayout(BoxLayout.Y_AXIS)); // 临时修复代码已注释 // formSplash.setBackCommand(new Command("") { // public void actionPerformed(ActionEvent ev) { // ///DO NOTHING // Log.p("Android back button pressed"); // } // }); centercnt.add(new Label("Splash Page")); ((BorderLayout)formSplash.getLayout()).setCenterBehavior(BorderLayout.CENTER_BEHAVIOR_CENTER_ABSOLUTE); formSplash.add(BorderLayout.NORTH, northcnt).add(BorderLayout.CENTER, centercnt).add(BorderLayout.SOUTH, southcnt); return formSplash; } public void HomePage(){ Form formHome = new Form(new BorderLayout()); formHome.getToolbar().setUIID("Container"); formHome.getToolbar().hideToolbar(); Container northcnt = new Container(new BoxLayout(BoxLayout.Y_AXIS)); Container centercnt = new Container(new BoxLayout(BoxLayout.Y_AXIS)); centercnt.setScrollableY(true); Container southcnt = new Container(new BoxLayout(BoxLayout.Y_AXIS)); centercnt.add(new Label("Home Page")); ((BorderLayout)formHome.getLayout()).setCenterBehavior(BorderLayout.CENTER_BEHAVIOR_CENTER_ABSOLUTE); formHome.add(BorderLayout.NORTH, northcnt).add(BorderLayout.CENTER, centercnt).add(BorderLayout.SOUTH, southcnt); formHome.show(); } private void hello() { Dialog.show("Hello Codename One", "Welcome to Codename One", "OK", null); } }
优化方案
1. 管理UITimer生命周期,避免后台执行
原代码中UITimer绑定到启动页Form,但用户按下返回键退出后,Timer并未被取消,仍会在后台执行跳转逻辑,导致应用状态混乱。需在Form销毁时取消Timer:
public Form SplashPage(){ Form formSplash = new Form(new BorderLayout()); // ...原代码其他逻辑 // 将Timer创建与销毁绑定到Form生命周期 formSplash.addShowListener(e -> { UITimer timer = new UITimer(() -> HomePage()); timer.schedule(3000, false, formSplash); // 监听Form销毁事件,取消Timer formSplash.addDisposeListener(disposeEvent -> timer.cancel()); }); return formSplash; }
2. 记录启动状态,避免重复显示启动页
应用重启时,判断是否已完成启动流程,用Preferences存储状态:
@Override public void runApp() { boolean hasLaunched = Preferences.get("hasLaunched", false); if(hasLaunched){ HomePage(); } else { Form splash = SplashPage(); splash.show(); } } public void HomePage(){ // ...原代码其他逻辑 // 标记启动完成 Preferences.set("hasLaunched", true); formHome.show(); }
注:用户首次安装或清除应用数据时,标记会重置,确保启动页正常显示。
3. 优化Form切换,清理旧页面
用showAndReplace()替代show(),切换时销毁旧Form,避免Form栈残留导致状态异常:
public void HomePage(){ // ...原代码其他逻辑 formHome.showAndReplace(); }
4. 优雅处理Android返回键
比起直接禁用返回键,按下返回键时直接退出应用并取消Timer,符合Android用户操作习惯:
formSplash.setBackCommand(new Command("") { public void actionPerformed(ActionEvent ev) { // 取消所有Timer UITimer.cancelAll(); // 退出应用 Display.getInstance().exitApplication(); } });
内容的提问来源于stack exchange,提问作者James N
相关产品推荐
相关产品推荐

