2010-01-16 5 views
5

Ich schreibe eine App, die im Grunde ein Wrapper rund um ein 250K JNI ist. Die JNI (eine Spiele-Engine) hat APIs wie handle_penUp (int x, int y). Manchmal muss der Benutzer den Benutzer innerhalb von handle_penUp() abfragen (über Rückrufe in Java-Code), sodass der Dialog, den ich zur Implementierung der Abfrage verwende, blockiert werden muss.Blockieren von Dialog aus JNI-Code

Ich verstehe, dass der Hauptthread der Ausführung nicht blockieren kann. Also habe ich einen zweiten Thread erzeugt, der alle JNI-Aufrufe durchführt, die zu Rückrufen führen könnten, die blockiert werden müssten. Innerhalb dieses zweiten Threads, wenn ich einen blockierenden Dialog aufstellen muss, rufe ich startActivityForResult() und dann accept() für einen Semaphor auf. Wenn onActivityResult() für den Haupt-Thread aufgerufen wird, ruft es release() für denselben Semaphor auf.

Dies funktioniert, wenn meine Abfrage als eine neue Aktivität implementiert ist, aber nicht wenn ich ShowDialog() innerhalb der vorhandenen Aktivität anzeigen möchte. Log-Nachrichten sagen mir, dass mein Thread einen Looper benötigt. Ich füge einen hinzu - und werde Informationen anhängen, ob es funktioniert - aber es fühlt sich an, als würde ich hier den falschen Weg gehen. Was ich brauche, ist ein Rezept für blockierende Dialoge (nützlich nur, weil jede andere Plattform sie hat und so portierter Code wird oft so funktionieren.)

Antwort

0

Sie wollen definitiv nicht zwei UI-Threads. Es sollte nur einen Thread geben, der mit dem Android-SDK kommuniziert, sofern der Kontrollfluss und die Anzeige aktiviert sind (d. H. Alles, was mit dem Zeichnen, Starten von Aktivitäten, Anzeigen von Dialogen usw. zu tun hat).

Denken Sie auch daran, dass Sie Ihren Thread nicht wirklich laufen lassen wollen - alles basiert auf Ereignissen. Sie möchten also, dass Ihr Code auf etwas reagiert, etwas tut und dann so schnell wie möglich beendet wird.

Wenn Sie "Block" sagen, was genau meinst du? Was muss blockiert werden? Wenn Sie einfach nicht mehr auf Ereignisse reagieren müssen, warum sollte nicht ein Boolescher Wert auf True gesetzt werden, während das Dialogfeld sichtbar ist, und einfach alle Ereignisse ignorieren, solange es wahr ist?

+0

wahrscheinlich blockieren, wie bei der Blockierung gegen non-blocking io hilft (der Anruf nicht zurückkehrt, bis es hat die angeforderte Eingabe erhalten oder ist fehlgeschlagen, im Gegensatz zu der sofortigen Rückgabe und dem Melden der Eingabe, wenn eine bereits in einem Puffer vorhanden war) –

2

Es klingt sehr nahe an ein Problem, das ich mit der Einstellung sichtbar/unsichtbar einige Sicht vom Touch-Thread hatte.

das Problem ist, dass Sie nicht einige Operationen auf der GUI bilden einen weiteren Thread tun (das ist Ihr Fall)

, was Sie tun müssen, ist ein Griff in Ihrem Haupt-Thread zu verwenden Ich erklärte es in die Aktivität

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

wählte ich die Möglichkeit, public static, so dass ich in überall zugreifen kann (weil ich nie mehr als einen Anruf zu einer Zeit habe und dass ich faul fühlte es passiert entlang zu den Unterklassen).

dann, was Sie tun möchten, ist eine Nachricht an diesen Handler senden, und da der Handler ist im selben Thread wie die gui es funktioniert ^^

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

Das Ihren Looper Fehler lösen sollte und ermöglichen es Ihnen, senden GUI Anfrage von einem Thread zu einem anderen

hoffen, dass es

Jason