Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 9209825
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 18, 20262026-06-18T00:56:12+00:00 2026-06-18T00:56:12+00:00

I’m still pretty confused as to when / how to end threads in my

  • 0

I’m still pretty confused as to when / how to end threads in my Surfaceview application and was hoping someone could explain.

Currently, I am using this code:

Log.v("Destroyed","Surface Destroyed");

preThread.setRunning(false);  
boolean retry = true;        
while (retry) {
    try {
        preThread.join();
        retry = false;
    } catch (InterruptedException e) {
    }
}

The above code sits in my surfaceDestroyed method – firstly, is this correct?

In my surfaceCreated method I have the following code which should check to see if the thread still exists or has been stopped and if it’s been stopped, then re-start it:

if (runthread==false){

if (preThread.getState()==Thread.State.TERMINATED){
    preThread = new MainThread(thisholder, thiscontext, thishandler);}
else {}
    preThread.setRunning(true);
    preThread.start();
    }

It seems to act really strange. Here is what I get:

*) When I first install the game and run it, through my logging, it says that the thread already exists, If I then press the back key, surfaceDestroyed is run but when I go back into the activity, again it says that the thread already exists.

*) If I press the home key, then surfaceDestroyed is run and when I go back into the activity it says that the thread was previously destroyed and starts a new one.

*) If I kill the activity using DDMS, surfaceDestroyed isn’t run and when I go back into the activity it says that the thread already exists.

If I’m thinking straight, then the third scenario is the only one that seems to make sense.

I’m clearly doing something drastically wrong. The main problem is this:

If I hit the home key during the game and then end the app via DDMS in Eclipse, restart the app and hit the back key twice in quick succession (once, to go back to the previous activity, then again to get back to the splash screen) – the app force-closes and I get a “Fatal exception: Thread 12” in logcat. I have to assume this is because my thread is never ending and is trying to be-restarted? I’m not sure.

I’ve been trying to figure this out for what seems like an age so I really hope someone can explain what I’m doing wrong!

Many thanks!

Edit. Logcat output.

enter image description here

my Run() method:

    public void run(){

    //Main Loop

    while (runthread){

    Log.v("tracking","runthread is: "+runthread);                             //This should only be logged while this loop is running

        timestart = System.currentTimeMillis();                             //Get time at start of loop for FPS calc

        try{c=mySurfaceHolder.lockCanvas();                                 //Set Canvas to locked

            synchronized(mySurfaceHolder){


                if (c==null){Log.v("Stop","Canvas is null for some reason - exiting, "+c+" - see?!!!");}


                framesskipped = 0;                                              // resetting frames skipped
        doDraw(c);                                                      //Draw to the screen
        updateMenu();
        }
        }
        finally{
            if (c != null){

            mySurfaceHolder.unlockCanvasAndPost(c);                     //Post canvas

            }
        }

        //work out timings

            timeend = System.currentTimeMillis();                       //get end time for current frame (for FPS) 
            frametime = timeend-timestart;                              //Set the frametime variable to the time the frame took to render & update (end time - start time)
            sleepfor = (int) (33-frametime);                            // this is the time that the thread will sleep for if <target time


            if (sleepfor>0){                                            // If the 'sleepfor' variable is >0 then set the thread to sleep for it's value (expressed in ms)

                try {
                    OptionsThread.sleep(sleepfor);                      //send thread to sleep for value of sleepfor (determined above).
                } catch (InterruptedException e) {}                     //in case of exception
            }                                                           //close if statement


                while (sleepfor<0 && framesskipped<maxframesskipped){   //if sleepfor is < 0 (ie, frame took longer to render than target time and the maxframesskipped has not reached it's limit)
                    updateMenu();                                       //Update animation variables without rendering to the screen while these conditions are met 
                    sleepfor+=33;                                       //time to sleep plus the time frame took to render
                    framesskipped++;                                    //add one to framesskipped variable so this only skips a certain number of frames
                    }
                }
            }

New Logcat output showing nullPointerException and output of logging. runThread is never logged as false so I’m not sure how the line that logs canvas as null is reached!

enter image description here

Thanks

Edit:

OK, I’ve completely started from scratch and re-written the whole class- it’s very much a stripped-down version of what I had before and here is the whole class:

    import android.content.res.Resources;
    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.Canvas;
    import android.os.Handler;
    import android.util.Log;
    import android.view.MotionEvent;
    import android.view.Surface;
    import android.view.SurfaceHolder;
    import android.view.SurfaceView;

