当前位置: 首页 > 科技观察

Android开发组件Android服务教程

时间:2023-03-14 22:05:23 科技观察

在本文中,我们想讨论Android应用程序开发中的一个重要组件-Android服务。与Activity不同,Service在Android中运行在后台,Service没有接口,其生命周期也不同于Activity。使用Service实现一些后台操作,比如从远程服务器加载网页。我们可以使用Service来实现Android中的多任务处理。AndroidService概述我们知道,如果系统资源紧张,AndroidActivity可以启动、停止、销毁,甚至可能重新创建。并且Service旨在具有更长的生命周期。Service可以从Activity、广播接收器(Broadcastreceiver)或Android中的其他Service启动。必须注意的是,使用Service不会自动创建新线程。所以,如果我们想在一个服务中实现一个简单的逻辑并且不需要很长时间来处理,我们就不必在单独的线程中运行它。但是,如果我们需要实现一个复杂的逻辑,需要很长时间来处理,那么在创建新线程的时候一定要小心,否则可能会因为Service运行在主线程上而导致ANR问题(应用无响应)。Android中Service的主要使用场景如下:实现多任务(multi-task)进程间通信(IPC)第一种情况的典型例子是应用程序需要从远程服务器下载数据。这种情况下,可以使用与用户交互的Activity,在用户使用应用时启动Service,在后台运行完成工作。还有一种场景,当Service完成任务并向用户发送消息时。在第二种情况下,我们希望“共享”一些通用功能,以便不同的应用程序可以重用它们。例如,假设我们有一个发送电子邮件的服务,我们希望在多个应用程序之间共享该服务,这样我们就不必重写相同的代码。在这种情况下,我们可以使用诸如IPC之类的服务来公开一个可以被其他应用程序调用的“远程”接口。服务基础既然我们对服务有了??更多的了解,让我们来创建它。在Android中创建一个Service,我们需要继承Service类。publicclassTestServiceextendsService{@OverridepublicIBinderonBind(Intentarg0){returnnull;}}如您所见,我们只实现了一个名为onBinde的方法。在上面的示例中,我们使用了本地服务,因此该方法返回null。前面提到Service有自己的生命周期,所以我们可以重写一些回调方法来处理它的不同状态:}@OverridepublicintonStartCommand(Intentintent,intflags,intstartId){returnsuper.onStartCommand(intent,flags,startId);}@OverridepublicIBinderonBind(Intentarg0){returnnull;}}***方法onCreate只在Service创建的那一刻被调用。如果服务已经在运行,则不会调用此方法。我们不能直接调用它,它是由系统调用的。OnStartCommand方法是最重要的方法,因为它在我们需要启动服务时被调用。在这个方法中,我们在运行Service的时候传入了Intent,这样我们就可以和Service交换一些信息。在这个方法中,我们实现了自己的逻辑:如果不是什么耗时的操作,我们可以直接在这个方法中执行,否则就创建一个线程。如您所见,此方法需要返回一个整数值。这个整数表示系统应该如何处理这个服务:START_STICKY:使用这个返回值,如果系统杀死我们的服务,它将被重新创建。但是,发送到Service的Intent将不会再次传递。这样,Service就一直在运行。START_NOT_STICKY:如果系统杀死了Service,除非客户端显式调用onStart命令,否则不会重新创建Service。START_REDELIVER_INTENT:类似于START_STICKY。此外,在这种情况下,Intent将被重新交付给服务。OnDestory是Service即将被销毁时系统调用的方法。有了自定义服务类后,您必须在Manifest.xml中声明它,以便我们可以使用它。启动和停止Service我们知道,一个Service会被启动,***会被停止,这样它的任务才能完成。假设我们从一个Activity启动它,我们可以使用Intent将一些信息传递给Service。假设我们的Activity有两个按钮,一个是启动一个是停止Service:name","SurvivingwithAndroid");MainActivity.this.startService(i);}});btnStop.setOnClickListener(newView.OnClickListener(){@OverridepublicvoidonClick(Viewv){Intenti=newIntent(MainActivity.this,TestService.class);MainActivity.this.stopService(i);}});在上面示例代码的第5行,我们创建了一个Intent传递类名来处理我们的服务,我们设置了一些参数,比如名称。然后在第7行,我们启动服务。同样,在第17行我们停止服务。点击开始按钮,得到如下Log:可以注意到onCreate方法被调用了。因为这是我们第一次启动这个Service,如果我们再次点击启动按钮,系统不会调用onCreate方法。当我们点击停止按钮时,系统会销毁该Service。IntentService正如我们之前提到的,Service运行在主线程上。因此,我们在服务中实现逻辑时必须非常小心。考虑如果这个逻辑是一个阻塞操作,或者需要很长时间才能结束,可能会导致ANR问题。在这种情况下,我们希望将逻辑移动到一个单独的线程中。这意味着,在onStartCommand方法中创建一个线程,然后运行它。Service派生的另一个IntentService类可以简化我们的开发。当不需要同时处理多个请求时,这个类很有用。这个类创建一个工作线程来处理不同的请求。执行的操作如下:创建一个单独的线程来处理请求。创建一个请求队列并偶尔传递一个Intent。创建一个默认的onStartCommand实现。在执行完所有请求后终止服务。如果我们想创建一个IntentService,我们需要继承IntentService类而不是Service类:需要实现onHandleIntent方法。这里实现的外部逻辑并不关心操作是否耗时,因为这个方法是在单独的线程中调用的。自动启动服务很多时候我们都希望自动启动我们的服务,比如开机自动启动。我们知道需要一个组件来启动服务。那么,如何让它自动启动呢?我们可以使用广播接收器来启动服务。比如我们想要在手机开机的时候启动它,我们可以先创建一个广播接收器来监听这个事件(boot),然后再启动Service。publicclassBootBroadcasttextendsBroadcastReceiver{@OverridepublicvoidonReceive(Contextctx,Intentintent){ctx.startService(newIntent(ctx,TestService.class));}}在Manifest.xml中声明: