【问题标题】:BlackBerry: "Application is not responding; process terminated" because of UiApplication.getUiApplication().popScreen()?黑莓:“应用程序没有响应;进程终止”因为 UiApplication.getUiApplication().popScreen()?
【发布时间】:2011-07-27 18:06:28
【问题描述】:

我有一个黑莓应用程序,当它在一些支持触摸的模拟器(例如:9500、9520、9530、9550)中运行时,会以:

“应用程序没有响应;进程 XPTO 终止”

使用日志,我发现应用程序似乎在我异步发出 HTTP 请求的类中停止:类似于:

public class LoadingFullScreen extends FullScreen implements Runnable {

    private Thread actionThread = null;

    protected void onDisplay() {
        actionThread = new Thread(this);
        actionThread.start();
    }

    protected void onUndisplay() {
        if(actionThread != null && actionThread.isAlive()) {
            actionThread.interrupt();
        }
    }

    public void run() {
        //make http requests - this is done successfully

        synchronized(Application.getEventLock()) {
                Screen active = UiApplication.getUiApplication().getActiveScreen();
                if (active instanceof LoadingFullScreen) {
                    Logger.debug("LoadingFullScreen popping screen"); //this appears in logs
                    UiApplication.getUiApplication().popScreen(active);
                    Logger.debug("LoadingFullScreen screen popped"); //this never appears in logs
                }
        }
    }
}

我用UiApplication.getUiApplication().pushModalScreen(new LoadingFullScreen()) 启动这个屏幕

在日志中我可以看到:

[0.0] Wed Jul 27 17:53:06 GMT 2011 - DEBUG: LoadingFullScreen popping screen
[0.0] JVM: bklt[1] @163148: JBSC on=0
[0.0] JVM: bklt[1] @163148: SC 0
[0.0] JVM: bklt[1]: setTimeout 30
[0.0] Application XPTO(212) is not responding; process terminated

似乎UiApplication.getUiApplication().popScreen() 阻止了应用程序,因此操作系统杀死了应用程序,但为什么呢?

编辑:
我也尝试过使用

UiApplication.getUiApplication().invokeLater(new Runnable() {...} };            

而不是synchronized(Application.getEventLock()) {...},但我得到完全相同的结果

编辑 2:
我也试过 active.close() 而不是 UiApplication.getUiApplication().popScreen(active); 但我得到了完全相同的结果

编辑 3: 使用javaloader,我从模拟器中得到了这种堆栈跟踪:

guid:0x9C3CD62E3320B498 time: Thu Jul 28 15:02:50 2011  severity:0 type:3 app:Java Exception data:
    ForcedStackTraceException
    net_rim_services_impl(4) 27 2 0x1030B000
    net_rim_os-3(4BEF0320)
     HttpConnectionManager$CleanupThread
     run
     0x3B09
guid:0x9C3CD62E3320B498 time: Thu Jul 28 15:02:50 2011  severity:0 type:3 app:Java Exception data:
    ForcedStackTraceException
    XPTO(247) 60 4 0x124A0400
    net_rim_cldc-16(4BEEF8A5)
     TextField
     getFocusRect
     0x2A61
    net_rim_cldc-12(4BEEF8A5)
     Manager
     getFocusRect
     0x717
    net_rim_cldc-12(4BEEF8A5)
     Manager
     getFocusRect
     0x717
    net_rim_cldc-12(4BEEF8A5)
     Screen
     getFocusRect
     0x9AF2
    net_rim_cldc-12(4BEEF8A5)
     Screen
     callOnExposed
     0x9D16
    net_rim_cldc-13(4BEEF8A5)
     UiEngineImpl
     <private>
     0x9007
    net_rim_cldc-13(4BEEF8A5)
     UiEngineImpl
     removeScreen
     0x7D08
    net_rim_cldc-12(4BEEF8A5)
     Screen
     close
     0x6B66
    XPTO-8(4E316B06)
     LoadingFullScreen$1
     run
     0x34D5
    net_rim_cldc-8(4BEEF8A5)
     Application
     dispatchInvokeLater
     0x1A87
    net_rim_cldc-8(4BEEF8A5)
     Application
     <private>
     0x2809
    net_rim_cldc-8(4BEEF8A5)
     Application
     processNextMessage
     0x1AEF
    net_rim_cldc-9(4BEEF8A5)
     ModalEventThread
     run
     0xBE4F
