Android 如果进程被终止,为什么服务仍在运行?

Android 如果进程被终止,为什么服务仍在运行?,android,process,android-service,Android,Process,Android Service,通过反编译,我检查了一些应用程序的清单中的服务是否不是通过单独的进程启动的。顺便说一下,在任务管理器中,它显示为“正在运行” 例如,Android 4.4.2上的Facebook已经运行了0个进程和2个服务。 从文档中(如果我错了,请纠正我),我了解到服务运行在其应用程序的同一进程中。如果进程终止,服务将停止(并可由AlarmManager或START_自动重新启动) 因此,如果它不是在单独的进程中启动的,那么应该至少有一个进程可以运行该服务。那么,即使没有进程,服务也可能运行吗?我重复一遍,服

通过反编译,我检查了一些应用程序的清单中的服务是否不是通过单独的进程启动的。顺便说一下,在任务管理器中,它显示为“正在运行”

例如,Android 4.4.2上的Facebook已经运行了0个进程和2个服务。 从文档中(如果我错了,请纠正我),我了解到服务运行在其应用程序的同一进程中。如果进程终止,服务将停止(并可由AlarmManager或START_自动重新启动)

因此,如果它不是在单独的进程中启动的,那么应该至少有一个进程可以运行该服务。那么,即使没有进程,服务也可能运行吗?我重复一遍,服务(来自清单)没有得到android:background指令

编辑1: 这似乎是安卓4.4.2的一个缺陷。见和。在我的例子中,当我从列表中滑动应用程序时遇到问题(如第二个链接中所述)

编辑2: 如果我错了,请纠正我,这是我所理解的

调用
startService()
时,将首次创建
Service
对象<将对该服务对象调用code>onCreate(),随后将调用
onStartCommand()
。从现在起:

  • 如果进程死亡,服务对象仍然存在(如果
    stopSelf()
    未调用),但它未运行
  • 如果服务终止,重新创建的唯一方法是从
    START\u STICKY
    (和其他重启常量)或手动调用startService()。当服务从系统中终止时,将再次调用onCreate

现在,这是Android<4.4.2上的正常行为。在KitKat上,如果您从LRU列表中滑动应用程序,则进程将终止,即使使用START_STICKY,也不会自动重新启动。解决方法是AlarmManager。是否正确?

您的服务是应用程序的一部分。根据定义,应用程序在服务运行时正在运行。例如,当AlarmManager在预定时间调用您的服务时,Android首先启动应用程序的进程(如果尚未运行),然后在正在运行的应用程序中调用您的服务

一般来说,您是正确的:如果应用程序(进程)死亡,服务也将随之死亡

Android支持Manifest属性,
Android:process
,它允许您指定应用程序的特定组件应在单独的进程中运行。这实际上是在多个进程中运行应用程序的多个相同副本。Android只是使用其中一个进程运行一个组件,另一个进程运行另一个组件。您的应用程序正在这两种环境中运行


造成混淆的原因是设置>应用程序页面使用“流程”和“服务”这两个词的方式。它似乎使用前者来计算包含UI组件的进程,而使用后者来计算所有其他进程。如果你使用adb连接到你的设备并使用“ps”命令,你会得到一些更好地反映这些词的共同理解的东西。

一些android操作系统的主要问题是当应用程序关闭时,android操作系统(在某些操作系统中)将终止服务,如果您无法重新启动服务,请致电报警管理器,像这样启动接收器

public class BackgroundService extends Service {
    private String LOG_TAG = null;

    @Override
    public void onCreate() {
        super.onCreate();
        LOG_TAG = "app_name";
        Log.i(LOG_TAG, "service created");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i(LOG_TAG, "In onStartCommand");
        //ur actual code
        return START_STICKY;
    }

    @Override
    public IBinder onBind(Intent intent) {
        // Wont be called as service is not bound
        Log.i(LOG_TAG, "In onBind");
        return null;
    }

    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    @Override
    public void onTaskRemoved(Intent rootIntent) {
        super.onTaskRemoved(rootIntent);
        Log.i(LOG_TAG, "In onTaskRemoved");
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.i(LOG_TAG, "In onDestroyed");
    }
}
清单是

         <service
            android:name=".BackgroundService"
            android:description="@string/app_name"
            android:enabled="true"
            android:label="Notification" />
        <receiver android:name="AlarmReceiver">
            <intent-filter>
                <action android:name="REFRESH_THIS" />
            </intent-filter>
        </receiver>
这将调用reciver,reciver是

public class AlarmReceiver extends BroadcastReceiver {
    Context context;

    @Override
    public void onReceive(Context context, Intent intent) {
        this.context = context;

        System.out.println("Alarma Reciver Called");

        if (isMyServiceRunning(this.context, BackgroundService.class)) {
            System.out.println("alredy running no need to start again");
        } else {
            Intent background = new Intent(context, BackgroundService.class);
            context.startService(background);
        }
    }

    public static boolean isMyServiceRunning(Context context, Class<?> serviceClass) {
        ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningServiceInfo> services = activityManager.getRunningServices(Integer.MAX_VALUE);

        if (services != null) {
            for (int i = 0; i < services.size(); i++) {
                if ((serviceClass.getName()).equals(services.get(i).service.getClassName()) && services.get(i).pid != 0) {
                    return true;
                }
            }
        }
        return false;
    }
}

非常感谢。所以在设置中使用的“进程”一词意味着“拥有UI的进程”?这很奇怪,因为(从清单中)似乎该特定服务没有使用andoird:process声明在单独的进程中运行。是否有关于流程和服务之间区别的来源(在设置选项卡中?)。谢谢你,阿加尼,我已经拨弄了一点,我收回了那部分。我根本不知道那两个数字是什么-(标记为“服务”的数字似乎是进程中运行的服务数。我根本不知道“进程”是什么意思。设置>应用程序>运行列表中的一个条目对应于“进程”这个词的正常含义,一个Linux进程。
public class BackgroundService extends Service {
    private String LOG_TAG = null;

    @Override
    public void onCreate() {
        super.onCreate();
        LOG_TAG = "app_name";
        Log.i(LOG_TAG, "service created");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i(LOG_TAG, "In onStartCommand");
        //ur actual code
        return START_STICKY;
    }

    @Override
    public IBinder onBind(Intent intent) {
        // Wont be called as service is not bound
        Log.i(LOG_TAG, "In onBind");
        return null;
    }

    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    @Override
    public void onTaskRemoved(Intent rootIntent) {
        super.onTaskRemoved(rootIntent);
        Log.i(LOG_TAG, "In onTaskRemoved");
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.i(LOG_TAG, "In onDestroyed");
    }
}