如何避免切换应用时我的CN1应用重启并保留运行状态?
问题:Codename One应用切出后台后返回,重新启动闪屏无法恢复原界面
我需要让应用在失去焦点后再次返回时,从之前中断的位置继续运行。但目前每次切出再切回应用,都会重新执行闪屏动画,回到初始界面。这个问题在真机和模拟器上都会出现。
主类代码
public class TarifaTaxiPredictivo extends Lifecycle { private Usuario iU; @Override public void runApp() { String sIdioma = L10NManager.getInstance().getLanguage().toLowerCase();// Salva el tipo de idioma if (!sIdioma.equals(IDIOMA_INGLES) && !sIdioma.equals(IDIOMA_ESPANOL)) { sIdioma = IDIOMA_ESPANOL; } iU = Usuario.getInstancia(); iU.setIdioma(sIdioma); iU.setAumento(calculatePorcentajeAumento()); showSplashAnimation(); } public void showSplashAnimation() { Form splash = new Form(new LayeredLayout()); splash.setUIID("Splash"); ScaleImageLabel iconBackground = new ScaleImageLabel(getGlobalResources().getImage("attt.png")); iconBackground.setBackgroundType(Style.BACKGROUND_IMAGE_SCALED_FILL); Container centerBackground = BorderLayout.center(iconBackground); splash.add(centerBackground); Label iconForeground = new Label(getGlobalResources().getImage("attt.png")); Container centerIcon = BorderLayout.centerAbsolute(iconForeground); splash.add(centerIcon); splash.show(); Display.getInstance().callSerially(() -> { ((BorderLayout) centerBackground.getLayout()).setCenterBehavior(BorderLayout.CENTER_BEHAVIOR_CENTER_ABSOLUTE); centerBackground.setShouldCalcPreferredSize(true); centerBackground.animateLayoutAndWait(2000); iconForeground.remove(); iconBackground.remove(); centerIcon.remove(); Container cnFondo = LayeredLayout.encloseIn( new Label(iconBackground.getIcon(), "CenterIcon")); Container boxy = BoxLayout.encloseY(cnFondo); Label placeholder = new Label(); placeholder.setShowEvenIfBlank(true); Label lbTit = new Label("Tarifa de Taxi", "SplashSubTitulo"); Component.setSameHeight(placeholder, lbTit); Component.setSameWidth(placeholder, lbTit, boxy); centerBackground.add(BorderLayout.CENTER, boxy); splash.revalidate(); Display.getInstance().callSerially(() -> { placeholder.setText(" "); boxy.add(placeholder); boxy.setShouldCalcPreferredSize(true); boxy.getParent().animateLayoutAndWait(1500); boxy.replaceAndWait(placeholder, lbTit, CommonTransitions.createFade(1500)); Label lbNuevoTitulo = new Label(" "); Label lbTitulo = new Label("ATTT", "SplashTitulo"); Component.setSameHeight(lbNuevoTitulo, lbTitulo); Component.setSameWidth(lbNuevoTitulo, lbTitulo); boxy.add(lbNuevoTitulo); boxy.getParent().animateLayoutAndWait(250); boxy.replaceAndWait(lbNuevoTitulo, lbTitulo, CommonTransitions.createFade(3000)); new Tarifa().show(); }); }); } }
相关截图

解决方案
问题根源:Codename One的Lifecycle.runApp()方法会在应用首次启动和从后台恢复时被调用,当前代码每次执行runApp()都会直接启动闪屏,导致恢复时重新初始化。
修改方案
- 添加初始化状态标记,避免重复执行初始化逻辑
- 保存当前显示的Form,恢复时直接显示该Form
- 重写
pause()方法保存应用状态,resume()方法可添加额外恢复逻辑
修改后的代码
public class TarifaTaxiPredictivo extends Lifecycle { private Usuario iU; private boolean isAppInitialized = false; private Form currentForm; // 保存当前活跃的Form @Override public void runApp() { if (!isAppInitialized) { // 首次启动时执行初始化逻辑 String sIdioma = L10NManager.getInstance().getLanguage().toLowerCase(); if (!sIdioma.equals(IDIOMA_INGLES) && !sIdioma.equals(IDIOMA_ESPANOL)) { sIdioma = IDIOMA_ESPANOL; } iU = Usuario.getInstancia(); iU.setIdioma(sIdioma); iU.setAumento(calculatePorcentajeAumento()); showSplashAnimation(); isAppInitialized = true; } else { // 应用从后台恢复,显示之前的界面 if (currentForm != null) { currentForm.show(); } else { // 兜底逻辑:如果没有保存的Form,直接显示主界面 currentForm = new Tarifa(); currentForm.show(); } } } @Override public void pause() { // 应用进入后台时,保存当前显示的Form currentForm = Display.getInstance().getCurrent(); super.pause(); } @Override public void resume() { super.resume(); // 可选:添加界面数据刷新等恢复逻辑 } public void showSplashAnimation() { Form splash = new Form(new LayeredLayout()); splash.setUIID("Splash"); ScaleImageLabel iconBackground = new ScaleImageLabel(getGlobalResources().getImage("attt.png")); iconBackground.setBackgroundType(Style.BACKGROUND_IMAGE_SCALED_FILL); Container centerBackground = BorderLayout.center(iconBackground); splash.add(centerBackground); Label iconForeground = new Label(getGlobalResources().getImage("attt.png")); Container centerIcon = BorderLayout.centerAbsolute(iconForeground); splash.add(centerIcon); splash.show(); Display.getInstance().callSerially(() -> { ((BorderLayout) centerBackground.getLayout()).setCenterBehavior(BorderLayout.CENTER_BEHAVIOR_CENTER_ABSOLUTE); centerBackground.setShouldCalcPreferredSize(true); centerBackground.animateLayoutAndWait(2000); iconForeground.remove(); iconBackground.remove(); centerIcon.remove(); Container cnFondo = LayeredLayout.encloseIn( new Label(iconBackground.getIcon(), "CenterIcon")); Container boxy = BoxLayout.encloseY(cnFondo); Label placeholder = new Label(); placeholder.setShowEvenIfBlank(true); Label lbTit = new Label("Tarifa de Taxi", "SplashSubTitulo"); Component.setSameHeight(placeholder, lbTit); Component.setSameWidth(placeholder, lbTit, boxy); centerBackground.add(BorderLayout.CENTER, boxy); splash.revalidate(); Display.getInstance().callSerially(() -> { placeholder.setText(" "); boxy.add(placeholder); boxy.setShouldCalcPreferredSize(true); boxy.getParent().animateLayoutAndWait(1500); boxy.replaceAndWait(placeholder, lbTit, CommonTransitions.createFade(1500)); Label lbNuevoTitulo = new Label(" "); Label lbTitulo = new Label("ATTT", "SplashTitulo"); Component.setSameHeight(lbNuevoTitulo, lbTitulo); Component.setSameWidth(lbNuevoTitulo, lbTitulo); boxy.add(lbNuevoTitulo); boxy.getParent().animateLayoutAndWait(250); boxy.replaceAndWait(lbNuevoTitulo, lbTitulo, CommonTransitions.createFade(3000)); // 闪屏结束后,保存主界面Form currentForm = new Tarifa(); currentForm.show(); }); }); } }
修改说明
isAppInitialized标记确保初始化逻辑只执行一次currentForm变量在pause()时保存当前界面,恢复时直接显示- 闪屏结束后主动保存主界面Form,避免空指针
- 添加兜底逻辑,防止异常情况导致无法恢复界面
内容的提问来源于stack exchange,提问作者Rubén Villarreal
相关产品推荐
相关产品推荐

