写点什么

HarmonyOS-Service&Android-Service,android 开发零基础教学

用户头像
Android架构
关注
发布于: 刚刚


Service Ability 和 Page Ability 是根据功能划分,HarmonyOS 中并没有单独为两者提供父类,两者都是 Ability 的一种,虽 Ability 实现了 Context,但是 context 是以接口定义的:


public interface Context {int CONTEXT_IGNORE_SECURITY = 2;...}


这一点与 Android 有很大不同,Android 中 Context 是抽象类:


public abstract class Context {/** @hide */@IntDef(flag = true, prefix = { "MODE_" }, value = {MODE_PRIVATE,...})...}


也就是说 HarmonyOS 中服务和界面其实是一体,而 Android 中服务与界面是分开的。 纵观 HarmonyOS 目前开放的应用开发代码,使用接口的地方明显要比 Android 多,这样代码会很轻量、方便、灵活。从上图中可以看出,相比 Android,HarmonyOS Ability 只有一个父类 AbilityContext(Context 是接口),层级只有一层,虽够简洁,但是其所支持的 Api 目前比较有限,甚至有些单一,不利于开发者开发。而 Android 是层级较多,代码执行效率相对比较慢,虽看起来代码嵌套太多,甚至有些冗余,但提供 Api 丰富,方便开发者开发。 HarmonyOS 中 Context 不管是何种 Context,可以通用。Android 中 Context 分为 Activity,Service 和 Application,所以有些时候使用 context 或 this 的会报错,主要是 context 类型不一致导致的。

生命周期

不管是 HarmonyOS 还 Android,两者 Service 的生命周期基本相同,具体如下:



根据调用方法的不同,两种 Service 生命周期都可以细分为普通服务和连接服务(HarmonyOS 中称为连接服务,Android 中则为绑定服务)。


  • 普通服务:一般后台服务,比如地图定位、文件下载等。

  • 连接服务:Service 在其他 Ability 调用 connectAbility()时创建,客户端可通过调用 disconnectAbility?()断开连接。多个客户端可以绑定到相同 Service,而且当所有绑定全部取消后,系统即会销毁该 Service。


根据使用场景不同,HarmonyOS Service 和 Android Service 都分为后台服务,前台服务,绑定(连接)服务。


  • 后台服务:后台服务执行用户不会直接注意到的操作。一般情况下,Service 都是在后台运行的,后台 Service 的优先级都是比较低的,当资源不足时,系统有可能回收正在运行的后台 Service。

  • 前台服务:前台服务执行一些用户能注意到的操作。在一些场景下(如播放音乐),用户希望应用能够一直保持运行,此时就需要使用前台 Service。前台 Service 会始终保持正在运行的图标在系统状态栏显示。

  • 绑定服务:绑定服务是客户端-服务器接口中的服务器。借助绑定服务,组件(例如 Activity)可以绑定到服务、发送请求、接收响应,以及执行进程间通信 (IPC)。绑定服务通常只在为其他应用组件提供服务时处于活动状态,不会无限期在后台运行。


不管是哪一种服务,服务既可以单独存在,也可以共存,即可以同时有前台服务和绑定服务,或者其他组合方式存在。 两种 Service 不仅生命周期基本一致,具体的周期状态也基本一致,如下表所示:



其中 HarmonyOS:


public class HarmonyOSService extends Ability {@Overridepublic void onStart(Intent intent) {super.onStart(intent);}


@Overridepublic void onCommand(Intent intent, boolean restart, int startId) {super.onCommand(intent, restart, startId);}


@Overridepublic IRemoteObject onConnect(Intent intent) {super.onConnect(intent);return null;}


@Overridepublic void onDisconnect(Intent intent) {super.onDisconnect(intent);}


@Overridepublic void onStop() {super.onStop();}}


Android:


public class AndroidService extends Service {@Overridepublic void onCreate() {super.onCreate();}


@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {return super.onStartCommand(intent, flags, startId);}


@Nullable@Overridepublic IBinder onBind(Intent intent) {return null;}


@Overridepublic boolean onUnbind(Intent intent) {return super.onUnbind(intent);}


@Overridepublic void onDestroy() {super.onDestroy();}}


初始化:


  • onStart():HarmonyOS 创建 Service 的时候调用,用于 Service 的初始化,在 Service 的整个生命周期只会调用一次。

  • onCreate():Android 首次创建服务时,系统会(在调用 onStartCommand() 或 onBind() 之前)调用此方法来执行一次性设置程序。如果服务已在运行,则不会调用此方法。


