android进阶 -service 转自官方(工具翻译)

 

API级别1添加

public abstract class Service 
extends ContextWrapper implements ComponentCallbacks2

java.lang.Object继承

   

android.content.Context

 

   

android.content.ContextWrapper

 

 

   

android.app.Service

已知的直接子

AbstractInputMethodServiceAccessibilityServiceAutofillServiceCallScreeningServiceCameraPrewarmServiceCarrierMessagingServiceCarrierServiceChooserTargetServiceConditionProviderServiceConnectionServiceDeviceAdminService以及其他20个。

 

已知的接子

InputMethodService

 


服务是一种应用程序组件,表示应用程序希望在不与用户交互的情况下执行较长时间运行的操作,或者为其他应用程序提供要使用的功能。每个服务类必须<service> 在其包中具有相应的 声明AndroidManifest.xml。可以使用Context.startService() 启动服务 Context.bindService()

请注意,服务与其他应用程序对象一样,在其托管进程的主线程中运行。这意味着,如果您的服务要进行任何CPU密集型(例如MP3播放)或阻止(例如网络)操作,它应该产生自己的线程来执行该工作。有关此内容的更多信息,请参见 进程和线程。该IntentService班是作为一个标准的实施服务的,有它自己的线程在哪里做它安排其工作。

这里涉及的主题:

  1. 什么是服
  2. 生命周期
  3. 权限
  4. 流程生命周期
  5. 本地服务样
  6. 远程Messenger示例

者指南

有关如何创建服务的详细讨论,请阅读 服务开发人员指南。

什么是服

关于Service类的大多数混淆实际上都围绕着它不是

  • 不是一个独的程。Service对象本身并不意味着它在自己的进程中运行除非另有明,否它将在与其所属的用程序相同的程中运行。
  • 不是一个线程。它本身不是从主线程开始工作的手段(以避免用程序无响应错误)。

因此,服务本身实际上非常简单,提供两个主要特征:

  • 一种用工具来告有关 西,它希望在背景(即使用不直接与用程序交互)做的事情。这对应于要求Context.startService()安排服工作的 ,直到服或其他人明确停止它止。
  • 应用程序的一种工具,可将其某些功能暴露给其他应用程序。这对应于调用 Context.bindService(),它允许对务进接以便与服务进行交互。

当实际创建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()返回时,应完成所有清理(停止线程,取消注册接收器)。

在清单<service> 标签中声明服务时,可以强制执行对服务的全局访问。通过这样做,其他应用程序将需要<uses-permission> 在其自己的清单中声明相应的 元素,以便能够启动,停止或绑定到服务。

截至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系统将尝试保持托管服务的进程。当内存不足并且需要杀死现有进程时,托管服务的进程的优先级将是以下可能性中的较高者:

  • 如果服务当前正在其onCreate(),, onStartCommand()onDestroy()方法中执行代码 ,那么托管进程将是一个前台进程,以确保此代码可以执行而不会被杀死。
  • 如果服务已经启动,则其托管过程被认为不如屏幕上用户当前可见的任何过程重要,但比任何不可见的过程更重要。因为用户通常只能看到一些进程,这意味着除了内存不足之外,不应该杀死该服务。但是,由于用户没有直接了解后台服务,因此在该状态下,它 认为是有效的候选者,您应该为此做好准备。特别是,长期运行的服务将越来越可能被杀死,并且如果它们保持足够长的启动,则可以保证被杀死(并且如果适当的话,重新启动)。
  • 如果有客户端绑定到该服务,那么该服务的托管过程永远不会比最重要的客户端重要。也就是说,如果其客户端之一对用户可见,则认为服务本身是可见的。该方法在客户端的重要性,影响到服务的重要性,可通过调整Context.BIND_ABOVE_CLIENT Context.BIND_ALLOW_OOM_MANAGEMENTContext.BIND_WAIVE_PRIORITYContext.BIND_IMPORTANT,和Context.BIND_ADJUST_WITH_ACTIVITY
  • 启动的服务可以使用startForeground(int, Notification) API将服务置于前台状态,系统认为该服务是用户主动了解的内容,因此在内存不足时不会成为查杀的候选者。(从理论上讲,服务在当前前台应用程序的极端内存压力下被杀死仍然是可能的,但实际上这不应该是一个问题。)

