Frage

Ich habe ein Spiel geschrieben (ich gebe ihm den Namen „Gamer“), in dem ich die folgende allgemeine Struktur habe (der Code wurde stark vereinfacht):

public class Gamer extends Activity implements View.OnClickListener
{
    public void onCreate(Bundle savedInstanceState) 
    {
        mpt = new MicksPanelThing(this);
    }
}
public class MicksPanelThing extends SurfaceView implements SurfaceHolder.Callback
{
    public MicksPanelThing(Context context) 
    {
        super(context);
        micks_thread_thing = new MicksThreadThing(getHolder(), this);
        getHolder().addCallback(this);
        setFocusable(true);
    }
    void updateView()
    {
        final SurfaceHolder holder = getHolder();

        try 
        {
            Canvas canvas = holder.lockCanvas();
        if(canvas != null)
            {
            onDraw(canvas);
            holder.unlockCanvasAndPost(canvas);
        }
        } 
        catch (Exception e) 
        {
        e.printStackTrace();
        }
    }
    public void onDraw(Canvas canvas) 
    {
        // blah
    }

}
class MicksThreadThing extends Thread 
{
    public MicksThreadThing(SurfaceHolder surfaceHolder, MicksPanelThing mpt)
    {
        // blah
    }
    public void run() 
    {
        while (this_thread_is_currently_active) 
        {
            micks_panel_thing.updateView();
        }
    }
}

Das Spiel funktionierte einwandfrei und war sehr robust.Jetzt wollte ich auf eine bestimmte Bedingung testen und, wenn sie wahr ist, einen AlertDialog erstellen.Ich ging davon aus, dass ich diesen Code in meine onDraw-Methode einfügen könnte.Dann erhielt ich die Meldung „Kann keinen Handler in einem Thread erstellen, der Looper.prepare() nicht aufgerufen hat“ – das verwirrt mich, weil ich angenommen habe, dass die onDraw-Methode vom Hauptthread ausgeführt wird, für den ich vermutlich keinen Bedarf habe irgendetwas einrichten.

Ich gehe davon aus, dass ich dieses Problem lösen könnte, indem ich entweder meinen Test und Dialog irgendwo im Hauptthread verschiebe (wo?) oder indem ich irgendwo Looper.prepare()-Code hinzufüge.

Kann mir bitte jemand sagen, was einfacher wäre – und wo der erforderliche Code hingehört?

War es hilfreich?

Lösung

Versuchen Sie, die Methode zu verwenden: runOnUIThread() um die App zu zwingen, Ihren Code auf dem auszuführen Haupt-Bedroung (was das ist UIThread ) , Beispiel :

class MicksThreadThing extends Thread 
{
    public MicksThreadThing(SurfaceHolder surfaceHolder, MicksPanelThing mpt)
    {
        // blah
    }
    public void run() 
    {
         Gamer.this.runOnUiThread(new Runnable(){
         @Override
         public void run(){
            //update/create your views here
            while (this_thread_is_currently_active) 
            {
                micks_panel_thing.updateView();
            }
        }
    });
    }
}

Andere Lösung ist:anstatt a zu verwenden Thread ,Sie können eine verwenden AsyncTask

Andere Tipps

Tun Sie es auf diese Weise: generasacodicetagpre.

Du rufst an onDraw(canvas); von MicksThreadThing.Offensichtlich ist es nicht der Hauptthread der Anwendung.Der Hauptthread sind diejenigen, die onCreate() Ihrer Aktivität heißt.

Sie können die Benutzeroberfläche nicht von einem normalen Thread aktualisieren. Verwenden Sie den runOnUiThread() zum Aktualisieren von UI.

Der Hauptthread ist der UI-Thread ...damit Sie es verwenden können Handler oder der onPostExecute() or onPreexecute() im AsyncTask.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top