Mick
Mick

Reputation: 7937

Where is the main thread in android app?

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.

Upvotes: 2

Views: 964

Answers (5)

Houcine
Houcine

Reputation: 24181

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

Upvotes: 2

a fair player
a fair player

Reputation: 11776

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

Upvotes: 0

waqaslam
waqaslam

Reputation: 68177

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

Upvotes: 1

Thommy
Thommy

Reputation: 5407

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

Upvotes: 0

Vladimir Ivanov
Vladimir Ivanov

Reputation: 43098

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.

Upvotes: 0

Related Questions