I have been working on an audio stream app but I need clarity on a variety of issues. First of all, I am playing the audio file with a bound service and I have a play-pause button` that toggles player on and off.
These are the issues i have with my code:
Media player gets instantiated each time I press play button but that is not what because I also need to pause playback when needed.
Playback is very slow. It takes a lot of time for the mediaplayer to prepare and stream.
Sometimes media player gets initialized twice if the user vigorously toggles the playpause button.
Here the code:
Music Player Activity
btn_play_pause.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!playPause) {
btn_play_pause.setImageResource(R.drawable.pause_button);
if (initialStage) {
musicService.play();
Toast.makeText(MusicPlayerActivity.this, "Playing started", Toast.LENGTH_SHORT).show();
}
playPause = true;
} else {
btn_play_pause.setImageResource(R.drawable.play_button);
Toast.makeText(MusicPlayerActivity.this, "Playing paused", Toast.LENGTH_SHORT).show();
playPause = false;
musicService.pause();
}
}
});
}
Music Service
public class MusicService extends Service implements MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener, MediaPlayer.OnBufferingUpdateListener, MediaPlayer.OnCompletionListener{
private final IBinder mBinder = new MusicService.AudioBinder();
private MediaPlayer mediaPlayer;
private AudioManager audioManager;
private AudioManager.OnAudioFocusChangeListener audioFocusChangeListener;
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
Toast.makeText(this, "Network Error", Toast.LENGTH_LONG).show();
mediaPlayer.reset();
return false;
}
#Override
public void onPrepared(MediaPlayer mp) {
try {
mp.setDataSource(stream_source);
mp.prepareAsync();
mp.start();
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {
mediaPlayer = mp;
}
#Override
public void onCompletion(MediaPlayer mp) {
mediaPlayer = mp;
}
public class AudioBinder extends Binder {
public MusicService getService() {
//Return this instance of RadioBinder so clients can call public methods
return MusicService.this;
}
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent != null && intent.getAction() != null) {
switch (intent.getAction()) {
case Constants.ACTION_STOP_AUDIO_SERVICE:
hideNotification();
Intent i = new Intent(this, MainActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.addFlags (Intent.FLAG_ACTIVITY_SINGLE_TOP);
i.putExtra("close_activity",true);
this.startActivity(i);
break;
case Constants.ACTION_STREAM_PLAY_PAUSE:
if (isPlaying()) {
pause();
showNotification();
stopForeground(false); // stop making it a foreground service but leave the notification there
} else {
play();
showNotification();
}
break;
default:
break;
}
}
return START_STICKY;
}
#Override
public void onCreate() {
setUpAudioManager();
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
}
public void play() {
mediaPlayer.setOnPreparedListener(this);
mediaPlayer.setOnErrorListener(this);
showNotification();
}
public void pause() {
if(mediaPlayer.isPlaying()) {
mediaPlayer.pause();
audioManager.abandonAudioFocus(audioFocusChangeListener);
}
showNotification();
}
public boolean isPlaying() {
return mediaPlayer != null && (mediaPlayer.isPlaying());
}
#Override
public boolean stopService(Intent name) {
if (mediaPlayer != null){
mediaPlayer.release();
mediaPlayer = null;
}
return super.stopService(name);
}
public void hideNotification() {
stopForeground(true);
}
#Override
public void onDestroy() {
if(mediaPlayer!= null){
mediaPlayer.release();
}
super.onDestroy();
}
public void releaseTrack(){
if(mediaPlayer!= null){
mediaPlayer.release();
}
}
}
Related
I want to play 6 different sounds triggered by 6 different buttons in background, so that if the app is on background the sound keeps playing.
When one sound is already playing, pressing another button will stop it and play its own sound,
Tapping the same button 2K times it stops, 2K+1 times: starts again.. (K is a non-null integer)
All of the code is done and seems to be working correctly, except that the player stops after one and a half minute. (This is not because of low memory)
Can anyone please tell me what am I doing wrong?
public class PlayService extends Service {
private MediaPlayer player;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
player = new MediaPlayer();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
int btnId = intent.getExtras().getInt("ID");
Toast.makeText(this, "onStart service" + btnId, Toast.LENGTH_SHORT).show();
selectResId(btnId);
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, "Service destroyed", Toast.LENGTH_SHORT).show();
if (player != null) {
player.stop();
player.release();
}
player = null;
}
#Override
public void onLowMemory() {
super.onLowMemory();
Toast.makeText(this, "Low mem", Toast.LENGTH_SHORT).show();
}
private void selectResId(int resId){
switch (resId){
case 1: playMediaFromResource(R.raw.number_one);
case 2: playMediaFromResource(R.raw.number_two);
case 3: playMediaFromResource(R.raw.number_three);
case 4: playMediaFromResource(R.raw.number_four);
case 5: playMediaFromResource(R.raw.number_five);
case 6: playMediaFromResource(R.raw.number_six);
default: break;
}
}
private void playMediaFromResource(int resId) {
Uri mediaPath = Uri.parse("android.resource://" + getPackageName() + "/" + resId);
try {
player.setDataSource(getApplicationContext(), mediaPath);
player.setLooping(true);
player.prepare();
player.start();
} catch (Exception e) {
e.printStackTrace();
}
}
}
And the MainActivity:
public class MainActivity extends AppCompatActivity {
private Button btnStart1;
private Button btnStart2;
private Button btnStart3;
private Button btnStart4;
private Button btnStart5;
private Button btnStart6;
private Intent intent;
private int previousID = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewsByIds();
setOnClickListeners();
}
private void findViewsByIds() {
btnStart1 = findViewById(R.id.btn_start_1);
btnStart2 = findViewById(R.id.btn_start_2);
btnStart3 = findViewById(R.id.btn_start_3);
btnStart4 = findViewById(R.id.btn_start_4);
btnStart5 = findViewById(R.id.btn_start_5);
btnStart6 = findViewById(R.id.btn_start_6);
}
private void setOnClickListeners() {
btnStart1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
checkIntentState(1);
}
});
btnStart2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
checkIntentState(2);
}
});
btnStart3.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
checkIntentState(3);
}
});
btnStart4.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
checkIntentState(4);
}
});
btnStart5.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
checkIntentState(5);
}
});
btnStart6.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
checkIntentState(6);
}
});
}
private void checkIntentState(int ID) {
if (intent == null) {
createNewIntent(ID);
} else {
stopService(intent);
intent = null;
if (ID != previousID) {
createNewIntent(ID);
}
}
}
private void createNewIntent(int ID) {
intent = new Intent(MainActivity.this, PlayService.class);
intent.putExtra("ID", ID);
startService(intent);
previousID = ID;
}
}
I want to answer to my own question just in case anyone else runs into the problem.
It turns out, that Android added some new features (restricted access to background resources for battery life improvement purposes since Oreo(i.e. Android 8.0+ || API level 26)).
As the documentation says:
"Apps that are running in the background now have limits on how freely they can access background services."
So, in this case we will need to use foreground services.
When I come back after click the back button and I try to play music I have error 'java.lang.IllegalStateException' - but why..? I noticed that others method like player.isPlaying() or player.reset() didn't work too. If somebody had already this problem - please help. Nice day :)
java.lang.IllegalStateException
at android.media.MediaPlayer.prepareAsync(Native Method)
Activity class:
#Override
protected void onStart() {
super.onStart();
playIntent = new Intent(this, MediaPlayerService.class);
bindService(playIntent, musicConnection, Context.BIND_AUTO_CREATE);
startService(playIntent);
}
#Override
protected void onDestroy() {
super.onDestroy();
if(musicConnection!=null){
unbindService(musicConnection);
}
}
private ServiceConnection musicConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
MediaPlayerService.LocalBinder musicBinder = (MediaPlayerService.LocalBinder) service;
musicService = musicBinder.getService();
musicBound = true;
}
#Override
public void onServiceDisconnected(ComponentName name) {
musicBound = false;
}
};
MusicService class:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return Service.START_NOT_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return iBinder;
}
#Override
public boolean onUnbind(Intent intent) {
player.stop();
player.reset();
player.release();
return false;
}
#Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
#Override
public void onCreate() {
super.onCreate();
setSong(0);
player = new MediaPlayer();
initMediaPlayer();
}
public void initMediaPlayer(){
player.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
player.setOnPreparedListener(this);
player.setOnCompletionListener(this);
player.setOnErrorListener(this);
}
public void playSong(){
try{
player.reset();
Song playSong = songList.get(songPos);
long currSong = playSong.getId();
Uri trackUri = ContentUris.withAppendedId(
android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
currSong);
player.setDataSource(getApplicationContext(), trackUri);
}catch(Exception e){
Log.e("MUSIC SERVICE", "Error setting data source", e);
}
player.prepareAsync();
}
I had to change the onDestroy method on:
#Override
protected void onDestroy() {
stopService(playIntent);
musicService = null;
super.onDestroy();
}
Hello i had implement code of Music service i want to create demo of music player but it not start automatically from onCreate() i want to start player automatically when activity open. here below i put code for Activity and service please help me any help will be appreciate.
public class MainActivity extends Activity {
private ArrayList<Song> songList;
private ListView songView;
private MusicService musicSrv;
private Intent playIntent;
private boolean musicBound = false;
private MusicController controller;
private boolean paused = false, playbackPaused = false;
private ServiceConnection musicConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
MusicService.MusicBinder binder = (MusicService.MusicBinder) service;
musicSrv = binder.getService();
musicSrv.setList(songList);
musicBound = true;
}
#Override
public void onServiceDisconnected(ComponentName name) {
musicBound = false;
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
songView = (ListView) findViewById(R.id.song_list);
songList = new ArrayList<Song>();
getSongList();
Collections.sort(songList, new Comparator<Song>() {
public int compare(Song a, Song b) {
return a.getTitle().compareTo(b.getTitle());
}
});
SongAdapter songAdt = new SongAdapter(this, songList);
songView.setAdapter(songAdt);
songPicked();
}
#Override
protected void onStart() {
super.onStart();
if (playIntent == null) {
playIntent = new Intent(this, MusicService.class);
bindService(playIntent, musicConnection, Context.BIND_AUTO_CREATE);
startService(playIntent);
}
}
public void songPicked() {
musicSrv.setSong(0);
musicSrv.playSong();
}
#Override
protected void onPause() {
super.onPause();
paused = true;
}
#Override
protected void onResume() {
super.onResume();
if (paused) {
paused = false;
}
}
#Override
protected void onStop() {
controller.hide();
super.onStop();
}
#Override
protected void onDestroy() {
stopService(playIntent);
musicSrv = null;
super.onDestroy();
}
}
Here below i put service code also.
public class MusicService extends Service implements
MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener,
MediaPlayer.OnCompletionListener {
private final IBinder musicBind = new MusicBinder();
private MediaPlayer player;
private ArrayList<Song> songs;
private int songPosn;
private String songTitle = "";
private Random rand;
public void onCreate() {
super.onCreate();
songPosn = 0;
rand = new Random();
player = new MediaPlayer();
initMusicPlayer();
}
public void initMusicPlayer() {
player.setWakeMode(getApplicationContext(),
PowerManager.PARTIAL_WAKE_LOCK);
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
player.setOnPreparedListener(this);
player.setOnCompletionListener(this);
player.setOnErrorListener(this);
}
public void setList(ArrayList<Song> theSongs) {
songs = theSongs;
}
#Override
public IBinder onBind(Intent intent) {
return musicBind;
}
#Override
public boolean onUnbind(Intent intent) {
player.stop();
player.release();
return false;
}
public void playSong() {
player.reset();
Song playSong = songs.get(0);
songTitle = playSong.getTitle();
long currSong = playSong.getID();
Uri trackUri = ContentUris.withAppendedId(
android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
currSong);
try {
player.setDataSource(getApplicationContext(), trackUri);
} catch (Exception e) {
Log.e("MUSIC SERVICE", "Error setting data source", e);
}
try {
player.prepare();
} catch (IOException e) {
e.printStackTrace();
}
}
public void setSong(int songIndex) {
songPosn = songIndex;
}
#Override
public void onCompletion(MediaPlayer mp) {
if (player.getCurrentPosition() > 0) {
mp.reset();
}
}
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
mp.reset();
return false;
}
#Override
public void onPrepared(MediaPlayer mp) {
mp.start();
playSong();
}
#Override
public void onDestroy() {
stopForeground(true);
}
public class MusicBinder extends Binder {
MusicService getService() {
return MusicService.this;
}
}
}
I just want to start player when application start automatically without any click. but it display unfortunately stopped with null object reference of Media player. I had never work with service also with music player.
Null pointer exception throws because music service object returns null so.
Finally solved as per #vladMatvienko answer thanks for your support man.
private ServiceConnection musicConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
MusicService.MusicBinder binder = (MusicService.MusicBinder) service;
musicSrv = binder.getService();
musicSrv.setList(songList);
musicBound = true;
songPicked();
}
#Override
public void onServiceDisconnected(ComponentName name) {
musicBound = false;
}
};
I know what a null pointer exception is i have tried using
MediaPlayer mp = new MediaPlayer();
and
public int check()
{
if(mp!=null)
{
return 1;
}
else
{
return 2;
}
}
doesn't helps.
This is the error im getting-
java.lang.RuntimeException: Unable to start activity
ComponentInfo{com.openaisearch.www.musicplayer/com.openaisearch.www.musicplayer.MainActivity}:
java.lang.NullPointerException: Attempt to invoke virtual method
'boolean com.openaisearch.www.musicplayer.Music.check()' on a null
object reference
public class MainActivity extends AppCompatActivity {
ArrayList<String> mSongsList = new ArrayList<>() ;
ArrayList<Long> SongsPath = new ArrayList<>() ;
Button btnPlay;
Music mService;
SeekBar seekBar;
ListView lv;
boolean mBound = false;
private ServiceConnection mConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName className,
IBinder service) {
Music.LocalBinder binder = (Music.LocalBinder) service;
mService = binder.getService();
mBound = true;
}
#Override
public void onServiceDisconnected(ComponentName arg0) {
mBound = false;
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent(this, Music.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
startService(intent);
btnPlay = (Button) findViewById(R.id.buttonPlay);
seekBar = (SeekBar) findViewById(R.id.seekBar);
lv = (ListView) findViewById(R.id.list);
getAudioList();
ArrayAdapter arrayAdapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1,mSongsList);
lv.setAdapter(arrayAdapter);
onSongClick();
setSeekBar();
check();
}
#Override
protected void onStop() {
super.onStop();
if (mBound) {
unbindService(mConnection);
mBound = false;
}
}
public void getAudioList() {
String orderBy = MediaStore.Audio.Media.TITLE ;
String selection = MediaStore.Audio.Media.IS_MUSIC + " != 0";
Cursor mCursor = getContentResolver().query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
new String[] { MediaStore.Audio.Media.TITLE,
MediaStore.Audio.Media._ID }, selection, null, orderBy);
int count = mCursor.getCount();
while (mCursor.moveToNext()) {
mSongsList.add(mCursor.getString(mCursor
.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE)));
SongsPath.add(mCursor.getLong(mCursor
.getColumnIndexOrThrow(MediaStore.Audio.Media._ID)));
}
mCursor.close();
}
public void onSongClick()
{
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
mService.playSong(SongsPath.get(position));
if(btnPlay.getText() == "Play")
{
btnPlay.setText("Pause");
}
}
});
}
public void onButtonClick(View view) {
int a = mService.stopMusic();
if(a == 1)
{
btnPlay.setText("Play");
}
else if (a ==2)
{
btnPlay.setText("Pause");
}
}
public void check()
{
boolean check = mService.check();
}
public void setSeekBar()
{
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (fromUser )
{
mService.setProg(progress*1000);
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
}
Service-
public class Music extends Service {
Long b;
MediaPlayer mp;
private final IBinder mBinder = new LocalBinder();
public class LocalBinder extends Binder {
Music getService() {
return Music.this;
}
}
public void playSong(Long a) {
if (a!= b)
{ if(mp!=null)
{
mp.stop();
mp.release();
mp=null;
}
b =a;
Uri contentUri = ContentUris.withAppendedId(
android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, a);
mp = new MediaPlayer();
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
mp.setDataSource(getApplicationContext(), contentUri);
mp.prepare();
mp.setLooping(true);
mp.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public int stopMusic()
{
if(mp.isPlaying())
{
mp.pause();
return 1;
}
else if (mp!=null)
{
mp.start();
return 2;
}
else
{
return 0;
}
}
public void setProg(int a)
{ if(mp!=null)
{
mp.seekTo(a);
}
}
public boolean check()
{
if(mp!=null)
{
return true;
}
else
{
return false;
}
}
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
}
You are not checking if the service has been connected to the activity or not using mbound in ur function.
public void check()
{
i f(mBound)
{
boolean check = mService.check();
}
}
You're probably getting the NPE from this line: boolean check = mService.check(); So it's mService that is null, not mp
I think you trying to bind service that is not started yet. Try to call startService(intent); before bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
Your service class should follow this format; overwrite the onCreate() method
you are getting NPE because mService is null in line: mService.check();
public class MyService extends Service {
private Binder binder;
#Override
public void onCreate() {
super.onCreate();
binder = new Binder();
}
#Override
public IBinder onBind(Intent intent) {
return binder;
}
public class Binder extends android.os.Binder {
public MyService getService() {
return MyService.this; // return instance
}
}
}
Please teach me how can I solve a MediaPlayer error. I have Mediaplayer, MediaController and listview. When I touch the list, a song starts with MediaController, but when I touch keycode_home and restart my app, the error occurs. Here is my code and error.
java.lang.RuntimeException: Unable to resume activity {}:
java.lang.IllegalStateException
Caused by: java.lang.IllegalStateException at android.media.MediaPlayer.getCurrentPosition(Native Method)
int si[]={R.raw.sample1,R.raw.sample2,R.raw.sample3};
onCreate
ItemBean IB1 = new ItemBean();
IB1.setName("sample1");
IB1.setUrl("http~");
ItemBean IB2 = new ItemBean();
IB2.setName("sample2");
IB2.setUrl("http~");
ItemBean IB3 = new ItemBean();
IB3.setName("sample3");
IB3.setUrl("http~");
List<ItemBean> list = new ArrayList<ItemBean>();
list.add(IB1);
list.add(IB2);
list.add(IB3);
mp = new MediaPlayer();
controller = new MediaController(this);
controller.setAnchorView(findViewById(R.id.mediaController));
controller.setMediaPlayer(this);
list2 = (ListView) findViewById(R.id.song_list);
SonglistAdapter_test adapter = new SonglistAdapter_test(getApplicationContext(),list);
list2.setAdapter(adapter);
list2.setOnItemClickListener(this);
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,long id) {
try {
mp.reset();
mp.release();
mp = MediaPlayer.create(SongsActivity.this,si[position]);
} catch (Exception e) {}
mp.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mediaPlayer) {
handler.post(new Runnable() {
#Override
public void run() {
controller.setEnabled(true);
controller.show(mp.getDuration());
mp.start();
try {
Method m = android.widget.MediaController.class.getDeclaredMethod("updatePausePlay");
m.setAccessible(true);
m.invoke(controller);
} catch (Exception e) {
}
}
});
}
});
}
#Override
public void start(){
mp.start(); }
#Override
public void pause(){
mp.pause(); }
#Override
public int getDuration(){
return mp.getDuration(); }
#Override
public int getCurrentPosition(){
return mp.getCurrentPosition(); }
#Override
public void seekTo(int pos){
mp.seekTo(pos); }
#Override
public boolean isPlaying(){
return mp.isPlaying(); }
#Override
public int getBufferPercentage(){
return 0; }
#Override
public boolean canPause(){
return true; }
#Override
public boolean canSeekBackward(){
return true; }
#Override
public boolean canSeekForward(){
return true; }
#Override
public int getAudioSessionId(){
return 0; }
#Override
protected void onPause(){
super.onPause();
}
#Override
protected void onResume(){
super.onResume();
}
#Override
protected void onStop(){
super.onStop();
controller.hide();
mp.stop();
mp.release();
}
#Override
public void onRestart(){
super.onRestart();
controller.show();
}
#Override
protected void onDestroy(){
super.onDestroy();
finish();
}
#Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
finish();
}
return super.dispatchKeyEvent(event);
}
The problem is in your onStop() method -- you are releasing your media player there and not recreating it before you show the controller during onRestart(). The onStop() method is not the same as onDestroy() -- onStop() doesn't mean that your activity will necessarily run through onCreate() again when it is resumed.
You should have a look at the Activity Lifecycle to get a better understanding of when these events occur.