在API级别1中添加
服务
public abstract class Service
extends ContextWrapper implements ComponentCallbacks2
java.lang.Object继承 |
|||
↳ |
android.content.Context |
||
|
↳ |
android.content.ContextWrapper |
|
|
|
↳ |
android.app.Service |
已知的直接子类 AbstractInputMethodService,AccessibilityService,AutofillService,CallScreeningService,CameraPrewarmService,CarrierMessagingService,CarrierService,ChooserTargetService,ConditionProviderService,ConnectionService,DeviceAdminService以及其他20个。 |
已知的间接子类 InputMethodService |
服务是一种应用程序组件,表示应用程序希望在不与用户交互的情况下执行较长时间运行的操作,或者为其他应用程序提供要使用的功能。每个服务类必须
请注意,服务与其他应用程序对象一样,在其托管进程的主线程中运行。这意味着,如果您的服务要进行任何CPU密集型(例如MP3播放)或阻止(例如网络)操作,它应该产生自己的线程来执行该工作。有关此内容的更多信息,请参见 进程和线程。该IntentService班是作为一个标准的实施服务的,有它自己的线程在哪里做它安排其工作。
这里涉及的主题:
开发者指南
有关如何创建服务的详细讨论,请阅读 服务开发人员指南。
什么是服务?
关于Service类的大多数混淆实际上都围绕着它不是:
因此,服务本身实际上非常简单,提供两个主要特征:
当实际创建Service组件时,由于上述任何一个原因,系统实际执行的所有操作都是实例化组件并onCreate()在主线程上调用它和任何其他适当的回调。服务由适当的行为来实现,例如创建一个辅助线程来完成它的工作。
请注意,因为Service本身非常简单,所以您可以根据需要简单或复杂地进行交互:将其视为本地Java对象,您可以直接进行方法调用(如本地服务示例所示),提供使用AIDL的完整远程接口。
服务生命周期
系统可以运行服务有两个原因。如果有人调用,Context.startService()则系统将检索服务(创建它并onCreate()在需要时调用其方法),然后onStartCommand(Intent, int, int)使用客户端提供的参数调用其方法。此服务将在此时继续运行,直到Context.stopService()或被 stopSelf()调用。请注意,对Context.startService()的多次调用不会嵌套(尽管它们会导致对onStartCommand()的多次相应调用),因此无论启动多少次,一旦Context.stopService()或stopSelf将停止服务() 叫做; 但是,服务可以使用它们的stopSelf(int)方法来确保在处理启动的意图之前不停止服务。
对于已启动的服务,他们可以决定运行两种主要的操作模式,具体取决于它们从onStartCommand()返回的值:START_STICKY用于根据需要显式启动和停止的服务,同时START_NOT_STICKY 或START_REDELIVER_INTENT用于服务应该只在处理发送给它们的任何命令时保持运行。有关语义的更多详细信息,请参阅链接的文档。
客户端还可以Context.bindService()用于获取与服务的持久连接。如果服务尚未运行(onCreate()在执行此操作时调用),这同样会创建服务,但不会调用onStartCommand()。客户端将接收IBinder服务从其onBind(Intent)方法返回的 对象 ,允许客户端然后回调该服务。只要建立连接,服务将保持运行(无论客户端是否保留对服务的IBinder的引用)。通常,IBinder返回的是一个用aidl编写的复杂接口。
服务既可以启动,也可以绑定连接。在这种情况下,只要系统启动或与Context.BIND_AUTO_CREATE 标志有一个或多个连接 ,系统就会保持服务运行。一旦这些情况都不成立,onDestroy()就会调用服务的方法并有效终止服务。从onDestroy()返回时,应完成所有清理(停止线程,取消注册接收器)。
权限
在清单
截至Build.VERSION_CODES.GINGERBREAD使用时 Context.startService(Intent),您还可以设置Intent.FLAG_GRANT_READ_URI_PERMISSION和/或Intent.FLAG_GRANT_WRITE_URI_PERMISSION使用Intent。这将授予服务临时访问Intent中特定URI的权限。在服务调用stopSelf(int)该启动命令或稍后启动命令或服务已完全停止之前,访问将保持不变。这适用于授予对未请求保护服务权限的其他应用程序的访问权限,或甚至根本不导出服务的权限。
此外,服务可以通过ContextWrapper.checkCallingPermission(String) 在执行该调用的实现之前调用该方法来保护具有权限的单个IPC调用 。
有关 权限和安全性的更多信息,请参阅“ 安全性和权限”文档。
流程生命周期
只要服务已启动或客户端绑定服务,Android系统将尝试保持托管服务的进程。当内存不足并且需要杀死现有进程时,托管服务的进程的优先级将是以下可能性中的较高者:
请注意,这意味着您的服务运行的大部分时间,如果系统处于严重的内存压力下,它可能会被系统杀死。如果发生这种情况,系统稍后将尝试重新启动该服务。这样做的一个重要结果是,如果您实现onStartCommand() 计划要异步完成或在另一个线程中完成工作,那么您可能希望让START_FLAG_REDELIVERY系统为您重新提供一个Intent,这样如果您的服务是在处理它时被杀死。
Activity当然,在与服务相同的过程中运行的其他应用程序组件(例如a )可以提高整个过程的重要性,而不仅仅是服务本身的重要性。
本地服务样本
服务的最常见用途之一是作为与应用程序的其他部分一起运行的辅助组件,与其余组件在同一进程中运行。除非另有明确说明,否则.apk的所有组件都在同一进程中运行,因此这是典型情况。
当以这种方式使用时,通过假设组件处于相同的过程中,您可以极大地简化它们之间的交互:服务的客户端可以简单地将它们从它接收的IBinder转换为由服务发布的具体类。
此处显示了此服务的使用示例。首先是服务本身,绑定时发布自定义类:
public class LocalService extends Service {
private NotificationManager mNM;
//通知的唯一标识号。
//我们在通知开始时使用它,并取消它。
private int NOTIFICATION = R.string.local_service_started;
/ **
*客户访问的类。因为我们总是知道这项服务
*在与客户相同的流程中运行,我们不需要处理
* IPC。
* /
公共类LocalBinder扩展Binder {
LocalService getService(){
返回LocalService.this;
}
}
@覆盖
public void onCreate(){
mNM =(NotificationManager)getSystemService(NOTIFICATION_SERVICE);
//显示有关我们的通知。我们在状态栏中放了一个图标。
显示通知();
}
@覆盖
public int onStartCommand(Intent intent,int flags,int startId){
Log.i(“LocalService”,“Received start id”+ startId +“:”+ intent);
返回START_NOT_STICKY;
}
@覆盖
public void onDestroy(){
//取消持久通知。
mNM.cancel(NOTIFICATION);
//告诉我们停止的用户
Toast.makeText(this,R.string.local_service_stopped,Toast.LENGTH_SHORT).show();
}
@覆盖
public IBinder onBind(Intent intent){
返回mBinder;
}
//这是从客户端接收交互的对象。看到
// RemoteService以获得更完整的示例。
私人决赛IBinder mBinder = new LocalBinder();
/ **
*在此服务运行时显示通知。
* /
private void showNotification(){
//在此示例中,我们将使用相同的文本作为自动收报机和扩展通知
CharSequence text = getText(R.string.local_service_started);
// PendingIntent如果用户选择此通知,则启动我们的活动
PendingIntent contentIntent = PendingIntent.getActivity(this,0,
new Intent(this,LocalServiceActivities.Controller.class),0);
//设置通知面板中显示的视图的信息。
通知通知=新Notification.Builder(this)
.setSmallIcon(R.drawable.stat_sample)//状态图标
.setTicker(text)//状态文本
.setWhen(System.currentTimeMillis())//时间戳
.setContentTitle(getText(R.string.local_service_label))//条目的标签
.setContentText(text)//条目的内容
.setContentIntent(contentIntent)//单击条目时发送的意图
。建立();
//发送通知
mNM.notify(通知,通知);
}
}
完成后,现在可以编写直接访问正在运行的服务的客户端代码,例如:
/ **
*绑定和解除绑定到本地服务的示例。
*绑定到,接收一个可以通过它与服务进行通信的对象。
*
*请注意,这是作为内部类实现的,只保留样本
* 全部一起; 通常这段代码会出现在某个单独的类中。
* /
public static class Binding extends Activity {
//除非客户收到了一些,否则不要尝试解除绑定
//有关服务状态的信息。
private boolean mShouldUnbind;
//要调用绑定服务,请首先确保此值
//不是null。
private LocalService mBoundService;
private ServiceConnection mConnection = new ServiceConnection(){
public void onServiceConnected(ComponentName className,IBinder service){
//当与服务建立连接时调用此方法
//建立,为我们提供我们可以使用的服务对象
//与服务交互。因为我们必须明确
//我们知道的服务正在我们自己的流程中运行,我们可以
//将其IBinder强制转换为具体类并直接访问它。
mBoundService =((LocalService.LocalBinder)service).getService();
//告诉用户我们的演示。
Toast.makeText(Binding.this,R.string.local_service_connected,
Toast.LENGTH_SHORT).show();
}
public void onServiceDisconnected(ComponentName className){
//当与服务建立连接时调用此方法
//意外断开连接 - 也就是说,它的进程崩溃了。
//因为它在同一个进程中运行,所以我们永远不应该
//看到这种情况发生
mBoundService = null;
Toast.makeText(Binding.this,R.string.local_service_disconnected,
Toast.LENGTH_SHORT).show();
}
};
void doBindService(){
//尝试与服务建立连接。我们使用了
//显式类名,因为我们需要特定的服务
//我们知道的实现将在我们自己的进程中运行
//(因此不会支持其他组件替换组件
//应用程序)。
if(bindService(new Intent(Binding.this,LocalService.class),
mConnection,Context.BIND_AUTO_CREATE)){
mShouldUnbind = true;
} else {
Log.e(“MY_APP_TAG”,“错误:请求的服务没有”+
“存在,或者不允许此客户端访问它。”);
}
}
void doUnbindService(){
if(mShouldUnbind){
//发布有关服务状态的信息。
unbindService(mConnection);
mShouldUnbind = false;
}
}
@覆盖
protected void onDestroy(){
super.onDestroy();
doUnbindService();
}
远程Messenger服务示例
如果您需要能够编写一个可以在远程进程中与客户端执行复杂通信的服务(除了使用 Context.startService向其发送命令之外),那么您可以使用Messenger该类而不是编写完整的AIDL文件。
此处显示了使用Messenger作为其客户端界面的服务示例。首先是服务本身,绑定时将Messenger发布到内部处理程序:
公共类MessengerService扩展Service {
/ **用于显示和隐藏我们的通知。* /
NotificationManager mNM;
/ **跟踪所有当前注册的客户。* /
ArrayList
/ **保留客户端设置的最后一个值。* /
int mValue = 0;
/ **
*命令服务注册客户端,接收回调
*来自服务。Message的replyTo字段必须是Messenger的Messenger
*应发送回调的客户端。
* /
static final int MSG_REGISTER_CLIENT = 1;
/ **
*命令服务取消注册客户端,停止接收回调
*来自服务。Message的replyTo字段必须是Messenger的Messenger
*客户端,如先前给出的MSG_REGISTER_CLIENT。
* /
static final int MSG_UNREGISTER_CLIENT = 2;
/ **
*用于设置新值的服务命令。这可以发送到
*服务提供新值,并将由服务发送到
*任何具有新价值的注册客户。
* /
static final int MSG_SET_VALUE = 3;
/ **
*来自客户的传入消息的处理程序。
* /
class IncomingHandler扩展Handler {
@覆盖
public void handleMessage(Message msg){
switch(msg.what){
案例MSG_REGISTER_CLIENT:
mClients.add(msg.replyTo);
打破;
case MSG_UNREGISTER_CLIENT:
mClients.remove(msg.replyTo);
打破;
case MSG_SET_VALUE:
mValue = msg.arg1;
for(int i = mClients.size() - 1; i> = 0; i--){
尝试{
mClients.get(ⅰ)。发送(Message.obtain(NULL,
MSG_SET_VALUE,mValue,0));
} catch(RemoteException e){
//客户端死了 从列表中删除它;
//我们将从后到前浏览列表
//所以这在循环内部是安全的。
mClients.remove(ⅰ);
}
}
打破;
默认:
super.handleMessage(MSG);
}
}
}
/ **
*目标我们发布客户端以向IncomingHandler发送消息。
* /
final Messenger mMessenger = new Messenger(new IncomingHandler());
@覆盖
public void onCreate(){
mNM =(NotificationManager)getSystemService(NOTIFICATION_SERVICE);
//显示有关我们的通知。
显示通知();
}
@覆盖
public void onDestroy(){
//取消持久通知。
mNM.cancel(R.string.remote_service_started);
//告诉我们停止的用户
Toast.makeText(this,R.string.remote_service_stopped,Toast.LENGTH_SHORT).show();
}
/ **
*绑定到服务时,我们返回一个接口到我们的信使
*用于向服务发送消息。
* /
@覆盖
public IBinder onBind(Intent intent){
return mMessenger.getBinder();
}
/ **
*在此服务运行时显示通知。
* /
private void showNotification(){
//在此示例中,我们将使用相同的文本作为自动收报机和扩展通知
CharSequence text = getText(R.string.remote_service_started);
// PendingIntent如果用户选择此通知,则启动我们的活动
PendingIntent contentIntent = PendingIntent.getActivity(this,0,
new Intent(this,Controller.class),0);
//设置通知面板中显示的视图的信息。
通知通知=新Notification.Builder(this)
.setSmallIcon(R.drawable.stat_sample)//状态图标
.setTicker(text)//状态文本
.setWhen(System.currentTimeMillis())//时间戳
.setContentTitle(getText(R.string.local_service_label))//条目的标签
.setContentText(text)//条目的内容
.setContentIntent(contentIntent)//单击条目时发送的意图
。建立();
//发送通知
//我们使用字符串id,因为它是唯一的数字。我们稍后用它来取消。
mNM.notify(R.string.remote_service_started,notification);
}
}
如果我们想让这个服务在远程进程中运行(而不是其.apk的标准服务),我们可以android:process在其manifest标签中指定一个:
android:process =“:remote”/>
请注意,此处选择的名称“remote”是任意的,如果您需要其他进程,则可以使用其他名称。':'前缀将名称附加到包的标准进程名称。
完成后,客户端现在可以绑定到服务并向其发送消息。请注意,这允许客户端注册它以接收消息:
/ **
*绑定和解除绑定到远程服务的示例。
*这演示了客户端将实现的服务
*通过aidl接口绑定,与之交互。
*
*请注意,这是作为内部类实现的,只保留样本
* 全部一起; 通常这段代码会出现在某个单独的类中。
* /
public static class Binding extends Activity {
/ ** Messenger用于与服务进行通信。* /
Messenger mService = null;
/ **表示我们是否已在服务上调用绑定的标志。* /
boolean mIsBound;
/ **我们用来显示状态信息的一些文本视图。* /
TextView mCallbackText;
/ **
*来自服务的传入消息的处理程序。
* /
class IncomingHandler扩展Handler {
@覆盖
public void handleMessage(Message msg){
switch(msg.what){
case MessengerService.MSG_SET_VALUE:
mCallbackText.setText(“从服务中接收:”+ msg.arg1);
打破;
默认:
super.handleMessage(MSG);
}
}
}
/ **
*目标我们发布客户端以向IncomingHandler发送消息。
* /
final Messenger mMessenger = new Messenger(new IncomingHandler());
/ **
*用于与服务主界面交互的类。
* /
private ServiceConnection mConnection = new ServiceConnection(){
public void onServiceConnected(ComponentName className,
IBinder服务){
//当与服务建立连接时调用此方法
//建立,为我们提供我们可以使用的服务对象
//与服务交互。我们正在和我们沟通
//通过IDL接口提供服务,以便获得客户端
//来自原始服务对象的表示。
mService = new Messenger(服务);
mCallbackText.setText( “附接”);
//我们希望尽可能长时间监控服务
//连接到它。
尝试{
消息msg = Message.obtain(null,
MessengerService.MSG_REGISTER_CLIENT);
msg.replyTo = mMessenger;
mService.send(MSG);
//给它一些值作为例子。
msg = Message.obtain(null,
MessengerService.MSG_SET_VALUE,this.hashCode(),0);
mService.send(MSG);
} catch(RemoteException e){
//在这种情况下,服务在我们可以做之前就已经崩溃了
//用它做任何事情; 我们可以指望很快
//断开连接(如果可以重新启动,则重新连接)
//所以这里没有必要做任何事情。
}
//作为示例的一部分,告诉用户发生了什么。
Toast.makeText(Binding.this,R.string.remote_service_connected,
Toast.LENGTH_SHORT).show();
}
public void onServiceDisconnected(ComponentName className){
//当与服务建立连接时调用此方法
//意外断开连接 - 也就是说,它的进程崩溃了。
mService = null;
mCallbackText.setText( “断开”。);
//作为示例的一部分,告诉用户发生了什么。
Toast.makeText(Binding.this,R.string.remote_service_disconnected,
Toast.LENGTH_SHORT).show();
}
};
void doBindService(){
//与服务建立连接。我们使用明确的
//类名,因为没有理由让其他人
//应用程序替换我们的组件
bindService(new Intent(Binding.this,
MessengerService.class),mConnection,Context.BIND_AUTO_CREATE);
mIsBound = true;
mCallbackText.setText( “结合”);
}
void doUnbindService(){
if(mIsBound){
//如果我们收到了服务,那么注册了
//它,然后现在是取消注册的时间。
if(mService!= null){
尝试{
消息msg = Message.obtain(null,
MessengerService.MSG_UNREGISTER_CLIENT);
msg.replyTo = mMessenger;
mService.send(MSG);
} catch(RemoteException e){
//如果服务,我们不需要做任何特别的事情
// 已经坠毁。
}
}
//分离我们现有的连接。
unbindService(mConnection);
mIsBound = false;
mCallbackText.setText( “解除绑定。”);
}
}
摘要
常量 |
|
int |
START_CONTINUATION_MASK 通过onStartCommand(Intent, int, int)描述如何终止服务来返回返回的位。 |
int |
START_FLAG_REDELIVERY onStartCommand(Intent, int, int)如果Intent是先前传递的intent的重新传递,则设置此标志,因为该服务先前已返回START_REDELIVER_INTENT但在调用stopSelf(int)该Intent 之前已被杀死。 |
int |
START_FLAG_RETRY onStartCommand(Intent, int, int)如果Intent是重试,则设置此标志,因为原始尝试从未到达或返回 onStartCommand(Intent, int, int)。 |
int |
START_NOT_STICKY 返回的常量onStartCommand(Intent, int, int):如果此服务的进程在启动时被终止(从返回之后 onStartCommand(Intent, int, int)),并且没有新的启动意图要传递给它,那么请将服务从启动状态中取出,并且不要重新创建直到将来显式调用 Context.startService(Intent)。 |
int |
START_REDELIVER_INTENT 返回的常量onStartCommand(Intent, int, int):如果此服务的进程在启动时被终止(在返回之后 onStartCommand(Intent, int, int)),则它将被安排重新启动,并且最后一次传递的Intent将再次通过它重新传递给它 onStartCommand(Intent, int, int)。 |
int |
START_STICKY 返回的常量onStartCommand(Intent, int, int):如果此服务的进程在启动时被终止(在返回之后 onStartCommand(Intent, int, int)),则将其保持在启动状态但不保留此传递的意图。 |
int |
START_STICKY_COMPATIBILITY 返回的常量onStartCommand(Intent, int, int):兼容版本START_STICKY不能保证onStartCommand(Intent, int, int)在被杀死后再次调用。 |
int |
STOP_FOREGROUND_DETACH 标记为stopForeground(int):如果设置,先前提供的通知startForeground(int, Notification)将与服务分离。 |
int |
STOP_FOREGROUND_REMOVE 标记为stopForeground(int):如果设置,startForeground(int, Notification)将删除先前提供的通知。 |
继承的常量 |
|
从课堂上 android.content.Context |
|
从界面 android.content.ComponentCallbacks2 |
公共建设者 |
|
Service() |
|
公共方法 |
|
final Application |
getApplication() 返回拥有此服务的应用程序。 |
abstract IBinder |
onBind(Intent intent) 将通信通道返回给服务。 |
void |
onConfigurationChanged(Configuration newConfig) 当组件运行时,设备配置发生变化时由系统调用。 |
void |
onCreate() 首次创建服务时由系统调用。 |
void |
onDestroy() 由系统调用以通知服务它已不再使用且正在被删除。 |
void |
onLowMemory() 当整个系统内存不足时调用此方法,并且主动运行的进程应调整其内存使用量。 |
void |
onRebind(Intent intent) 在新客户端连接到服务之后调用,之前已通知所有客户端已断开连接 onUnbind(Intent)。 |
void |
onStart(Intent intent, int startId) 此方法在API级别5中已弃用。请onStartCommand(Intent, int, int)改为实施。 |
int |
onStartCommand(Intent intent, int flags, int startId) 每次客户端通过调用显式启动服务时,系统调用 Context.startService(Intent),提供它提供的参数和表示启动请求的唯一整数标记。 |
void |
onTaskRemoved(Intent rootIntent) 如果服务当前正在运行且用户已删除来自服务应用程序的任务,则会调用此方法。 |
void |
onTrimMemory(int level) 当操作系统确定是进程从其进程中删除不需要的内存的好时机时调用。 |
boolean |
onUnbind(Intent intent) 当所有客户端与服务发布的特定接口断开连接时调用。 |
final void |
startForeground(int id, Notification notification) 如果您的服务已启动(正在运行Context.startService(Intent)),则还要使此服务在前台运行,并在此状态下提供正在向用户显示的持续通知。 |
final void |
stopForeground(int flags) 从前台状态中删除此服务,如果需要更多内存,则允许它被杀死。 |
final void |
stopForeground(boolean removeNotification) 同义词stopForeground(int)。 |
final void |
stopSelf() 如果先前已启动,请停止该服务。 |
final void |
stopSelf(int startId) 旧版本stopSelfResult(int)不会返回结果。 |
final boolean |
stopSelfResult(int startId) 如果最近启动的时间是startId,请停止服务 。 |
受保护的方法 |
|
void |
dump(FileDescriptor fd, PrintWriter writer, String[] args) 将服务的状态打印到给定的流中。 |
继承方法 |
|
从课堂上 android.content.ContextWrapper |
|
从课堂上 android.content.Context |
|
从课堂上 java.lang.Object |
|
从界面 android.content.ComponentCallbacks2 |
|
从界面 android.content.ComponentCallbacks |
常量
START_CONTINUATION_MASK
在API级别5中添加
public static final int START_CONTINUATION_MASK
通过onStartCommand(Intent, int, int)描述如何终止服务来返回返回的位。五月是START_STICKY,START_NOT_STICKY,START_REDELIVER_INTENT,或START_STICKY_COMPATIBILITY。
常数值:15(0x0000000f)
START_FLAG_REDELIVERY
在API级别5中添加
public static final int START_FLAG_REDELIVERY
onStartCommand(Intent, int, int)如果Intent是先前传递的intent的重新传递,则设置此标志,因为该服务先前已返回START_REDELIVER_INTENT但在调用stopSelf(int)该Intent 之前已被杀死。
常数值:1(0x00000001)
START_FLAG_RETRY
在API级别5中添加
public static final int START_FLAG_RETRY
onStartCommand(Intent, int, int)如果Intent是重试,则设置此标志,因为原始尝试从未到达或返回onStartCommand(Intent, int, int)。
常数值:2(0x00000002)
START_NOT_STICKY
在API级别5中添加
public static final int START_NOT_STICKY
返回的常量onStartCommand(Intent, int, int):如果此服务的进程在启动时被终止(从返回之后onStartCommand(Intent, int, int)),并且没有新的启动意图要传递给它,那么请将服务从启动状态中取出,并且不要重新创建直到将来显式调用 Context.startService(Intent)。该服务不会接收onStartCommand(Intent, int, int) 带有null Intent 的调用,因为如果没有待传递的Intent,它将不会重新启动。
这种模式对于想要在启动时做一些工作的事情是有意义的,但是在内存压力下可以停止,并且稍后会再次明确地开始做更多的工作。这种服务的一个例子是轮询来自服务器的数据:它可以通过让警报启动其服务来安排警报每N分钟轮询一次。当onStartCommand(Intent, int, int)从警报中调用它时,它会在N分钟后安排新的警报,并生成一个线程来进行网络连接。如果在执行该检查时其进程被终止,则在警报响起之前不会重新启动该服务。
常数值:2(0x00000002)
START_REDELIVER_INTENT
在API级别5中添加
public static final int START_REDELIVER_INTENT
返回的常量onStartCommand(Intent, int, int):如果此服务的进程在启动时被终止(在返回之后onStartCommand(Intent, int, int)),则它将被安排重新启动,并且最后一次传递的Intent将再次通过它重新传递给它 onStartCommand(Intent, int, int)。此Intent将保持计划重新发送,直到stopSelf(int)提供了启动ID 的服务调用onStartCommand(Intent, int, int)。该服务不会接收onStartCommand(Intent, int, int) 带有null Intent 的调用,因为只有在未完成处理发送给它的所有Intent时才会重新启动它(并且任何此类挂起事件将在重新启动时传递)。
常数值:3(0x00000003)
START_STICKY
在API级别5中添加
public static final int START_STICKY
返回的常量onStartCommand(Intent, int, int):如果此服务的进程在启动时被终止(在返回之后onStartCommand(Intent, int, int)),则将其保持在启动状态但不保留此传递的意图。稍后系统将尝试重新创建服务。因为它处于启动状态,所以它将保证onStartCommand(Intent, int, int)在创建新服务实例后调用; 如果没有任何挂起的启动命令要传递给服务,它将使用空的intent对象调用,因此您必须注意检查这一点。
此模式适用于将在任意时间段内显式启动和停止运行的事物,例如执行背景音乐播放的服务。
常数值:1(0x00000001)
START_STICKY_COMPATIBILITY
在API级别5中添加
public static final int START_STICKY_COMPATIBILITY
返回的常量onStartCommand(Intent, int, int):兼容版本START_STICKY不能保证 onStartCommand(Intent, int, int)在被杀死后再次调用。
常数值:0(0x00000000)
STOP_FOREGROUND_DETACH
在API级别24中添加
public static final int STOP_FOREGROUND_DETACH
标记为stopForeground(int):如果设置,先前提供的通知startForeground(int, Notification)将与服务分离。才有意义,当STOP_FOREGROUND_REMOVE是没有设置-在这种情况下,通知将保持显示,但是从服务中完全分离,因此不再改变,除非通过直接调用通知管理器。
常数值:2(0x00000002)
STOP_FOREGROUND_REMOVE
在API级别24中添加
public static final int STOP_FOREGROUND_REMOVE
标记为stopForeground(int):如果设置,startForeground(int, Notification)将删除先前提供的通知。否则它将一直保留到稍后的呼叫(去除startForeground(int, Notification)或 stopForeground(int)删除它,或者服务被销毁)。
常数值:1(0x00000001)
公共建设者
服务
在API级别1中添加
公共服务 ()
公共方法
getApplication
在API级别1中添加
public final 应用程序 getApplication()
返回拥有此服务的应用程序。
返回 |
|
Application |
onBind
在API级别1中添加
公共抽象IBinder onBind(意图意图)
将通信通道返回给服务。如果客户端无法绑定到服务,则可能返回null。返回 IBinder通常用于使用aidl描述的复杂接口。
请注意,与其他应用程序组件不同,此处返回的IBinder接口的调用可能不会发生在进程的主线程上。有关主线程的更多信息可以在进程和线程中找到 。
参数 |
|
intent |
Intent:用于绑定到此服务的Intent,如给定的。请注意,此处不会显示Intent中包含的任何额外内容。Context.bindService |
返回 |
|
IBinder |
返回IBinder,客户可通过该IBinder呼叫该服务。 这个值可能是null。 |
onConfigurationChanged
在API级别1中添加
public void onConfigurationChanged(Configuration newConfig)
当组件运行时,设备配置发生变化时由系统调用。请注意,与活动不同,其他组件在配置更改时永远不会重新启动:它们必须始终处理更改的结果,例如通过重新检索资源。
在调用此函数时,您的Resources对象将更新为返回与新配置匹配的资源值。
有关更多信息,请阅读处理运行时更改。
参数 |
|
newConfig |
Configuration:新设备配置。 |
的onCreate
在API级别1中添加
public void onCreate()
首次创建服务时由系统调用。不要直接调用此方法。
的onDestroy
在API级别1中添加
public void onDestroy()
由系统调用以通知服务它已不再使用且正在被删除。该服务应该清理它所拥有的任何资源(线程,注册接收器等)。返回后,将不再有对此Service对象的调用,它实际上已经死了。不要直接调用此方法。
onLowMemory
在API级别1中添加
public void onLowMemory()
当整个系统内存不足时调用此方法,并且主动运行的进程应调整其内存使用量。虽然没有定义调用它的确切点,但通常会在所有后台进程都被杀死时发生。也就是说,在达到杀死进程托管服务和前台UI之前,我们希望避免被杀死。
您应该实现此方法以释放您可能持有的任何缓存或其他不必要的资源。从此方法返回后,系统将为您执行垃圾回收。
最好,您应该实现ComponentCallbacks2.onTrimMemory(int)从 ComponentCallbacks2根据不同级别的内存需求逐步卸载资源。该API适用于API级别14及更高版本,因此您只应将此onLowMemory()方法用作旧版本的后备版本,可以将其视为ComponentCallbacks2.onTrimMemory(int)与ComponentCallbacks2.TRIM_MEMORY_COMPLETE级别相同。
onRebind
在API级别1中添加
public void onRebind(Intent intent)
在新客户端连接到服务之后调用,之前已通知所有客户端已断开连接 onUnbind(Intent)。只有在onUnbind(Intent)重写的实现被返回true 时才会调用此方法。
参数 |
|
intent |
Intent:用于绑定到此服务的Intent,如给定的。请注意,此处不会显示Intent中包含的任何额外内容。 Context.bindService |
在onStart
在API级别1中添加
public void onStart(Intent intent,
int startId)
此方法在API级别5中已弃用。请改为
实施onStartCommand(Intent, int, int)。
参数 |
|
intent |
Intent |
startId |
int |
onStartCommand
在API级别5中添加
public int onStartCommand(Intent intent,
int标志,
int startId)
每次客户端通过调用显式启动服务时,系统调用 Context.startService(Intent),提供它提供的参数和表示启动请求的唯一整数标记。不要直接调用此方法。
为了向后兼容,默认实现调用 onStart(Intent, int)并返回START_STICKY 或START_STICKY_COMPATIBILITY。
请注意,系统会在服务的主线程上调用此方法。服务的主线程是同一个线程,在该线程中,对于在同一进程中运行的活动进行UI操作。您应该始终避免停止主线程的事件循环。在进行长时间运行操作,网络调用或重磁盘I / O时,您应该启动新线程或使用AsyncTask。
参数 |
|
intent |
Intent:给出的意图提供给。如果服务在其进程消失后重新启动,则它可能为null,并且之前已返回除了之外的任何内容。Context.startService(Intent)START_STICKY_COMPATIBILITY |
flags |
int:有关此启动请求的其他数据。 值可以是0或的组合START_FLAG_REDELIVERY或START_FLAG_RETRY。 |
startId |
int:表示此特定启动请求的唯一整数。使用。stopSelfResult(int) |
返回 |
|
int |
返回值指示系统应该为服务的当前启动状态使用的语义。它可能是与START_CONTINUATION_MASK位相关的常数之一。 值是START_STICKY_COMPATIBILITY,START_STICKY,START_NOT_STICKY或START_REDELIVER_INTENT。 |
也可以看看:
onTaskRemoved
在API级别14中添加
public void onTaskRemoved(Intent rootIntent)
如果服务当前正在运行且用户已删除来自服务应用程序的任务,则会调用此方法。如果你已经设置,ServiceInfo.FLAG_STOP_WITH_TASK 那么你将不会收到此回调; 相反,该服务将被停止。
参数 |
|
rootIntent |
Intent:用于启动正在删除的任务的原始根Intent。 |
onTrimMemory
在API级别14中添加
public void onTrimMemory(int level)
当操作系统确定是进程从其进程中删除不需要的内存的好时机时调用。例如,当它进入后台并且没有足够的内存来保持尽可能多的后台进程运行时,就会发生这种情况。您永远不应该与级别的确切值进行比较,因为可能会添加新的中间值 - 您通常希望比较该值是否大于或等于您感兴趣的级别。
要在任何时刻检索过程当前修剪级别,您可以使用ActivityManager.getMyMemoryState(RunningAppProcessInfo)。
参数 |
|
level |
int:修剪的上下文,给出了应用程序可能要执行的修剪量的提示。 |
onUnbind
在API级别1中添加
public boolean onUnbind(Intent intent)
当所有客户端与服务发布的特定接口断开连接时调用。默认实现不执行任何操作并返回false。
参数 |
|
intent |
Intent:用于绑定到此服务的Intent,如给定的。请注意,此处不会显示Intent中包含的任何额外内容。Context.bindService |
返回 |
|
boolean |
如果您希望稍后在新客户端绑定服务时调用该服务的方法,则返回true 。 onRebind(Intent) |
startForeground
在API级别5中添加
public final void startForeground(int id,
Notification notification)
如果您的服务已启动(正在运行Context.startService(Intent)),则还要使此服务在前台运行,并在此状态下提供正在向用户显示的持续通知。默认情况下,启动服务是后台服务,这意味着它们的进程不会被赋予前台CPU调度(除非该进程中的其他内容是前台),并且,如果系统需要终止它们以回收更多内存(例如显示大页面)在网络浏览器中),他们可以在没有太多伤害的情况下被杀死。您可以使用 startForeground(int, Notification),如果杀死你的服务将是破坏性的用户,例如,如果你的服务执行后台音乐播放,所以如果他们的音乐停止播放,用户会注意到。
请注意,调用该方法并没有把服务启动状态本身,尽管名字听起来像它。您必须始终ContextWrapper.startService(Intent)先打电话 告诉系统它应该保持服务运行,然后使用此方法告诉它保持运行更加困难。
针对API Build.VERSION_CODES.P或更高版本的应用必须请求权限Manifest.permission.FOREGROUND_SERVICE才能使用此API。
参数 |
|
id |
int:此通知的标识符 ; 一定不能是0。NotificationManager.notify(int, Notification) |
notification |
Notification:要显示的通知。 |
也可以看看:
stopForeground
在API级别24中添加
public final void stopForeground(int flags)
从前台状态中删除此服务,如果需要更多内存,则允许它被杀死。这不会阻止服务运行(对于您使用stopSelf()或相关的方法),只是将其从前台状态中取出。
参数 |
|
flags |
int:其他行为选项。 值可以是0或的组合STOP_FOREGROUND_REMOVE或STOP_FOREGROUND_DETACH。 |
也可以看看:
stopForeground
在API级别5中添加
public final void stopForeground(boolean removeNotification)
同义词stopForeground(int)。
参数 |
|
removeNotification |
boolean:如果为true,STOP_FOREGROUND_REMOVE将提供该标志。 |
也可以看看:
stopSelf
在API级别1中添加
public final void stopSelf()
如果先前已启动,请停止该服务。这与调用Context.stopService(Intent)此特定服务相同。
也可以看看:
stopSelf
在API级别1中添加
public final void stopSelf(int startId)
旧版本stopSelfResult(int)不会返回结果。
参数 |
|
startId |
int |
也可以看看:
stopSelfResult
在API级别1中添加
public final boolean stopSelfResult(int startId)
如果最近启动的时间是startId,请停止服务 。这与调用Context.stopService(Intent)此特定服务相同,但如果有来自您尚未见过的客户端的启动请求,则允许您安全地避免停止onStart(Intent, int)。
关于调用此函数的命令要小心。。如果在为之前收到的ID调用之前使用最近收到的ID调用此函数,则无论如何都会立即停止该服务。如果您最终可能无序处理ID(例如通过在不同的线程上调度它们),那么您有责任按照收到它们的顺序停止它们。
参数 |
|
startId |
int:收到的最新启动标识符。onStart(Intent, int) |
返回 |
|
boolean |
如果startId与上一个启动请求匹配并且服务将停止,则返回true,否则返回false。 |
也可以看看:
受保护的方法
倾倒
在API级别1中添加
protected void dump(FileDescriptor fd,
PrintWriter writer,
String [] args)
将服务的状态打印到给定的流中。如果您运行“adb shell dumpsys activity service
参数 |
|
fd |
FileDescriptor:转储发送到的原始文件描述符。 |
writer |
PrintWriter:您应该将状态转储到的PrintWriter。返回后,这将暂停给您。 |
args |
String:转储请求的其他参数。 |