gpt4 book ai didi

android - 服务不断被破坏

转载 作者:行者123 更新时间:2023-11-29 14:38:19 25 4
gpt4 key购买 nike

我有一项使用媒体播放器播放音乐的服务。该服务由一个 Activity 启动,如果正在播放某些内容并且用户离开该 Activity ,该服务应继续在后台播放。在前台运行服务似乎可行(我可以看到通知),但在几乎所有情况下,服务都会立即被销毁(系统在服务上调用 OnDestroy)。我知道使用 startForeground 并不意味着该服务永远不会被终止,但它会立即被破坏,所以我想迫使系统终止它的资源太少并不是原因。

我是这样实现的:在 Activity 的 OnCreate 中,我(在后台)启动并绑定(bind)服务。在 OnPause 中,我将服务带到前台以免被破坏:

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_play);

// start service
startService(new Intent(this, MyService.class));
// connect to service
bindToService();
...
}

@Override
protected void onDestroy() {
unbindFromService();
super.onDestroy();
};

@Override
protected void onStart() {
super.onStart();
}

@Override
protected void onStop() {
super.onStop();
}

@Override
protected void onPause() {
super.onPause();

if (MediaPlayerService.getInstance().getStatus() == MEDIA_PLAYER_STATUS.Started) {
// current playing something => keep service running
mService.startForeground();
} else {
// stop service
stopService(new Intent(MainActivity.this, MyService.class));
}
}

@Override
protected void onResume() {
super.onResume();

// remove service from foreground
if (mService != null) {
mService.stopForeground();
}
}

void bindToService() {
// Establish a connection with the service. We use an explicit
// class name because we want a specific service implementation that
// we know will be running in our own process (and thus won't be
// supporting component replacement by other applications).
bindService(new Intent(MainActivity.this, MyService.class), mConnection, Context.BIND_AUTO_CREATE);
mIsBound = true;
}

void unbindFromService() {
if (mIsBound) {
// Detach our existing connection.
unbindService(mConnection);
mIsBound = false;
}
}

private final ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName className, IBinder service) {
// This is called when the connection with the service has been
// established, giving us the service object we can use to
// interact with the service. Because we have bound to a explicit
// service that we know is running in our own process, we can
// cast its IBinder to a concrete class and directly access it.
mService = ((MyService.LocalBinder) service).getService();
mService.registerClient(MainActivity.this);
}

@Override
public void onServiceDisconnected(ComponentName className) {
// This is called when the connection with the service has been
// unexpectedly disconnected -- that is, its process crashed.
// Because it is running in our same process, we should never
// see this happen.
mService = null;
mService.unRegisterClient(MainActivity.this);
}
};

我的服务中的 start/stopForeground 函数如下所示:

public void startForeground() {
String songName = "blabla";
// assign the song name to songName
PendingIntent pi = PendingIntent.getActivity(getApplicationContext(), 0,
new Intent(getApplicationContext(), MainActivity.class),
PendingIntent.FLAG_UPDATE_CURRENT);
Notification notification = new Notification();
notification.tickerText = songName;
notification.icon = R.drawable.ic_launcher;
notification.flags |= Notification.FLAG_ONGOING_EVENT;
notification.setLatestEventInfo(getApplicationContext(), "MusicPlayerSample",
"Playing: " + songName, pi);
startForeground(NOTIFICATION_ID, notification);
}

public void stopForeground() {
stopForeground(true);
}

如果我离开 Activity ,为什么服务会不断被破坏,有什么想法吗?

最佳答案

问题出在onCreate/onDestroy 中的bind/unbind。我无法真正解释它,但是即使您在 Activity 的 onCreate() 中使用 startService(),绑定(bind)到该生命周期状态也会导致服务被销毁。

此设置现在运行良好:

  • 在 Activity 的 onCreate() 中使用 startService() 启动服务。
  • 服务的 onStartCommand() 必须返回 Service.START_STICKY
  • 在 Activity 的 onResume() 中绑定(bind)服务
  • 在 Activity 的 onPause() 中,如果正在播放,调用服务的 startForeground() 并解除绑定(bind)。
  • 如果当前没有播放任何内容,则在 Activity 的 onDestroy() 中调用 stopService()。

关于android - 服务不断被破坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22895001/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com