public class OptionsScreen extends SurfaceView implements
  SurfaceHolder.Callback {   

    //Create Variables

    private SurfaceHolder thisHolder;
    private Context thisContext;
    private Handler thisHandler;
    private preThread thread;
    private Bitmap background;
    private Resources res;
    private Context myContext;
    private Handler myHandler;


    private Canvas c;
    //      thisholder = getHolder();


    public OptionsScreen(Context context) {
    super(context);

    myContext=context;                                  //This is the context passed into this constructor (this)
    thisHolder = getHolder();                           //Get surface holder
    thisHandler=getHandler();                           //Get Handler
    thisContext = getContext();                         //Get context
    res=getResources();                                 //Get resource

    //add the callback surface holder
    getHolder().addCallback(this);
    //make focusable
    setFocusable(true);
    //create new thread
    thread = new preThread(thisHolder, thisContext, thisHandler);
    //create bitmaps from resources
    background = BitmapFactory.decodeResource(res, R.drawable.sky);
}

 @Override
 public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    Log.v("check","surfaceChanged run");

 }

 @Override
 public void surfaceCreated(SurfaceHolder holder) {

    Log.v("check","surfaceCreated run"+thread.getState());

    int height = this.getHeight();
    int width = this.getWidth();

    if(thread.getState()==Thread.State.TERMINATED){             //Has thread been stopped previously? could happen if the home key is pressed
        Log.v("check","Thread still exists!!!! - Starting a new one. "+thread.getState()); 
        thread = new preThread(thisHolder, thisContext, thisHandler);

    }

    thread.setRunning(true);
            thread.start();

    Log.v("check","Thread - "+thread.getState());

 }

 @Override
 public void surfaceDestroyed(SurfaceHolder holder) {

      Log.v("check","surfaceDestroyed run"+thread.getState());

      thread.setRunning(false);                     //Set to false to exit run() method

     boolean retry = true;                          //Shut off rendering thread
          while (retry) {
            try {
                thread.join();
                retry = false;
              } catch (InterruptedException e) {
            // try again shutting down the thread

           }

          }

 }

 @Override
 public boolean onTouchEvent(MotionEvent event) {
     Log.v("check","Surface Touched");
    Log.v("check","Thread - "+thread.getState());
     // System.exit(0);

    return super.onTouchEvent(event);
 }

 @Override
 protected void onDraw(Canvas canvas) {

    // if (canvas!=null){

        canvas.drawBitmap(background, 0, 0, null);
        Log.v("Stop","Canvas is "+canvas);
     }
 }








 //*******************************************************************
 //**                           run loop                            **
 //*******************************************************************

protected class preThread extends Thread {

    private SurfaceHolder mySurfaceHolder;
    private Context myContext;

    public preThread(SurfaceHolder surfaceholder, Context context, Handler handler) {               //Constructor

        mySurfaceHolder=surfaceholder;
        myContext=context;
        res = myContext.getResources();


    }



         // flag
         private boolean running;
         public void setRunning(boolean running) {
          this.running = running;
         }

         @Override
         public void run() {

                      while (running) {

            try{c=mySurfaceHolder.lockCanvas();                                 

            synchronized(mySurfaceHolder){


                Log.v("check","Drawing!!");

        onDraw(c);                                                      

        }
        }
        finally{
            if (c != null){

            mySurfaceHolder.unlockCanvasAndPost(c);                     

            }
        }





          }
         }
        }
}
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-18T00:56:13+00:00Added an answer on June 18, 2026 at 12:56 am

    Threads are pretty difficult to manage, but after some hit and trial i think i have come up with a scheme which works correctly most of the time.
    To End a Thread

     if(m_hThread != null)
            {
                try 
                {
                    m_bThread = false; // m_bThread is the while condition of the thread
                    m_hThread.interrupt(); // incase the thread is in sleep
                    m_Thread.join(); // This call blocks and waits for thread to end
                    m_hThread = null;  
    
                } catch (InterruptedException e) {
    
                    e.printStackTrace();
                }
            }
    

    For re-creating thread

     if(m_hThread == null) 
         {   
             m_bThread = true; //while condition of thread
             StartNewThread(); 
         }
    

    In your implementation, No need to retry Thread.join, either it will join in the first try or it will block until the thread joins. As for your cases only the first case seems to be weird, where you find the thread is already running, this can’t possibly be true. Second and third make complete sense to me, and work like they should. When the user clicks Home button surfaceDestroyed is invoked and thread is Terminated.

    thread continues as long as m_bThread is true,

     while(m_bThread) //b
        {
          // Continuous Thread operations...
        }
    

    m_hThread is simply preThread in your code, and m_Thread is a also m_hThread just a typing mistake here.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

That's pretty much it. I'm using Nokogiri to scrape a web page what has
I'm parsing an RSS feed that has an &#8217; in it. SimpleXML turns this
This could be a duplicate question, but I have no idea what search terms
I'm not entirely sure how I managed to jack this up. http://pretty-senshi.com If you
I have a string like this: La Torre Eiffel paragonata all&#8217;Everest What PHP function
I'm new to using the Perl treebuilder module for HTML parsing and can't figure
link Im having trouble converting the html entites into html characters, (&# 8217;) i
I am confused How to use looping for Json response Array in another Array.
I am using JSon response to parse title,date content and thumbnail images and place
For some reason, after submitting a string like this Jack’s Spindle from a text

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.