Android应用程序中的主要线程在哪里?

时间:2012-01-26 11:07:12

标签: android ui-thread

我已经写了一个游戏(我将它命名为“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()代码来解决这个问题。

请有人告诉我哪个更容易 - 以及任何必要的代码应该去哪里。

5 个答案:

答案 0 :(得分: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

而不是使用AsyncTask

答案 1 :(得分: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();
               }
            });
        }
    }
}

答案 2 :(得分:0)

您从MicksThreadThing致电onDraw(canvas);。显然,它不是应用程序的主线程。主线程就是那些,你的活动被onCreate()调用。

答案 3 :(得分:0)

您无法从普通线程更新UI。 使用runOnUiThread()更新用户界面。

答案 4 :(得分:0)

主线程是ui线程...因此您可以使用Handler中的onPostExecute() or onPreexecute()AsyncTask