2

私は次の一般的な構造を持つゲーム(「ゲーマー」という名前を付けます)を作成しました(コードは大幅に簡略化されています)。

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();
        }
    }
}

ゲームはすべて正常に機能し、非常に堅牢でした。ここで、特定の条件をテストし、それが真である場合は、AlertDialogを作成したいと思いました。このコードをonDrawメソッド内に配置できると思いました。次に、「Looper.prepare()を呼び出していないスレッド内にハンドラーを作成できません」というメッセージが表示されました。これは、onDrawメソッドが必要ないと思われるメインスレッドによって実行されていると想定したため、混乱を招きます。何かを設定します。

テストとダイアログをメインスレッド内のどこかに移動するか(どこ?)、Looper.prepare()コードをどこかに追加することで、これを解決できると思います。

誰かが私にどちらが簡単か、そして必要なコードはどこに行くべきか教えてもらえますか?

4

5 に答える 5

2

メソッド:を使用して、アプリにmainThread(である)でrunOnUIThread()コードを実行させるようにします。例:UIThread

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();
            }
        }
    });
    }
}

他の解決策は:を使用する代わりに、を使用するThreadことができますAsyncTask

于 2012-01-26T11:12:50.220 に答える
1

このようにしてください:

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

            Gamer.this.runOnUiThread(new Runnable(){
               @Override
               public void run(){
                  micks_panel_thing.updateView();
               }
            });
        }
    }
}
于 2012-01-26T11:15:59.717 に答える
0

onDraw(canvas);MicksThreadThingから呼び出します。明らかに、それはアプリケーションのメインスレッドではありません。メインスレッドはonCreate()、あなたのアクティビティのどれと呼ばれるものです。

于 2012-01-26T11:11:14.250 に答える
0

通常のスレッドからUIを更新することはできません。runOnUiThread()UIの更新に使用します。

于 2012-01-26T11:11:57.473 に答える
0

メインスレッドはUIスレッドです...したがって、HandlerまたはonPostExecute() or onPreexecute()を使用できますAsyncTask

于 2012-01-26T11:16:05.317 に答える