问题
I currently have an Activty
that when created starts and binds with a service
. This service
has a mediaplayer
. What I would like to do is if the activity is resumed
then the service
keeps playing, etc. When the activity
is destroyed, it should stop
the service
. So far I can get both the service to keep playing when activity is re-activated and the service to stop when a new activity is created but not both together. Any suggestions or ideas? Thanks. Code below:
Activity class:
public class DUBAudioActivity extends Activity{
private static final String TAG = DUBAudioActivity.class.getSimpleName();
Button playPauseButtonDUB;
Intent playbackServiceIntentDUB;
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.sdrplaylist_dubstep);
playPauseButtonDUB = (Button)findViewById(R.id.playpausebuttonDUB);
playbackServiceIntentDUB = new Intent(this, DUBAudioService.class);
Log.d(TAG, "created intent");
startService(playbackServiceIntentDUB);
Log.d(TAG, "bound service");
//
//set button text
playPauseButtonDUB.setText("Pause");
//set button tag
playPauseButtonDUB.setTag(1);
playPauseButtonDUB.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
//set the tag stuff
final int status = (Integer) v.getTag();
//create if statement for the button to do play and pause
if(status==1){
playPauseButtonDUB.setText("Play");
v.setTag(0);
Log.d(TAG, "set tag to 0");
baServiceDUB.pauseSong();
Log.d(TAG, "pause song");
}else{
playPauseButtonDUB.setText("Pause");
v.setTag(1);
Log.d(TAG, "set tag to 1");
baServiceDUB.playSong();
Log.d(TAG, "song play'd");
}
}
});
//
}
private DUBAudioService baServiceDUB;
private ServiceConnection serviceConnectionDUB = new ServiceConnection(){
public void onServiceConnected(ComponentName className, IBinder baBinder) {
baServiceDUB =
((DUBAudioService.DUBBackgroundAudioServiceBinder)baBinder).getService();
}
public void onServiceDisconnected(ComponentName className){
baServiceDUB = null;
}
//
};
void doBindService(){
getApplicationContext().bindService(playbackServiceIntentDUB, serviceConnectionDUB,
Context.BIND_AUTO_CREATE);
Log.d(TAG, "do bind service");
}
@Override
public void onResume() {
getApplicationContext().bindService(playbackServiceIntentDUB, serviceConnectionDUB,
Context.BIND_AUTO_CREATE);
Log.d(TAG, "on resume + re-bound service");
super.onResume();
}
@Override
public void onDestroy(){
stopService(playbackServiceIntentDUB);
getApplicationContext().unbindService(serviceConnectionDUB);
Log.d(TAG, "destroy'd + unbind service");
//finish();
super.onDestroy();
}
}
Service Class:
public class DUBAudioService extends Service implements OnPreparedListener, OnCompletionListener{
Toast loadingMessage;
private static final String TAG = DUBAudioService.class.getSimpleName();
public boolean isRunning;
//to keep track of the playlist item
Vector<PlaylistFile> playlistItems;
MediaPlayer mediaPlayer;
String baseURL = "";
//keep track of which item from the vector we are on
int currentPlaylistltemNumber = 0;
public class DUBBackgroundAudioServiceBinder extends Binder {
DUBAudioService getService() {
return DUBAudioService.this;
}
}
private final IBinder basBinderDUB = new DUBBackgroundAudioServiceBinder();
@Override
public IBinder onBind(Intent intent) {
return basBinderDUB;
}
@Override
public void onCreate() {
Log.v("PLAYERSERVICE", "onCreate");
mediaPlayer = new MediaPlayer();
new MusicAsync().execute();
Log.d(TAG, "execute'd async");
mediaPlayer.setOnPreparedListener(this);
Log.d(TAG, "set on prepared listener");
mediaPlayer.setOnCompletionListener(this);
Log.d(TAG, "set on completion listener");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//if (!mediaPlayer.isPlaying()) {
// mediaPlayer.start();
//}
return START_STICKY;
}
class MusicAsync extends AsyncTask<Void,Void,Void>{
@Override
protected void onPreExecute(){
}
@Override
protected Void doInBackground(Void... arg0) {
// TODO Auto-generated method stub
//create empty vector
playlistItems = new Vector<PlaylistFile>();
//HTTP client library
HttpClient httpClient = new DefaultHttpClient();
HttpGet getRequest = new HttpGet ("http://dl.dropbox.com/u/24535120/m3u%20playlist/DubstepPlaylist.m3u"); //i think you could add the m3u thing in here
Log.v("URI",getRequest.getURI().toString());
try {
HttpResponse httpResponse = httpClient.execute(getRequest);
if (httpResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
// ERROR MESSAGE
Log.v("HTTP ERROR",httpResponse.getStatusLine().getReasonPhrase());
}
else {
InputStream inputStream = httpResponse.getEntity().getContent();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = bufferedReader.readLine()) != null) {
Log.v("PLAYLISTLINE","ORIG: " + line);
if (line.startsWith("#")) {
//Metadata
//Could do more with this but not fo now
} else if (line.length() > 0) {
String filePath = "";
if (line.startsWith("http://")) {
// Assume its a full URL
filePath = line;
} else {
//Assume it’s relative
filePath = getRequest.getURI().resolve(line).toString();
}
PlaylistFile playlistFile = new PlaylistFile(filePath);
playlistItems.add (playlistFile);
}
}
inputStream.close();
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e. printStackTrace();
}
currentPlaylistltemNumber = 0;
if (playlistItems.size() > 0)
{
String path = ((PlaylistFile)playlistItems.get(currentPlaylistltemNumber)).getFilePath();
try {
mediaPlayer.setDataSource(path);
mediaPlayer.prepareAsync();}
catch (IllegalArgumentException e)
{ e.printStackTrace();
}catch (IllegalStateException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();}
}
return null;
}
//
protected void onPostExecute(Void result){
//playButton. setEnabled (false);
}
}
@Override
public void onStart(Intent intent, int startId) {
// TODO Auto-generated method stub
super.onStart(intent, startId);
}
public void onDestroy() {
if (mediaPlayer.isPlaying()) {
mediaPlayer.stop();
Log.d(TAG, "music stopp'd");
}
//mediaPlayer.release();
Log.d(TAG, "onDestroy");
}
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
// TODO Auto-generated method stub\
Log.d(TAG, "music is prepared and will start");
mediaPlayer.start();
}
public void onCompletion(MediaPlayer _mediaPlayer) {
Log.d(TAG, "Song completed, next song");
mediaPlayer.stop();
mediaPlayer.reset();
if (playlistItems.size() > currentPlaylistltemNumber + 1) {
currentPlaylistltemNumber++;
String path =
((PlaylistFile)playlistItems.get(currentPlaylistltemNumber)).getFilePath();
try {
mediaPlayer.setDataSource(path);
mediaPlayer.prepareAsync();
} catch (IllegalArgumentException e) {
e. printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
class PlaylistFile {
String filePath;
public PlaylistFile(String _filePath) {
filePath = _filePath;
}
public void setFilePath(String _filePath) {
filePath = _filePath;
}
public String getFilePath() {
return filePath;
}
}
public void playSong(){
Log.d(TAG, "start'd");
mediaPlayer.start();
}
public void pauseSong(){
Log.d(TAG, "pause'd");
mediaPlayer.pause();
}
}
回答1:
I'd say you got lucky that it stopped -- only onPause()
is guaranteed to be called when your Activity is backgrounded. The only time onDestroy()
is called is when the system decides to reclaim the memory your app is using
The only guaranteed lifecycle calls are:
onCreate()
only when the app is starting from scratch;onResume()
every run, whether paused or first created;onPause()
every time the system is moving your app to the background, period.
来源:https://stackoverflow.com/questions/6720774/android-resuming-service-in-activity-and-destroying-them-on-destroy