前台服务在执行互联网相关操作时被杀死

var*_*nkr 12 android android-service

更新:以前我找不到一个定义良好的模式,以确定我的前台服务何时被杀死.在发现这种情况后,对设备进行了更多调试(并未发生任何事情).

1.)很多时候,当我打开chrome加载网站时,前台服务被杀死了.有时即使我使用whatsapp,也会发生这种情况.

2.)没有例外,堆栈跟踪没有显示任何有用的东西.

原始问题如下:

StackOverflow上有很多这样的问题,但到目前为止我已阅读的答案主要是说它取决于Android,我们没有100%保证前台服务不会被杀死.一些答案建议START_STICKY,但这对我的情况没有多大帮助.

在我的情况下,我有一个音乐播放器应用程序,它具有前台服务.这项服务在某些设备上被杀死,主要是Xiomi的某些版本(Android版本为5.1.1).现在我明白android可能内存不足,所以我的前台服务被杀了,但是为什么其他音乐播放器应用程序永远不会经历这样的终止.什么是他们做得对,我不是?

我使用了我的服务前台服务startForeground.此外,我返回START_STICKYonStartCommand,虽然这没有帮助,因为服务在4-5秒后重新启动,如果被杀死.要使用我的活动绑定我的服务

bindService(playIntent, musicConnection, Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT );
Run Code Online (Sandbox Code Playgroud)

那么究竟我可以在我的应用程序中改进/更改以防止这种情况发生,如果其他应用程序正常工作,那么我的情况肯定会出现问题.有人可以请帮助.提前致谢 !!

编辑:

这就是我调用startForeground()的方法

public void sendNotification() {

        Intent notIntent = new Intent(this, MainActivity.class);
        notIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendInt = PendingIntent.getActivity(this, 0,
                notIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        Bitmap bitmap = null;
        if (!notificationShowing || !forwarded) {
            Log.i(TAG, "present");
            String title = CommonUtils.getSongFromID(songIndex, this);

            bigView.setTextViewText(R.id.title, title);
            bigView.setImageViewBitmap(R.id.img, bitmap);

            smallView.setTextViewText(R.id.title1, title);
            smallView.setImageViewBitmap(R.id.img1, bitmap);

            if (pauseButton == 1) {
                bigView.setImageViewResource(R.id.pause, R.drawable.pause_noti);
                smallView.setImageViewResource(R.id.pause1, R.drawable.pause_noti);
            } else {
                bigView.setImageViewResource(R.id.pause, R.drawable.play_noti);
                smallView.setImageViewResource(R.id.pause1, R.drawable.play_noti);
            }

            musicNotification = builder.setContentIntent(pendInt)
                    .setSmallIcon(R.drawable.logo1)
                    .setTicker(songTitle)
                    .setOngoing(true)
                    .setContentTitle("Playing")
                    .setStyle(new Notification.BigTextStyle().bigText("Song App"))
                    .setContentText(songTitle)
                    .setPriority(Notification.PRIORITY_MAX)
                    .build();

            musicNotification.contentView = smallView;
            musicNotification.bigContentView = bigView;

            musicNotification.contentIntent = pendInt;

            Intent switchIntent = new Intent("pause");
            switchIntent.putExtra("button", "pause");
            PendingIntent pendingSwitchIntent = PendingIntent.getBroadcast(this, 100, switchIntent, PendingIntent.FLAG_UPDATE_CURRENT);
            bigView.setOnClickPendingIntent(R.id.pause, pendingSwitchIntent);
            smallView.setOnClickPendingIntent(R.id.pause1, pendingSwitchIntent);

            Intent switchIntent1 = new Intent("forward");
            switchIntent1.putExtra("button", "forward");
            PendingIntent pendingSwitchIntent2 = PendingIntent.getBroadcast(this, 100, switchIntent1, PendingIntent.FLAG_UPDATE_CURRENT);
            bigView.setOnClickPendingIntent(R.id.forward, pendingSwitchIntent2);
            smallView.setOnClickPendingIntent(R.id.forward1, pendingSwitchIntent2);

            Intent switchIntent2 = new Intent("previous");
            switchIntent2.putExtra("button", "previous");
            PendingIntent pendingSwitchIntent3 = PendingIntent.getBroadcast(this, 100, switchIntent2, PendingIntent.FLAG_UPDATE_CURRENT);
            bigView.setOnClickPendingIntent(R.id.previous, pendingSwitchIntent3);
            smallView.setOnClickPendingIntent(R.id.previous1, pendingSwitchIntent3);

            Intent switchIntent3 = new Intent("end");
            switchIntent3.putExtra("button", "end");
            PendingIntent pendingSwitchIntent4 = PendingIntent.getBroadcast(this, 100, switchIntent3, PendingIntent.FLAG_UPDATE_CURRENT);
            bigView.setOnClickPendingIntent(R.id.end, pendingSwitchIntent4);
            smallView.setOnClickPendingIntent(R.id.end1, pendingSwitchIntent4);

            startForeground(NOTIFY_ID, musicNotification);
            notificationShowing = true;
        }
        forwarded = false;

    }
Run Code Online (Sandbox Code Playgroud)

Sav*_*een 9

由于以下原因,这发生在Xiomi手机.

MIUI 7.0的解决方案=>安全性=>自动启动=>选择要在后台 运行的应用程序=>重新启动重启后,您的设备应该像其他Android设备一样在后台运行您的应用程序服务.

MIUI 4.0设置

MIUI AutoStart详细说明

如果你正在寻找其他手机,那么检查这里是服务结构.它会自动重启,但当你重新启动电话时,请调用BootReceiver.

public class AppService extends Service {

private class LocalBinder extends Binder {
    public AppService getServerInstance() {

        return AppService.this;
    }
}


@Override
public IBinder onBind(Intent intent) {
    return mBinder;
}


@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    // If we get killed, after returning from here, restart

    return Service.START_STICKY;
}

@Override
public void onCreate() {
    super.onCreate();

} 

@Override
public void onDestroy() {

}

}
Run Code Online (Sandbox Code Playgroud)