请注意,这意味着您的服务运行的大部分时间,如果系统处于严重的内存压力下,它可能会被系统杀死。如果发生这种情况,系统稍后将尝试重新启动该服务。这样做的一个重要结果是,如果您实现onStartCommand() 计划要异步完成或在另一个线程中完成工作,那么您可能希望让START_FLAG_REDELIVERY系统为您重新提供一个Intent,这样如果您的服务是在处理它时被杀死。

Activity当然,在与服务相同的过程中运行的其他应用程序组件(例如)可以提高整个过程的重要性,而不仅仅是服务本身的重要性。

本地服务样

服务的最常见用途之一是作为与应用程序的其他部分一起运行的辅助组件,与其余组件在同一进程中运行。除非另有明确说明,否则.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 =NotificationManagergetSystemServiceNOTIFICATION_SERVICE;

 

        //显示有关我们的通知。我们在状态栏中放了一个图标。

        显示通知();

    }

 

    @覆盖

    public int onStartCommandIntent intentint flagsint startId{

        Log.i“LocalService”“Received start id”+ startId +“”+ intent;

        返回START_NOT_STICKY;

    }

 

    @覆盖

    public void onDestroy(){

        //取消持久通知。

        mNM.cancelNOTIFICATION;

 

        //告诉我们停止的用户

        Toast.makeTextthisR.string.local_service_stoppedToast.LENGTH_SHORT.show();

    }

 

    @覆盖

    public IBinder onBindIntent intent{

        返回mBinder;

    }

 

    //这是从客户端接收交互的对象。看到

    // RemoteService以获得更完整的示例。

    私人决赛IBinder mBinder = new LocalBinder();

 

    / **

     *在此服务运行时显示通知。

     * /

    private void showNotification(){

        //在此示例中,我们将使用相同的文本作为自动收报机和扩展通知

        CharSequence text = getTextR.string.local_service_started;

 

        // PendingIntent如果用户选择此通知,则启动我们的活动

        PendingIntent contentIntent = PendingIntent.getActivitythis0

                new IntentthisLocalServiceActivities.Controller.class),0;

 

        //设置通知面板中显示的视图的信息。

        通知通知=Notification.Builderthis

                .setSmallIconR.drawable.stat_sample//状态图标

                .setTickertext//状态文本

                .setWhenSystem.currentTimeMillis())//时间戳

                .setContentTitlegetTextR.string.local_service_label))//条目的标签

                .setContentTexttext//条目的内容

                .setContentIntentcontentIntent//单击条目时发送的意图

                。建立();

 

        //发送通知

        mNM.notify(通知,通知);

    }

}

完成后,现在可以编写直接访问正在运行的服务的客户端代码,例如:

/ **

 *绑定和解除绑定到本地服务的示例。

 *绑定到,接收一个可以通过它与服务进行通信的对象。

 *

 *请注意,这是作为内部类实现的,只保留样本

 * 全部一起; 通常这段代码会出现在某个单独的类中。

 * /

public static class Binding extends Activity {

    //除非客户收到了一些,否则不要尝试解除绑定

    //有关服务状态的信息。

    private boolean mShouldUnbind;

 

    //要调用绑定服务,请首先确保此值

    //不是null

    private LocalService mBoundService;

 

    private ServiceConnection mConnection = new ServiceConnection(){

        public void onServiceConnectedComponentName classNameIBinder service{

            //当与服务建立连接时调用此方法

            //建立,为我们提供我们可以使用的服务对象

            //与服务交互。因为我们必须明确

            //我们知道的服务正在我们自己的流程中运行,我们可以

            //将其IBinder强制转换为具体类并直接访问它。

            mBoundService =((LocalService.LocalBinderservice.getService();

 

            //告诉用户我们的演示。

            Toast.makeTextBinding.thisR.string.local_service_connected

                    Toast.LENGTH_SHORT.show();

        }

 

        public void onServiceDisconnectedComponentName className{

            //当与服务建立连接时调用此方法

            //意外断开连接 - 也就是说,它的进程崩溃了。

            //因为它在同一个进程中运行,所以我们永远不应该

            //看到这种情况发生

            mBoundService = null;

            Toast.makeTextBinding.thisR.string.local_service_disconnected

                    Toast.LENGTH_SHORT.show();

        }

    };

 

    void doBindService(){

        //尝试与服务建立连接。我们使用了

        //显式类名,因为我们需要特定的服务

        //我们知道的实现将在我们自己的进程中运行

        //(因此不会支持其他组件替换组件

        //应用程序)。

        ifbindServicenew IntentBinding.thisLocalService.class),

                mConnectionContext.BIND_AUTO_CREATE)){

            mShouldUnbind = true;

        } else {

            Log.e“MY_APP_TAG”错误:请求的服务没有”+

                    “存在,或者不允许此客户端访问它。;

        }

    }

 

    void doUnbindService(){

        ifmShouldUnbind{

            //发布有关服务状态的信息。

            unbindServicemConnection;

            mShouldUnbind = false;

        }

    }

 

    @覆盖

    protected void onDestroy(){

        super.onDestroy();

        doUnbindService();

    }

