BlackBerry: «Приложение не отвечает; процесс завершен» из-за UiApplication.getUiApplication (). PopScreen ()? - PullRequest
7 голосов
/ 27 июля 2011

У меня есть приложение Blackberry, которое при запуске в некоторых эмуляторах с сенсорной поддержкой (например: 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() блокирует приложение, и поэтому ОС убивает приложение, но почему?

EDIT:
Я также пытался использовать

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: Я попытался переместить метод run() в LoadingFullScreen в новый класс Runnable, поскольку мне сказали, что наличие LoadingFullScreen implement Runnable может вызвать проблемы, когда этот класс отображается как модальный экран.
Однако мне не повезло, и у меня все та же проблема.
Есть идеи?

РЕДАКТИРОВАТЬ 5: Решено здесь: BlackBerry: «Приложение не отвечает; процесс завершен» из-за UiApplication.getUiApplication (). PopScreen ()?

Ответы [ 6 ]

4 голосов
/ 02 августа 2011

Поскольку ни один из ответов не решает проблему, я публикую здесь решение, к которому я пришел с помощью другого форума (http://supportforums.blackberry.com/t5/Java-Development/Application-is-not-responding-process-terminated-because-of/m-p/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'. "Это означает, что они делают некоторые вещи, когда вы нажимаете клавишу. Как правило, они пытаются отобразить«выбор» для пользователя, потому что у каждой клавиши есть две опции. потому что вы делаете pushModal в методе FieldChanged, вы блокируете это. И я думаю, это то, из-за чего он расстраивается. "

Таким образом, решение состояло в том, чтобы изменить способ так:

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);          
            }
        }
    }
}
4 голосов
/ 27 июля 2011

Я помню, что однажды у меня была почти такая же проблема. Всякий раз, когда я пытался открыть экран, получая блокировку потока событий, приложение зависало. Поэтому вместо того, чтобы удерживать (блокировать) поток событий, попробуйте выполнить синхронизацию в потоке событий с помощью invokeLater ().

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

   }  
});
1 голос
/ 28 июля 2011

Предполагается, что что-то не так (при условии, что есть ошибка RIM) с UiApplication.getUiApplication().popScreen(), вот только идея, чтобы попробовать:

Вместо UiApplication.getUiApplication().popScreen(active); попробуйте позвонить active.close().

0 голосов
/ 30 июня 2012

Я испытал нечто похожее на это.У меня есть обратный вызов (вызванный из другого потока), в котором происходит обработка, и информирует пользователя об индикации обработки через Status и использует код, подобный этому:

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

И получал почти идентичные ошибкикак OP.

Я понял тогда, потому что обратный вызов выполнялся несколько раз, ALL из этих Runnable были поставлены в очередь и, следовательно, "слишкоммного потоков ", сопровождаемое хорошим отказом!

Решение:

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

Это будет блокировать, пока очередь событий не будет очищена, освобождая путь для появления дополнительных Status.

Поскольку он находится в потоке, это не имеет значения и, следовательно, является хорошим компромиссом.

Конечный результат: Нет больше неприятных сбоев и никаких ложных сообщений в журнале событий.

Оператору: вам, возможно, придется немного изменить структуру информирования конечного пользователя об уведомлении об обработке логики пользовательского интерфейса, чтобы не исчерпать пул потоков.

Кстати, это должнонадо отметить - это на ББ 4.5:)

0 голосов
/ 18 января 2012

У меня были похожие странные проблемы с всплывающим экраном, который я реализовал.Оказалось, что у меня было 2 разных способа, пытающихся выскочить на экран одновременно.Это привело к ошибке.

В итоге я создал статический вспомогательный метод, который теперь использую для закрытия экранов, который проверяет, отображается ли экран перед закрытием.

В случае, если это кому-то поможет:

/**
 * 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();
            }
        }
    });
}
0 голосов
/ 01 августа 2011

Я считаю, что это связано с тем, что созданный поток пользовательского интерфейса и ваш поток не взаимодействуют должным образом. Вы можете использовать этот следующий код.

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

   }  
});
...