guid:0x9C3CD62E3320B498 time: Thu Jul 28 15:02:50 2011  severity:0 type:3 app:Java Exception data:
    ForcedStackTraceException
    XPTO(247) 30 2 0x139DA800
    net_rim_cldc(4BEEF8A5)
     Object
     wait
     0x9922
    net_rim_cldc-8(4BEEF8A5)
     Application
     startModalEventThread
     0x1EB8
    net_rim_cldc-13(4BEEF8A5)
     UiEngineImpl
     addScreenModal
     0x83F4
    net_rim_cldc-13(4BEEF8A5)
     UiEngineImpl
     pushModalScreen
     0x674E
    net_rim_cldc-13(4BEEF8A5)
     UiApplication
     pushModalScreen
     0x62B0
    XPTO-8(4E316B06)
     MyBaseScreen
     <private>
     0x3AA6
    XPTO-8(4E316B06)
     MyBaseScreen
     openTheModalScreenFunction
     0x382C
    XPTO-8(4E316B06)
     MyBaseScreen$4
     fieldChanged
     0x4271
    net_rim_cldc-11(4BEEF8A5)
     Field
     fieldChangeNotify
     0x160B
    net_rim_cldc-16(4BEEF8A5)
     TextField
     replace
     0x7A5
    net_rim_cldc-16(4BEEF8A5)
     TextField
     inputMethodTextChanged
     0x24E1
    net_rim_cldc-15(4BEEF8A5)
     PasswordEditField
     inputMethodTextChanged
     0x4F26
    net_rim_cldc-27(4BEEF8A5)
     IMContext
     dispatchInputMethodEvent
     0x1E00
    net_rim_tid-4(4BEEF8E1)
     SLInputMethod
     sendComposedText
     0x5CA1
    net_rim_tid-4(4BEEF8E1)
     SLInputMethod
     sendComposedText
     0x5BD1
    net_rim_tid_fastEuropean(4BEF034C)
     FastEuropeanInputMethod
     sendComposedText
     0x48E1
    net_rim_tid_fastEuropean(4BEF034C)
     FastEuropeanInputMethod
     dispatchConversionEvent
     0x43E3
    net_rim_tid-4(4BEEF8E1)
     SLInputMethod
     dispatchKeyEvent
     0x5309
    net_rim_tid-4(4BEEF8E1)
     SLInputMethod
     dispatchEvent
     0x63CA
    net_rim_tid_fastEuropean(4BEF034C)
     FastEuropeanInputMethod
     dispatchEvent
     0x426E
    net_rim_cldc-27(4BEEF8A5)
     InputContext
     dispatchEvent
     0x3E15
    net_rim_cldc-27(4BEEF8A5)
     IMContext
     dispatchEvent
     0x21DE
    net_rim_cldc-11(4BEEF8A5)
     Field
     dispatchEvent
     0x3739
    net_rim_cldc-16(4BEEF8A5)
     TextField
     dispatchEvent
     0x30F6
    net_rim_cldc-27(4BEEF8A5)
     EventHandler
     <private>
     0x1460
    net_rim_cldc-27(4BEEF8A5)
     EventHandler
     processKeyEvent
     0x1A79
    net_rim_cldc-16(4BEEF8A5)
     TextField
     processKeyEvent
     0x37F6
    net_r

编辑 4: 我试图将LoadingFullScreen 中的run() 方法移动到新的Runnable 类,因为有人告诉我,当该类显示为模式屏幕时,拥有LoadingFullScreen implement Runnable 可能会导致问题。
但是,我没有运气,我仍然遇到同样的问题。
有什么想法吗?

编辑 5: 在这里解决:BlackBerry: "Application is not responding; process terminated" because of UiApplication.getUiApplication().popScreen()?

【问题讨论】:

  • 您是否在“活动”上使用任何覆盖,例如onClose()?
  • 嗨,雷。我正在覆盖 onDisplay 和 onUndisplay。我正在编辑帖子,添加这些方法
  • 我用UiApplication.getUiApplication().pushModalScreen(new LoadingFullScreen())启动这个屏幕,有影响吗?
  • modal 用于从屏幕获取响应。例如。允许用户选择某些内容的弹出屏幕,我认为它不会导致此问题。您可能应该将其更改为 pushScreen() 因为您不需要响应,我可以告诉这一点,因为您将其引用为 (new LoadingFullScreen()) 例如要获得响应,您将使用 myLoadingFullScreenInstance.someGetter()。 onDisplay、onUndisplay 已弃用,替换为 onUiEngineAttached(true|false) 尝试使用它们。也尝试等待线程肯定结束 b4 弹出。我无法解释为什么这只会破坏触摸设备

标签: blackberry blocking blackberry-simulator


【解决方案1】:

我记得有一次我遇到了几乎相同的问题。每当我试图通过获取事件线程的锁来弹出屏幕时,应用程序就会崩溃。所以不要获取事件线程的保持(锁定),而是尝试使用invokeLater()在事件线程上同步。

UiApplication.getUiApplication().invokeLater(new Runnable()
{  
   public void run()
   {  

   }  
});

【讨论】:

  • 感谢您的回答。我试过了,但我有完全相同的问题。我编辑了原始帖子以反映这一点
  • 我的这个建议可能有误。我不是线程专家。但是认为这可能是问题查看您的代码,我注意到您在 UI 类(FullScreen)上实现了 Runnable。然后你使用 UiApplication.getUiApplication().pushModalScreen() 推动这个 scree。所以你的 LoadingFullScreen 现在是事件线程。当屏幕被推送到显示堆栈时,您创建一个新线程并将 LoadingFullScreen 可运行在该线程上,该线程将执行 run()。在此线程中,您尝试 popScreen 创建此线程。我怀疑这里有问题。
  • 我建议创建一个实现 Runnable 的新类(类似于 ConnectNetwork )。剪切 LoadigFullScreen 的 run() 方法并将其粘贴到新类中。现在将这个新的可运行类放在将照常创建的线程上。还有一件事,使用 onUiEngineAttached() 代替 onDisplay() 和 onUnDisplay()。最近的操作系统已弃用后来的方法。我希望这是问题所在。
  • 感谢@indusBull 的回复,我会试试的
  • 嗨@indusBull。不幸的是,它没有用。我将 run() 方法移到了一个新的 Runnable 类,但我遇到了同样的问题:S
