MikeCoverUps
MikeCoverUps

Reputation: 783

Threads on Orientation Change

This has been really confusing me of late. I have a thread which I start, and it keeps running until I kill it - by setting it's while variable to false.

This all works ok, but I lose contact with the thread on orientation change so I can't stop it. I've written this to try and clarify the problem:

public class FTTest extends Activity {

boolean isPlaying = false;
Player player = new Player();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_fttest);
}

public void play(View v) {
    if (!isPlaying) {
        Log.d("Play Button", "Start Pressed");
        player.start();
        isPlaying = true;
    } else {
        Log.d("Play Button", "Stop Pressed");
        player.going=false;
        isPlaying = false;
    }
}

}

The player is just this:

public class Player extends Thread{
int i;
public boolean going=true;

public void run(){
    while(going){
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        i++;
        Log.d("Thread", "Running "+i+" times");
    }
}

}

I've been reading about using fragments to solve this - but I just can't get my head around how to use them in this context. Is there something simple I'm missing?

Thanks for your help,

Mike

Upvotes: 1

Views: 1428

Answers (2)

Anup Cowkur
Anup Cowkur

Reputation: 20563

I think what is happening is that on your orientation change, the activity is getting recreated (as it usually does in android). When this happens, the Player object is being re-initialised as well.

So, you are actually going to have a reference to a new Player object and the old one will keep on running happily outside your control.

There are many ways to handle this. This blog post will be of help:

http://blog.andresteingress.com/2011/09/27/fighting-orientation-changes-in-android/

Upvotes: 0

dymmeh
dymmeh

Reputation: 22306

The idea is that you allow a fragment to be retained (fragment is not destroyed.. it will be persisted across your orientation changes). Your activity will get recreated and will be reattached to your Fragment which is still running your thread..

public class FTTest extends Activity {

    private FTFragment fragment;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (savedInstanceState == null) {
            fragment = new FTFragment();
            getFragmentManager().beginTransaction().add(android.R.id.content, fragment).commit();
        }
        else {
          fragment = (FTFragment)getFragmentManager().findFragmentById(android.R.id.content);
        }
    }
}

Retained fragment class

public class FTFragment extends Fragment
{
    boolean isPlaying = false;
    Player player = new Player();

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setRetainInstance(true);
    }

    public void play(View v) {
        if (!isPlaying) {
            Log.d("Play Button", "Start Pressed");
            player.start();
            isPlaying = true;
        } else {
            Log.d("Play Button", "Stop Pressed");
            player.going=false;
            isPlaying = false;
        }
    }

}

In your activity where you called play(View) you now should call fragment.play(View);

Upvotes: 2

Related Questions