当 onCreate() 调用 startService() 时我能期待什么
What can I expect when onCreate() calls startService()
我在研究一些 Android 开源代码时试图了解服务生命周期。
我正在查看一个服务实现,我将其提炼为如下内容...
public class MyService extends Service {
public MyService() { super(); }
@Override
public void onCreate() {
super.onCreate();
init();
//==this seems odd to me
//comment in AOSP says startService() is called to make
//sure Service stays around long enough for the async call
//to complete.
startService(new Intent(this, myservice.class()));
doSomeMoreInitAsync();
}
@Override
public int onStartCommand(final Intent intent, final int flags, final int startId) {
if(actionableIntent(intent,flags,startId)) {
//do something
//NOTE: the Intent passed to startService() in onCreate()
//above will go around this block of code, doing nothing
//except returning START_STICKY
}
return START_STICKY;
}
public void onDestroy() {
//destroy stuff
}
@Override
public IBinder onBind(final Intent intent) {
return mBinder; //an instance of android.os.Binder derivative
// created when this service was instantiated
}
//other stuff
}
为什么有人会像上面那样让 onCreate() 自己调用 startService(),什么也不做?代码中的注释说明了一些问题,但这就像是在对我不理解的生命周期做出假设。即,期望 onCreate() 有效地启动自己的服务是否合理?
我知道,如果一个服务已经启动,那么 onCreate() 只会被调用一次(除非销毁并重新启动,然后会创建一个新的服务实例并在其上调用 onCreate() 一次)。我对这个例子的第一个担心是,在调用 onCreate() 之前服务已经处于初始化状态的底层服务 API 实现存在期望(否则会有无限递归,但有不是)。
但是 onCreate() 不应该是初始化的一部分(尽管是子类的可选部分)吗?
此编码逻辑是否是确保服务强制成为无界服务的合理方式?还是我在看 AOSP 中的一个坏例子,它将来可能有未定义的行为?
你是正确的,如果 Service
是通过 Context.startService
启动的,它将调用 onCreate
和 onStartCommand
。因此,从这个意义上说,当您 return START_STICKY 时,服务将持续 运行 直到调用 stopService()
的显式调用。在此生命周期内,它也将被销毁并重新启动。
另一种创建服务的方法是绑定到它。 As per the docs:
Clients can also use Context.bindService() to obtain a persistent connection to a service. This likewise creates the service if it is not already running (calling onCreate() while doing so), but does not call onStartCommand().
因此,可以通过简单地绑定到服务来创建服务。然而,服务的生命周期表明,如果它被启动或客户端仍然绑定到它,它将保持不变。意思是,如果它是由绑定命令创建的,它会在客户端解除绑定后立即销毁。
因此,如果服务在 onCreate()
中自行启动,它将确保将自身置于启动状态,而不管它是通过绑定还是通过显式调用 startService
创建的.由于没有可操作的意图,onStartCommand
将直接通过。调用 startSevice
的客户端大概会有可操作的 Intent,在这种情况下服务将履行其职责。
我在研究一些 Android 开源代码时试图了解服务生命周期。
我正在查看一个服务实现,我将其提炼为如下内容...
public class MyService extends Service {
public MyService() { super(); }
@Override
public void onCreate() {
super.onCreate();
init();
//==this seems odd to me
//comment in AOSP says startService() is called to make
//sure Service stays around long enough for the async call
//to complete.
startService(new Intent(this, myservice.class()));
doSomeMoreInitAsync();
}
@Override
public int onStartCommand(final Intent intent, final int flags, final int startId) {
if(actionableIntent(intent,flags,startId)) {
//do something
//NOTE: the Intent passed to startService() in onCreate()
//above will go around this block of code, doing nothing
//except returning START_STICKY
}
return START_STICKY;
}
public void onDestroy() {
//destroy stuff
}
@Override
public IBinder onBind(final Intent intent) {
return mBinder; //an instance of android.os.Binder derivative
// created when this service was instantiated
}
//other stuff
}
为什么有人会像上面那样让 onCreate() 自己调用 startService(),什么也不做?代码中的注释说明了一些问题,但这就像是在对我不理解的生命周期做出假设。即,期望 onCreate() 有效地启动自己的服务是否合理?
我知道,如果一个服务已经启动,那么 onCreate() 只会被调用一次(除非销毁并重新启动,然后会创建一个新的服务实例并在其上调用 onCreate() 一次)。我对这个例子的第一个担心是,在调用 onCreate() 之前服务已经处于初始化状态的底层服务 API 实现存在期望(否则会有无限递归,但有不是)。
但是 onCreate() 不应该是初始化的一部分(尽管是子类的可选部分)吗?
此编码逻辑是否是确保服务强制成为无界服务的合理方式?还是我在看 AOSP 中的一个坏例子,它将来可能有未定义的行为?
你是正确的,如果 Service
是通过 Context.startService
启动的,它将调用 onCreate
和 onStartCommand
。因此,从这个意义上说,当您 return START_STICKY 时,服务将持续 运行 直到调用 stopService()
的显式调用。在此生命周期内,它也将被销毁并重新启动。
另一种创建服务的方法是绑定到它。 As per the docs:
Clients can also use Context.bindService() to obtain a persistent connection to a service. This likewise creates the service if it is not already running (calling onCreate() while doing so), but does not call onStartCommand().
因此,可以通过简单地绑定到服务来创建服务。然而,服务的生命周期表明,如果它被启动或客户端仍然绑定到它,它将保持不变。意思是,如果它是由绑定命令创建的,它会在客户端解除绑定后立即销毁。
因此,如果服务在 onCreate()
中自行启动,它将确保将自身置于启动状态,而不管它是通过绑定还是通过显式调用 startService
创建的.由于没有可操作的意图,onStartCommand
将直接通过。调用 startSevice
的客户端大概会有可操作的 Intent,在这种情况下服务将履行其职责。