谢谢希望这会对你有所帮助.


Pra*_*iya 1

\n

该服务在某些设备上被终止,主要是小米的某些版本\n(Android 版本为 5.1.1)

\n
\n\n

不确定这一点,但根据我的理解,这可能是因为

\n\n
    \n
  1. 供应商的操作系统定制中存在错误。
  2. \n
  3. Android 中关于前台服务优先级的错误,这些错误是由服务绑定标志的各种组合(即 BIND_AUTO_CREATE、BIND_IMPORTANT 等)触发的。请阅读Robin Davies 的回答
  4. \n
\n\n

我不知道你是否使用startService()。但如果你不这样做,那么按照本文档

\n\n
\n

您可以创建一个既已启动又已绑定的服务。也就是说,可以通过调用 来启动服务,这允许服务无限期地运行,并且还允许客户端通过调用bindService()startService()来绑定到服务。(这称为绑定到已启动的服务)

\n\n

如果您允许启动并绑定服务,那么当服务启动后,当所有客户端解除绑定时,系统不会销毁该服务。相反,您必须通过调用stopSelf()或显式停止服务stopService()

\n\n

虽然您通常应该实现onBind()或 onStartCommand (),但有时有必要同时实现两者。例如,音乐播放器可能会发现允许其服务无限期运行并提供绑定很有用。这样,活动就可以启动服务来播放一些音乐,并且即使用户离开应用程序,音乐也会继续播放。然后,当用户返回应用程序时,该活动可以绑定到服务以重新获得对播放的控制。

\n
\n\n

请务必阅读有关管理绑定服务的生命周期的部分,以获取有关将绑定添加到已启动服务时的服务生命周期的更多信息。

\n\n

onStartCommand将在启动服务的情况下调用,因此仅START_STICKY在以下情况下工作startService()

\n\n

更新进程日志

\n\n
\n

程序 # 5: prcp F/S/IF trm: 0 22407:com.wave.music.player/u0a2\n (fg-service)

\n
\n\n

在您的进程中,使用 adj 设置记录在前台运行的播放器服务prcp (visible foreground service),这意味着它实际上是坚不可摧的。您的服务仍然被操作系统破坏,但可用于运行新启动的应用程序的内存可能非常低。根据本文档

\n\n
\n

系统中只会有几个前台进程,并且只有当内存太低以至于这些进程无法继续运行时,这些进程才会被杀死作为最后的手段。通常,此时设备已达到内存分页状态,因此需要执行此操作以保持用户界面响应。

\n
\n\n

所以我认为你没有做错什么。我只是想建议您阅读官方 Android 开发人员文档,并尝试在单独的进程中运行您的服务(文档建议音乐播放器应用程序采用这种方法)。请小心实施此操作,因为如果操作不当,它可能会轻松增加\xe2\x80\x94而不是减少\xe2\x80\x94您的 RAM 占用空间。

\n