远程Messenger示例

如果您需要能够编写一个可以在远程进程中与客户端执行复杂通信的服务(除了使用 Context.startService向其发送命令之外),那么您可以使用Messenger该类而不是编写完整的AIDL文件。

此处显示了使用Messenger作为其客户端界面的服务示例。首先是服务本身,绑定时将Messenger发布到内部处理程序:

公共类MessengerService扩展Service {

    / **用于显示和隐藏我们的通知。* /

    NotificationManager mNM;

    / **跟踪所有当前注册的客户。* /

    ArrayList <Messenger> mClients = new ArrayList <Messenger>();

    / **保留客户端设置的最后一个值。* /

    int mValue = 0;

 

    / **

     *命令服务注册客户端,接收回调

     *来自服务。MessagereplyTo字段必须是MessengerMessenger

     *应发送回调的客户端。

     * /

    static final int MSG_REGISTER_CLIENT = 1;

 

    / **

     *命令服务取消注册客户端,停止接收回调

     *来自服务。MessagereplyTo字段必须是MessengerMessenger

     *客户端,如先前给出的MSG_REGISTER_CLIENT

     * /

    static final int MSG_UNREGISTER_CLIENT = 2;

 

    / **

     *用于设置新值的服务命令。这可以发送到

     *服务提供新值,并将由服务发送到

     *任何具有新价值的注册客户。

     * /

    static final int MSG_SET_VALUE = 3;

 

    / **

     *来自客户的传入消息的处理程序。

     * /

    class IncomingHandler扩展Handler {

        @覆盖

        public void handleMessageMessage msg{

            switchmsg.what{

                案例MSG_REGISTER_CLIENT

                    mClients.addmsg.replyTo;

                    打破;

                case MSG_UNREGISTER_CLIENT

                    mClients.removemsg.replyTo;

                    打破;

                case MSG_SET_VALUE

                    mValue = msg.arg1;

                    forint i = mClients.size() -  1; i> = 0; i--{

                        尝试{

                            mClients.get)。发送(Message.obtainNULL

                                    MSG_SET_VALUEmValue0));

                        } catchRemoteException e{

                            //客户端死了 从列表中删除它;

                            //我们将从后到前浏览列表

                            //所以这在循环内部是安全的。

                            mClients.remove;

                        }

                    }

                    打破;

                默认:

                    super.handleMessageMSG;

            }

        }

    }

 

    / **

     *目标我们发布客户端以向IncomingHandler发送消息。

     * /

    final Messenger mMessenger = new Messengernew IncomingHandler());

 

    @覆盖

    public void onCreate(){

        mNM =NotificationManagergetSystemServiceNOTIFICATION_SERVICE;

 

        //显示有关我们的通知。

        显示通知();

    }

 

    @覆盖

    public void onDestroy(){

        //取消持久通知。

        mNM.cancelR.string.remote_service_started;

 

        //告诉我们停止的用户

        Toast.makeTextthisR.string.remote_service_stoppedToast.LENGTH_SHORT.show();

    }

 

    / **

     *绑定到服务时,我们返回一个接口到我们的信使

     *用于向服务发送消息。

     * /

    @覆盖

    public IBinder onBindIntent intent{

        return mMessenger.getBinder();

    }

 

    / **

     *在此服务运行时显示通知。

     * /

    private void showNotification(){

        //在此示例中,我们将使用相同的文本作为自动收报机和扩展通知

        CharSequence text = getTextR.string.remote_service_started;

 

        // PendingIntent如果用户选择此通知,则启动我们的活动

        PendingIntent contentIntent = PendingIntent.getActivitythis0

                new IntentthisController.class),0;

 

        //设置通知面板中显示的视图的信息。

        通知通知=Notification.Builderthis

                .setSmallIconR.drawable.stat_sample//状态图标

                .setTickertext//状态文本

                .setWhenSystem.currentTimeMillis())//时间戳

                .setContentTitlegetTextR.string.local_service_label))//条目的标签

                .setContentTexttext//条目的内容

                .setContentIntentcontentIntent//单击条目时发送的意图

                。建立();

 

        //发送通知

        //我们使用字符串id,因为它是唯一的数字。我们稍后用它来取消。

        mNM.notifyR.string.remote_service_startednotification;

    }

}

