2

我编写了一个游戏(我将其命名为“Gamer”),其中我具有以下一般结构(代码已大大简化):

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

尝试使用方法:runOnUIThread()强制应用程序在mainThread(即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您可以使用 an而不是使用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线程......所以你可以使用HandleronPostExecute() or onPreexecute()AsyncTask.

于 2012-01-26T11:16:05.317 回答