环境: - Android 6.0,华为智能手机
我的应用程序是一个 IM 客户端,它必须与服务器保持连接并从中接收消息。所以我必须让它一直保持活力,只要网络连接可用。
我使用前台服务使我的应用程序在后台保持活跃。请参阅:android-keeping-a-background-service-alive-preventing-process-death此方法适用于 Android 4.1 和 4.4。但它在 Android 5.1 和 6.0 上失败。单击电源按钮后,应用程序进程大约 10 秒后被终止。
下面是重新制作的步骤。这是一个简单的演示应用程序,它启动一个线程来跟踪进程是被杀死还是活着。
- 启动一个带有活动的 android 应用程序;
- 启动一个日志线程以每秒记录一条消息;
覆盖服务 onStartCommand() 方法,调用 startForeground() 并显示通知;
单击按钮启动服务;
- 按智能手机上的HOME/BACK键返回首页;
- 按POWER键关闭屏幕;
等待大约 10 秒,记录线程停止;
单击应用程序图标以再次启动应用程序;
- 日志线程启动,但其索引从 0 开始;并且 PID 已更改(请参见下面的屏幕截图)!
注意:我注意到一件奇怪的事情:当应用程序再次启动时,活动的 onCreate() 不会被调用!
任何帮助表示赞赏!提前致谢!
这是我启动服务的代码:
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
AppGlobal.logDebug(">>>> onStartCommand()");
if (intent.getAction().equals(Constants.ACTION.STARTFOREGROUND_ACTION)) {
Log.i(LOG_TAG, "==== Received Start Foreground Intent ");
showNotification();
Toast.makeText(this, "Service Started!", Toast.LENGTH_SHORT).show();
} else if (intent.getAction().equals(Constants.ACTION.PREV_ACTION)) {
Log.i(LOG_TAG, "Clicked Previous");
Toast.makeText(this, "Clicked Previous!", Toast.LENGTH_SHORT)
.show();
} else if (intent.getAction().equals(Constants.ACTION.PLAY_ACTION)) {
Log.i(LOG_TAG, "Clicked Play");
Toast.makeText(this, "Clicked Play!", Toast.LENGTH_SHORT).show();
} else if (intent.getAction().equals(Constants.ACTION.NEXT_ACTION)) {
Log.i(LOG_TAG, "Clicked Next");
Toast.makeText(this, "Clicked Next!", Toast.LENGTH_SHORT).show();
} else if (intent.getAction().equals(
Constants.ACTION.STOPFOREGROUND_ACTION)) {
Log.i(LOG_TAG, "==== Received Stop Foreground Intent");
stopForeground(true);
stopSelf();
}
return START_STICKY;
}
private void showNotification() {
AppGlobal.logDebug(">>>> show notification");
Intent notificationIntent = new Intent(this, StTest33MainActivity.class);
notificationIntent.setAction(Constants.ACTION.MAIN_ACTION);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
notificationIntent, 0);
Intent previousIntent = new Intent(this, ForegroundService.class);
previousIntent.setAction(Constants.ACTION.PREV_ACTION);
PendingIntent ppreviousIntent = PendingIntent.getService(this, 0,
previousIntent, 0);
Intent playIntent = new Intent(this, ForegroundService.class);
playIntent.setAction(Constants.ACTION.PLAY_ACTION);
PendingIntent pplayIntent = PendingIntent.getService(this, 0,
playIntent, 0);
Intent nextIntent = new Intent(this, ForegroundService.class);
nextIntent.setAction(Constants.ACTION.NEXT_ACTION);
PendingIntent pnextIntent = PendingIntent.getService(this, 0,
nextIntent, 0);
Bitmap icon = BitmapFactory.decodeResource(getResources(),
R.drawable.ic_launcher);
Notification notification = new NotificationCompat.Builder(this)
.setContentTitle("TutorialsFace Music Player")
.setTicker("TutorialsFace Music Player")
.setContentText("My song")
.setSmallIcon(R.drawable.ic_launcher)
.setLargeIcon(Bitmap.createScaledBitmap(icon, 128, 128, false))
.setContentIntent(pendingIntent)
.setOngoing(true)
.addAction(android.R.drawable.ic_media_previous, "Previous",
ppreviousIntent)
.addAction(android.R.drawable.ic_media_play, "Play",
pplayIntent)
.addAction(android.R.drawable.ic_media_next, "Next",
pnextIntent).build();
startForeground(Constants.NOTIFICATION_ID.FOREGROUND_SERVICE,
notification);
}