我通过反编译检查过,在某些应用程序的清单中,服务不是通过单独的进程启动的。顺便说一下,在任务管理器中,它显示为“正在运行”。
例如Facebook,在Android 4.4.2上,有0个进程和2个服务正在运行。 从文档中(如果我错了,请纠正我)我已经明白服务在其应用程序的相同过程中运行。如果进程终止,则服务停止(可以通过AlarmManager或START_STICKY自动重启)。
因此,如果它没有在一个单独的进程内启动,那么至少应该有一个服务可以运行的进程。那么,即使没有进程,服务是否可能运行?我再说一遍,服务(来自清单)没有得到指令android:background
编辑1: 它似乎是Android 4.4.2的一个错误。请参阅this和this。在我的情况下,当我从列表中滑动应用程序时遇到问题(如第二个链接中所述)
编辑2: 如果我错了,请纠正我,这是我所理解的。
调用Service
时首次创建startService()
对象。将在该服务对象上调用onCreate()
,然后onStartCommand()
将跟随。从现在开始:
stopSelf()
没有被调用但是它没有运行。 START_STICKY
(和其他重启常量)或手动调用startService()。当服务从系统中终止时,将再次调用onCreate。现在,这是Android上的正常行为< 4.4.2。在KitKat上,如果从LRU列表中滑动应用程序,则进程会死亡,即使使用START_STICKY,它也不会自动重新启动。解决方法是AlarmManager。这是对的吗?
答案 0 :(得分:1)
您的服务是您的申请的一部分。根据定义,您的应用程序在服务运行时运行。例如,当AlarmManager在预定时间调用您的服务时,Android首先启动应用程序的进程(如果它尚未运行),然后在正在运行的应用程序中调用您的服务。
一般来说,你是对的:如果应用程序(进程)死了,服务就会死掉。
Android支持清单属性android:process
,它允许您指定应用程序的特定组件应在单独的进程中运行。实际上,这在多个进程中运行多个相同的应用程序副本。 Android只使用其中一个进程来运行一个组件而另一个运行另一个组件。您的应用程序正在两者中运行。
混淆的原因是设置>应用页面使用“进程”和“服务”字样。它似乎使用前者来计算具有UI组件的进程,而后者用于计算所有其他进程。如果您使用adb连接到您的设备并使用“ps”命令,您将获得更好地反映对这些词的共同理解的内容。
答案 1 :(得分:0)
某些Android操作系统的主要问题是当应用程序关闭时,Android OS(在某些操作系统)将终止该服务,如果您无法重新启动该服务,则调用警报马槽开始这样的接收器,
清单是,
<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>
IN Main Activty以这种方式启动报警管理器,
String alarm = Context.ALARM_SERVICE;
AlarmManager am = (AlarmManager) getSystemService(alarm);
Intent intent = new Intent("REFRESH_THIS");
PendingIntent pi = PendingIntent.getBroadcast(this, 123456789, intent, 0);
int type = AlarmManager.RTC_WAKEUP;
long interval = 1000 * 50;
am.setInexactRepeating(type, System.currentTimeMillis(), interval, pi);
这将调用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;
}
}
当打开Android应用程序并关闭应用程序时,这个Alaram会调用一次。服务是这样的,
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");
}
}