启动:


  • onCommand():HarmonyOS 在 Service 创建完成之后调用,该方法在客户端每次启动该 Service 时都会调用,用户可以在该方法中做一些调用统计、初始化类的操作。

  • onStartCommand() :Android 中当另一个组件(如 Activity)请求启动服务时,系统会通过调用 startService() 来调用此方法。执行此方法时,服务即会启动并可在后台无限期运行。实现此方法,则在服务工作完成后,则通过调用 stopSelf() 或 stopService() 来停止服务。(如果只想绑定,则无需实现此方法。)


绑定:


  • onConnect():HarmonyOS 中在 Ability 和 Service 连接时调用,该方法返回 IRemoteObject 对象,用户可以在该回调函数中生成对应 Service 的 IPC 通信通道,以便 Ability 与 Service 交互。Ability 可以多次连接同一个 Service,系统会缓存该 Service 的 IPC 通信对象,只有第一个客户端连接 Service 时,系统才会调用 Service 的 onConnect 方法来生成 IRemoteObject 对象,而后系统会将同一个 RemoteObject 对象传递至其他连接同一个 Service 的所有客户端,而无需再次调用 onConnect 方法。

  • onBind():Android 中当另一个组件想要与服务绑定(例如执行 RPC)时,系统会通过调用 bindService() 来调用此方法。在此方法的实现中,开发者必须通过返回 IBinder 提供一个接口,以供客户端用来与服务进行通信。请务必实现此方法;但是,如果开发者并不希望允许绑定,则应返回 null。


解绑:


  • onDisconnect() :HarmonyOS 中在 Ability 与绑定的 Service 断开连接时调用。

  • onUnbind():Android 中客户端可通过调用 unbindService() 关闭连接。多个客户端可以绑定到相同服务,而且当所有绑定全部取消后,系统即会销毁该服务。(服务不必自行停止运行。)


销毁:


  • onStop():HarmonyOS 中在 Service 销毁时调用。Service 应通过实现此方法来清理任何资源,如关闭线程、注册的侦听器等。

  • onDestroy():Android 中当不再使用服务且准备将其销毁时,系统会调用此方法。服务应通过实现此方法来清理任何资源,如线程、注册的侦听器、接收器等。这是服务接收的最后一个调用。 总而言之,不管是 HarmonyOS 还是 Android,有关 Service 的生命周期及相关方法调用及方法作用基本一致。

使用

创建 Service

HarmonyOS:创建 Ability 的子类,实现 Service 相关的生命周期方法。Service 也是一种 Ability,用户可以重写这些方法来添加自己的处理。


public class HarmonyOSService extends Ability {@Overridepublic void onStart(Intent intent) {super.onStart(intent);}...}


Android:创建 Service 的子类(或使用它的一个现有子类)。开发者需要重写一些回调方法,从而处理服务生命周期的某些关键方面,并提供一种机制将组件绑定到服务。


public class AndroidService extends Service {@Overridepublic void onCreate() {super.onCreate();}...}


或者创建 IntentService(Service 子类)子类,串行执行所有启动服务请求。