【解决方案2】:

由于没有一个答案可以解决问题,我在这里发布了我在其他论坛的帮助下获得的解决方案 (http://supportforums.blackberry.com/t5/Java-Development/Application-is-not-responding-进程终止-因为/mp/1234573#M168285)

我没有发现它相关,但似乎我打电话给LoadingFullScreen 的方式很重要:

public void fieldChanged(Field field, int context) {
    LoadingFullScreen loading  = new LoadingFullScreen();
    System.out.println("calling pushModalScreen"); //this was showing up in logs
    UiApplication.getUiApplication().pushModalScreen(loading);
    System.out.println("pushModalScreen done"); //this wasn't showing up in logs    
}

原来我提到的模拟器/设备支持“SureType”。 “这意味着当你按下一个键时他们会做一些事情。通常,他们会尝试为用户显示一个'选择',因为每个键都有两个选项。因为你在 FieldChanged 方法中执行 pushModal,你正在阻止这个。我认为这就是它令人不安的原因。”

所以解决方案是改变这种方式:

public void fieldChanged(Field field, int context) {
    if ( context != FieldChangeListener.PROGRAMMATIC ) {
        UiApplication.getUiApplication().invokeLater(new Runnable() { 
            public void run() {
                LoadingFullScreen loading  = new LoadingFullScreen();
                UiApplication.getUiApplication().pushModalScreen(loading);          
            }
        }
    }
}

【讨论】:

    【解决方案3】:

    假设 UiApplication.getUiApplication().popScreen() 的 smth 是错误的(假设存在 RIM 错误),这只是一个尝试的想法:

    尝试拨打active.close(),而不是UiApplication.getUiApplication().popScreen(active);

    【讨论】:

    • 您好,感谢您的建议。但是,我得到完全相同的行为。我编辑了原始帖子以反映这一点
    • 嗯..我相信MusiGenesis和你所说的。然而这对我来说是非常出乎意料的。几年来,我一直在 Storms 上成功使用UiApplication.getUiApplication().popScreen()。可能应该有一些其他条件(我的应用程序没有)才能显示此错误。或者,该错误可能会出现在某些特定的操作系统版本上。
    【解决方案4】:

    我相信这是因为创建的 ui 线程和您的线程无法正常通信。您可以使用以下代码。

    UiApplication.getUiApplication().invokeLater(new Runnable()
    {  
       public void run()
       {  
    
       }  
    });
    

    【讨论】:

    • 感谢您的提示,但正如我在第一次编辑中所说的那样,我已经尝试过了,但没有成功
    【解决方案5】:

    我在实现的弹出屏幕中遇到了类似的奇怪问题。事实证明,我有两种不同的方法试图同时弹出屏幕。这导致了错误。

    我最终创建了一个静态帮助方法,现在我用它来关闭我的屏幕,它会在关闭屏幕之前检查屏幕是否实际显示。

    张贴在这里以防它帮助某人:

    /**
     * Convenience method to request a screen to close & pop it from the display
     * stack. This method handles the UI threading issues.
     * 
     * @param screen
     *        {@link Screen} to be closed.
     */
    public static void closeScreen(final Screen screen)
    {
        UiApplication.getUiApplication().invokeLater(new Runnable()
        {
    
            public void run()
            {
                if (screen.isDisplayed())
                {
                    screen.close();
                }
            }
        });
    }
    

    【讨论】:

      【解决方案6】:

      我经历过类似的事情。我有一个回调(从另一个线程调用),其中发生了处理,并通过Status 通知用户处理指示,并使用如下代码:

      UiApplication.getUIApplication.invokeLater(new Runnable(){
         public void run(){
           Status.show("....");
         }
      });
      

      并且正在接近与 OP 相同的错误。

      我当时意识到,因为回调被多次执行,所有 Runnables 都在排队​​,因此“线程太多”紧随其后一次不错的崩溃!

      解决办法:

      UiApplication.getUIApplication.invokeAndWait(new Runnable(){
         public void run(){
           Status.show("....");
         }
      });
      

      这将一直阻塞,直到事件队列被清除,让更多Status 出现。

      因为它在一个线程上,所以没关系,因此是一个不错的折衷方案。

      最终结果:事件日志中不再出现令人讨厌的崩溃和虚假消息。

      致 OP:您可能需要稍微调整如何通知最终用户处理 UI 逻辑的通知,以免耗尽线程池。

      顺便说一句,应该注意 - 这是在 BB 4.5 上 :)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-10
        • 2021-07-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多