如果我们想让这个服务在远程进程中运行(而不是其.apk的标准服务),我们可以android:process在其manifest标签中指定一个:

<service androidname =“app.MessengerService”

        androidprocess =“remote”/>

请注意,此处选择的名称“remote”是任意的,如果您需要其他进程,则可以使用其他名称。''前缀将名称附加到包的标准进程名称。

完成后,客户端现在可以绑定到服务并向其发送消息。请注意,这允许客户端注册它以接收消息:

/ **

 *绑定和解除绑定到远程服务的示例。

 *这演示了客户端将实现的服务

 *通过aidl接口绑定,与之交互。

 *

 *请注意,这是作为内部类实现的,只保留样本

 * 全部一起; 通常这段代码会出现在某个单独的类中。

 * /

public static class Binding extends Activity {

    / ** Messenger用于与服务进行通信。* /

    Messenger mService = null;

    / **表示我们是否已在服务上调用绑定的标志。* /

    boolean mIsBound;

    / **我们用来显示状态信息的一些文本视图。* /

    TextView mCallbackText;

 

    / **

     *来自服务的传入消息的处理程序。

     * /

    class IncomingHandler扩展Handler {

        @覆盖

        public void handleMessageMessage msg{

            switchmsg.what{

                case MessengerService.MSG_SET_VALUE

                    mCallbackText.setText从服务中接收:”+ msg.arg1;

                    打破;

                默认:

                    super.handleMessageMSG;

            }

        }

    }

 

    / **

     *目标我们发布客户端以向IncomingHandler发送消息。

     * /

