Блокировка диалога из кода JNI - PullRequest
5 голосов
/ 16 января 2010

Я пишу приложение, которое по сути является оберткой вокруг 250K JNI. JNI (игровой движок) имеет API-интерфейсы, такие как handle_penUp (int x, int y). Иногда требуется запросить пользователя изнутри handle_penUp () (посредством обратных вызовов в код Java), поэтому диалоговое окно, которое я использую для реализации запроса, должно блокироваться.

Я понимаю, что основной поток выполнения не может блокироваться. Итак, я создал второй поток, который выполняет все вызовы JNI, которые могут привести к обратным вызовам, которые необходимо будет заблокировать. Внутри этого второго потока, когда мне нужно открыть диалоговое окно блокировки, я вызываю startActivityForResult (), а затем acqu () на семафор. Когда onActivityResult () вызывается в главном потоке, он вызывает release () для того же семафора.

Это работает, если мой запрос реализован как новое действие, но не если я хочу показатьDialog () в существующем действии. Сообщения в журнале говорят мне, что моей теме нужен Looper. Я добавляю один - и добавлю информацию о том, работает ли он - но мне кажется, что я иду по неверному пути здесь. Что мне нужно, так это рецепт блокирования диалогов (полезен хотя бы потому, что они есть у любой другой платформы, и поэтому перенесенный код будет часто работать таким образом.)

Ответы [ 2 ]

2 голосов
/ 27 октября 2010

Это звучит очень близко к проблеме, с которой я столкнулся при настройке видимого / невидимого некоторого вида из сенсорной нити.

проблема в том, что вы не можете выполнять некоторые операции в графическом интерфейсе другого потока (в вашем случае)

что вам нужно сделать, это использовать дескриптор в вашем основном потоке Я объявил это в Деятельности

public static final Handler handlerVisibility = new Handler() {
    public void handleMessage(Message msg) {
        int visibility = msg.getData().getInt("visibility");
        view.setVisibility(visibility);
    }
};

Я выбрал опцию public static, чтобы я мог получить доступ в любом месте (поскольку у меня никогда не было больше одного вызова за раз, и мне было лень передавать его подклассам).

тогда вы хотите отправить сообщение этому обработчику, и, поскольку обработчик находится в том же потоке, что и графический интерфейс, он работает ^^

Message msg = MainActivity.handlerVisibility.obtainMessage();
    Bundle b = new Bundle();
            b.putInt("visibility", View.VISIBLE);
    msg.setData(b);
            MainActivity.handlerVisibility.sendMessage(msg);

Это должно решить вашу ошибку петлителя и позволить вам отправлять запрос GUI из одного потока в другой

надеюсь, это поможет

Jason

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

Вы определенно не хотите двух потоков пользовательского интерфейса. Должен быть только один поток, который связывается с Android SDK в отношении потока управления и отображения (т. Е. Всего, что связано с рисованием, начальными действиями, отображением диалоговых окон и т. Д.).

Кроме того, имейте в виду, что вы на самом деле не хотите, чтобы ваш поток работал - все основано на событиях, поэтому вы хотите, чтобы ваш код что-то отвечал, что-то делал, а затем выходил как можно скорее. *

Когда вы говорите «блок», что именно вы имеете в виду? Что нужно заблокировать? Если вам просто нужно перестать отвечать на события, почему бы не иметь логическое значение, установленное в значение true, когда диалог видим, и просто игнорировать все события, пока оно истинно?

...