public class AndroidIntentService extends IntentService {


public AndroidIntentService() {super("AndroidIntentService");}@Overrideprotected void onHandleIntent(Intent intent) {try {Thread.sleep(5000);} catch (InterruptedException e) {// Restore interrupt status.Thread.currentThread().interrupt();}}}

注册

HarmonyOS:Service 需要在应用配置文件中进行注册,注册类型 type 需要设置为 service。


{"module": {"abilities": [


{


"name": ".ServiceAbility","type": "service","visible": true...}]...}...}


Android:开发者必须在应用的清单文件中声明所有服务。如要声明服务,需要添加 元素作为 元素的子元素,name 属性是唯一必需的属性。


<manifest ... >...<application ... ><service android:name=".AndroidService" />...</application></manifest>

启动服务

HarmonyOS

HarmonyOS 中 Ability 为开发者提供了 startAbility()方法来启动另外一个 Ability。因为 Service 也是 Ability 的一种,开发者同样可以通过将 Intent 传递给该方法来启动 Service。不仅支持启动本地 Service,还支持启动远程 Service。其中启动本地服务如下:


Intent intent = new Intent();Operation operation = new Intent.OperationBuilder().withDeviceId("").withBundleName("com.huawei.hiworld.himusic").withAbilityName("com.huawei.hiworld.himusic.entry.ServiceAbility").build();intent.setOperation(operation);startAbility(intent);


参数说明:


  • DeviceId:表示设备 ID。如果是本地设备,则可以直接留空;如果是远程设备,可以通过 ohos.distributedschedule.interwork.DeviceManager 提供的 getDeviceList 获取设备列表。

  • BundleName:表示包名称。

  • AbilityName:表示待启动的 Ability 名称。 启动远程服务如下:


Operation operation = new Intent.OperationBuilder().withDeviceId("deviceId").withBundleName("com.huawei.hiworld.himusic").withAbilityName("com.huawei.hiworld.himusic.entry.ServiceAbility").withFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE) // 设置支持分布式调度系统多设备启动的标识.build();Intent intent = new Intent();intent.setOperation(operation);startAbility(intent);


Ability 将通过 startAbility() 方法来启动 Service。 如果 Service 尚未运行,则系统会先调用 onStart()来初始化 Service,再回调 Service 的 onCommand()方法来启动 Service。 如果 Service 正在运行,则系统会直接回调 Service 的 onCommand()方法来启动 Servi


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


ce。

Android

开发者可以通过将 Intent 传递给 startService() 或 startForegroundService(),从 Activity 或其他应用组件启动服务。Android 系统会调用服务的 onStartCommand() 方法,并向其传递 Intent,从而指定要启动的服务。如果应用面向 API 级别 26 或更高版本,除非应用本身在前台运行,否则系统不会对使用或创建后台服务施加限制。如果应用需要创建前台服务,则其应调用 startForegroundService()。此方法会创建后台服务,但它会向系统发出信号,表明服务会将自行提升至前台。创建服务后,该服务必须在五秒内调用自己的 startForeground() 方法。


Intent intent = new Intent(this, AndroidService.class);startService(intent);


startService() 方法会立即返回,并且 Android 系统会调用服务的 onStartCommand() 方法。如果服务尚未运行,则系统首先会调用 onCreate(),然后调用 onStartCommand()。 如果服务亦未提供绑定,则应用组件与服务间的唯一通信模式便是使用 startService() 传递的 Intent。但是,如果开发者希望服务返回结果,则启动服务的客户端可以为广播(通过 getBroadcast() 获得)创建一个 PendingIntent,并将其传递给启动服务的 Intent 中的服务。然后,服务便可使用广播传递结果。 多个服务启动请求会导致多次对服务的 onStartCommand() 进行相应的调用。但是,如要停止服务,只需一个服务停止请求(使用 stopSelf() 或 stopService())即可。

启动前台服务(可选)

HarmonyOS

开发者只需在 Service 创建的方法里,调用 keepBackgroundRunning()将 Service 与通知绑定。调用 keepBackgroundRunning()方法前需要在配置文件中声明。ohos.permission.KEEP_BACKGROUND_RUNNING 权限,该权限是 normal 级别,同时还需要在配置文件中添加对应的 backgroundModes 参数。在 onStop()方法中调用 cancelBackgroundRunning?()方法可停止前台 Service。使用前台 Service 的 onStart()代码示例如下:


// 创建通知,其中 1005 为 notificationIdNotificationRequest request = new NotificationRequest(1005);NotificationRequest.NotificationNormalContent content = new NotificationRequest.NotificationNormalContent();content.setTitle("title").setText("text");NotificationRequest.NotificationContent notificationContent = new NotificationRequest.NotificationContent(content);request.setContent(notificationContent);


// 绑定通知,1005 为创建通知时传入的 notificationIdkeepBackgroundRunning(1005, request);


在配置文件中配置如下:


{


"name": ".ServiceAbility","type": "service","visible": true,"backgroundModes": ["dataTransfer","location"]}

Android

开发者创建前台服务,需要调用 startForeground(),这个方法同样需要 notificationId 和 Notification 实例:


Intent notificationIntent = new Intent(this, AndroidActivity.class);PendingIntent pendingIntent =PendingIntent.getActivity(this, 0, notificationIntent, 0);


Notification notification =new Notification.Builder(this, CHANNEL_DEFAULT_IMPORTANCE).setContentTitle(getText(R.string.notification_title)).setContentText(getText(R.string.notification_message)).setSmallIcon(R.drawable.icon).setContentIntent(pendingIntent).setTicker(getText(R.string.ticker_text)).build();startForeground(ONGOING_NOTIFICATION_ID, notification);


注意:Notification ID 不能为 0,同时在 Android 9 (API level 28) 获取更高版本中前台服务需要申明:FOREGROUND_SERVICE 权限:


<manifest xmlns:android="http://schemas.android.com/apk/res/android" ...><uses-permission android:name="android.permission.FOREGROUND_SERVICE"/><application ...>...</application></manifest>


如果应用目标 level 高于 Android 10 (API level 29) 在清单文件中还要申明相关前台服务类型:


<manifest>...<service ... android:foregroundServiceType="location|camera" /></manifest>


代码中也要申明:


Notification notification = ...;Service.startForeground(notification,FOREGROUND_SERVICE_TYPE_LOCATION | FOREGROUND_SERVICE_TYPE_CAMERA);

绑定服务(可选)

HarmonyOS
用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
HarmonyOS-Service&Android-Service,android开发零基础教学