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

发布于 2024-12-29 03:20:44 字数 1595 浏览 0 评论 0原文

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

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

I have written a game (I'll give it the name "Gamer") in which I have the following general structure (the code has been much simplified):

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

The game was all working fine and was very robust. Now I wanted to test for a certain condition and, if it was true, put up an AlertDialog. I presumed that I could put this code within my onDraw method. I then got a message "Can't create handler inside thread that has not called Looper.prepare()" - this is confusing me because I assumed that the onDraw method was being executed by the main thread for which I presumed I needn't set anything up.

I presume I could solve this by either moving my test and dialog to somewhere within the main thread (where?) or by adding some Looper.prepare() code somewhere.

Please can someone tell me which would be easier - and where should any necessary code go.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

蓝眼睛不忧郁 2025-01-05 03:20:44

尝试使用方法:runOnUIThread()强制应用程序在ma​​inThread(即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();
            }
        }
    });
    }
}

其他解决方案是:您可以使用 AsyncTask 而不是使用 Thread

try to use the method : runOnUIThread() to force the app to run your code on the mainThread ( which is the UIThread ) , Example :

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

Other solution is : instead of using a Thread ,you can use an AsyncTask

意中人 2025-01-05 03:20:44

这样做:

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

do it in this way:

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();
               }
            });
        }
    }
}
べ映画 2025-01-05 03:20:44

您从 MicksThreadThing 调用 onDraw(canvas);。显然,它不是应用程序的主线程。主线程是那些调用 Activity 的 onCreate() 的线程。

You call onDraw(canvas); from MicksThreadThing. Obviously, it is not the main thread of the application. The main thread is those, which onCreate() of your activity is called.

燃情 2025-01-05 03:20:44

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

You can't update the UI from a normal Thread.
Use runOnUiThread() for updating UI.

掀纱窥君容 2025-01-05 03:20:44

主线程是ui线程...因此您可以在AsyncTask中使用HandleronPostExecute()或onPreexecute()

the main thread is the ui thread... so you can use Handler or the onPostExecute() or onPreexecute() in the AsyncTask.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文