    final Messenger mMessenger = new Messengernew IncomingHandler());

 

    / **

     *用于与服务主界面交互的类。

     * /

    private ServiceConnection mConnection = new ServiceConnection(){

        public void onServiceConnectedComponentName className

                IBinder服务){

            //当与服务建立连接时调用此方法

            //建立,为我们提供我们可以使用的服务对象

            //与服务交互。我们正在和我们沟通

            //通过IDL接口提供服务,以便获得客户端

            //来自原始服务对象的表示。

            mService = new Messenger(服务);

            mCallbackText.setText附接;

 

            //我们希望尽可能长时间监控服务

            //连接到它。

            尝试{

                消息msg = Message.obtainnull

                        MessengerService.MSG_REGISTER_CLIENT;

                msg.replyTo = mMessenger;

                mService.sendMSG;

 

                //给它一些值作为例子。

                msg = Message.obtainnull

                        MessengerService.MSG_SET_VALUEthis.hashCode(),0;

                mService.sendMSG;

            } catchRemoteException e{

                //在这种情况下,服务在我们可以做之前就已经崩溃了

                //用它做任何事情; 我们可以指望很快

                //断开连接(如果可以重新启动,则重新连接)

                //所以这里没有必要做任何事情。

            }

 

            //作为示例的一部分,告诉用户发生了什么。

            Toast.makeTextBinding.thisR.string.remote_service_connected

                    Toast.LENGTH_SHORT.show();

        }

 

        public void onServiceDisconnectedComponentName className{

            //当与服务建立连接时调用此方法

            //意外断开连接 - 也就是说,它的进程崩溃了。

            mService = null;

            mCallbackText.setText断开。);

 

            //作为示例的一部分,告诉用户发生了什么。

            Toast.makeTextBinding.thisR.string.remote_service_disconnected

                    Toast.LENGTH_SHORT.show();

        }

    };

 

    void doBindService(){

        //与服务建立连接。我们使用明确的

        //类名,因为没有理由让其他人

        //应用程序替换我们的组件

        bindServicenew IntentBinding.this

                MessengerService.class),mConnectionContext.BIND_AUTO_CREATE;

        mIsBound = true;

        mCallbackText.setText结合;

    }

 

    void doUnbindService(){

        ifmIsBound{

            //如果我们收到了服务,那么注册了

            //它,然后现在是取消注册的时间。

            ifmService= null{

                尝试{

                    消息msg = Message.obtainnull

                            MessengerService.MSG_UNREGISTER_CLIENT;

                    msg.replyTo = mMessenger;

                    mService.sendMSG;

                } catchRemoteException e{

                    //如果服务,我们不需要做任何特别的事情

                    // 已经坠毁。

                }

            }

 

            //分离我们现有的连接。

            unbindServicemConnection;

            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_STICKYSTART_NOT_STICKYSTART_REDELIVER_INTENT,或START_STICKY_COMPATIBILITY

常数值:150x0000000f

START_FLAG_REDELIVERY

API级别5添加

public static final int START_FLAG_REDELIVERY

onStartCommand(Intent, int, int)如果Intent是先前传递的intent的重新传递,则设置此标志,因为该服务先前已返回START_REDELIVER_INTENT但在调用stopSelf(int)Intent 之前已被杀死。

常数值:10x00000001

START_FLAG_RETRY

API级别5添加

public static final int START_FLAG_RETRY

onStartCommand(Intent, int, int)如果Intent是重试,则设置此标志,因为原始尝试从未到达或返回onStartCommand(Intent, int, int)

常数值:20x00000002

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分钟后安排新的警报,并生成一个线程来进行网络连接。如果在执行该检查时其进程被终止,则在警报响起之前不会重新启动该服务。

常数值:20x00000002

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时才会重新启动它(并且任何此类挂起事件将在重新启动时传递)。

常数值:30x00000003

START_STICKY

API级别5添加

public static final int START_STICKY

返回的常量onStartCommand(Intent, int, int):如果此服务的进程在启动时被终止(在返回之后onStartCommand(Intent, int, int)),则将其保持在启动状态但不保留此传递的意图。稍后系统将尝试重新创建服务。因为它处于启动状态,所以它将保证onStartCommand(Intent, int, int)在创建新服务实例后调用如果没有任何挂起的启动命令要传递给服务,它将使用空的intent对象调用,因此您必须注意检查这一点。

此模式适用于将在任意时间段内显式启动和停止运行的事物,例如执行背景音乐播放的服务。

常数值:10x00000001

START_STICKY_COMPATIBILITY

API级别5添加

public static final int START_STICKY_COMPATIBILITY

返回的常量onStartCommand(Intent, int, int):兼容版本START_STICKY不能保证 onStartCommand(Intent, int, int)在被杀死后再次调用。

常数值:00x00000000

STOP_FOREGROUND_DETACH

API级别24添加

public static final int STOP_FOREGROUND_DETACH

标记为stopForeground(int):如果设置,先前提供的通知startForeground(int, Notification)将与服务分离。才有意义,当STOP_FOREGROUND_REMOVE没有设置-在这种情况下,通知将保持显示,但是从服务中完全分离,因此不再改变,除非通过直接调用通知管理器。

常数值:20x00000002

STOP_FOREGROUND_REMOVE

API级别24添加

public static final int STOP_FOREGROUND_REMOVE

标记为stopForeground(int):如果设置,startForeground(int, Notification)将删除先前提供的通知。否则它将一直保留到稍后的呼叫(去除startForeground(int, Notification) stopForeground(int)删除它,或者服务被销毁)。

常数值:10x00000001

公共建

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 onConfigurationChangedConfiguration 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 onRebindIntent intent

在新客户端连接到服务之后调用,之前已通知所有客户端已断开连接 onUnbind(Intent)。只有在onUnbind(Intent)重写的实现被返回true 时才会调用此方法。

参数

intent

Intent:用于定到此服Intent,如定的。请注意,此不会Intent中包含的任何外内容。 Context.bindService

onStart

API级别1添加

public void onStartIntent intent

                int startId

此方法在API级别5中已弃用。请改为
实施onStartCommand(Intent, int, int)

参数

intent

Intent

startId

int

onStartCommand

API级别5添加

public int onStartCommandIntent 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_REDELIVERYSTART_FLAG_RETRY

startId

int:表示此特定启动请求的唯一整数。使用。stopSelfResult(int)

返回

int

返回指示系统应该为的当前启使用的语义。它可能是与START_CONTINUATION_MASK位相关的常数之一。

值是START_STICKY_COMPATIBILITYSTART_STICKYSTART_NOT_STICKYSTART_REDELIVER_INTENT

也可以看看:

onTaskRemoved

API级别14添加

public void onTaskRemovedIntent rootIntent

如果服务当前正在运行且用户已删除来自服务应用程序的任务,则会调用此方法。如果你已经设置,ServiceInfo.FLAG_STOP_WITH_TASK 那么你将不会收到此回调相反,该服务将被停止。

参数

rootIntent

Intent:用于启正在除的任的原始根Intent

onTrimMemory

API级别14添加

public void onTrimMemoryint level

当操作系统确定是进程从其进程中删除不需要的内存的好时机时调用。例如,当它进入后台并且没有足够的内存来保持尽可能多的后台进程运行时,就会发生这种情况。您永远不应该与级别的确切值进行比较,因为可能会添加新的中间值 - 您通常希望比较该值是否大于或等于您感兴趣的级别。

要在任何时刻检索过程当前修剪级别,您可以使用ActivityManager.getMyMemoryState(RunningAppProcessInfo)

参数

level

int:修剪的上下文,出了用程序可能要行的修剪量的提示。

onUnbind

API级别1添加

public boolean onUnbindIntent intent

当所有客户端与服务发布的特定接口断开连接时调用。默认实现不执行任何操作并返回false

参数

intent

Intent:用于定到此服Intent,如定的。请注意,此不会Intent中包含的任何外内容。Context.bindService

返回

boolean

如果您希望稍后在新客定服务时调该服务的方法,则返回true  onRebind(Intent)

startForeground

API级别5添加

public final void startForegroundint 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:此通知的标识 ; 一定不能是0NotificationManager.notify(int, Notification)

notification

Notification:要示的通知。

也可以看看:

stopForeground

API级别24添加

public final void stopForegroundint flags

从前台状态中删除此服务,如果需要更多内存,则允许它被杀死。这不会阻止服务运行(对于您使用stopSelf()或相关的方法),只是将其从前台状态中取出。

参数

flags

int:其他行为选项

值可以是0或的组合STOP_FOREGROUND_REMOVESTOP_FOREGROUND_DETACH

也可以看看:

stopForeground

API级别5添加

public final void stopForegroundboolean removeNotification

同义词stopForeground(int)

参数

removeNotification

boolean:如果trueSTOP_FOREGROUND_REMOVE将提供该标志

也可以看看:

stopSelf

API级别1添加

public final void stopSelf()

如果先前已启动,请停止该服务。这与调用Context.stopService(Intent)此特定服务相同。

也可以看看:

stopSelf

API级别1添加

public final void stopSelfint startId

旧版本stopSelfResult(int)不会返回结果。

参数

startId

int

也可以看看:

stopSelfResult

API级别1添加

public final boolean stopSelfResultint startId

如果最近启动的时间是startId,请停止服务 。这与调用Context.stopService(Intent)此特定服务相同,但如果有来自您尚未见过的客户端的启动请求,则允许您安全地避免停止onStart(Intent, int)

关于调用此函数的命令要小心。。如果在为之前收到的ID调用之前使用最近收到的ID调用此函数,则无论如何都会立即停止该服务。如果您最终可能无序处理ID(例如通过在不同的线程上调度它们),那么您有责任按照收到它们的顺序停止它们。

参数

startId

int:收到的最新启动标识符。onStart(Intent, int)

返回

boolean

如果startId与上一个启动请求匹配并且服将停止,返回true,否返回false

也可以看看:

受保的方法

API级别1添加

protected void dumpFileDescriptor fd

                 PrintWriter writer

                 String [] args

将服务的状态打印到给定的流中。如果您运行“adb shell dumpsys activity service <yourservicename>”,则会调用此方法(请注意,要使此命令生效,该服务必须正在运行,并且您必须指定完全限定的服务名称)。这与“dumpsys <servicename>”不同,后者仅适用于命名系统服务,并且IBinder.dump(FileDescriptor, String[])IBinder使用ServiceManager注册的接口上调用该方法。

参数

fd

FileDescriptor转储发送到的原始文件描述符。

writer

PrintWriter:您应该将状态转储到的PrintWriter。返回后,您。

args

String转储请求的其他参数。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值