2024年【Android】在framework中使用AIDL_android aidl 接口引用(5),学生会面试题选择题怎么答

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!


img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上鸿蒙开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化的资料的朋友,可以戳这里获取

17  package android.media;
...
50  /**
51   * {@hide}
52   */
53  interface IAudioService {
...
96      boolean isMasterMute();//我们就只关注这一个方法
...
395  } 

2 实现具体的服务并注册

想先看完 audio 服务实现流程的同学,看完 2.1 节就可以到第 3 章了,后面其他小节只是为了展示 binder 服务的不同写法。

2.1 写法一:直接继承 IAudioService.Stub,内部类继承 SystemServer

定义 AudioService.java 直接继承 IAudioService.Stub,然后在该类里实现章节 1 定义的方法。

/frameworks/base/services/core/java/com/android/server/audio/AudioService.java 

17  package com.android.server.audio;
...
90  import android.media.IAudioService;
187  /**
197   * @hide
198   */
199  public class AudioService extends IAudioService.Stub
200          implements AccessibilityManager.TouchExplorationStateChangeListener,
201              AccessibilityManager.AccessibilityServicesStateChangeListener {
...
4025      public boolean isMasterMute() {
4026          return AudioSystem.getMasterMute();
4027      }
...
10525  } 

服务实现好后,必须要告诉系统,系统才知道有这么一个服务。所以通过 publishBinderService(Context.AUDIO_SERVICE, mService) 将该服务发布出去,第一个参数是我们给该服务起的名字,第二个参数是实现该服务的类实例,也就是 AudioService 对象。

这个 AudioService 是把服务的注册放在了内部类 Lifecycle 中,而 Lifecycle 继承了 SystemService,因为我们要实现的是一个系统服务,必须要继承它才行。

为了不影响阅读的连贯性,此处我们先知道它能注册一个 binder 服务就行了。

785      public static final class Lifecycle extends SystemService {
786          private AudioService mService;
787  
788          public Lifecycle(Context context) {
789              super(context);
790              mService = new AudioService(context);
791          }
792  
793          @Override
794          public void onStart() {
795              publishBinderService(Context.AUDIO_SERVICE, mService);
796          }
797  
798          @Override
799          public void onBootPhase(int phase) {
800              if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
801                  mService.systemReady();
802              }
803          }
804      } 

2.2 写法二:直接继承 SystemService,内部匿名类创建 IBinder 对象

接着,我们看一下 NotificationManagerService 的写法。

(1)NotificationManagerService 是直接继承自 SystemServer;
(2)通过匿名类的方式创建 IBinder 对象,具体实现接口中定义的方法。

334  /** {@hide} */
335  public class NotificationManagerService extends SystemService {
...
2437      public void onStart() {
...
2483          publishBinderService(Context.NOTIFICATION_SERVICE, mService, /* allowIsolated= */ false,
2484                  DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL);
2485          publishLocalService(NotificationManagerInternal.class, mInternalService);
2486      }
2487  
...
   @VisibleForTesting
3176      final IBinder mService = new INotificationManager.Stub() {
...
3180          @Override
3181          public void enqueueTextToast(String pkg, IBinder token, CharSequence text, int duration,
3182                  int displayId, @Nullable ITransientNotificationCallback callback) {
3183              enqueueToast(pkg, token, text, null, duration, displayId, callback);
3184          }
...
11101      }
11102  } 

2.3 写法三:直接继承 .stub,然后用另一个继承自 SystemServer 的类将其发布

这次看一下 AppWidget 相关的 AIDL 服务。

服务的实现类是 AppWidgetServiceImpl.java

17  package com.android.server.appwidget;
...
146  class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBackupProvider,
147          OnCrossProfileWidgetProvidersChangeListener {
...
4940  } 

我们发现这个类直接继承了 IAppWidgetService.Stub,实现了一些具体方法。但然后呢?我们发现,它并没有 IBinder 类型的对象,没有继承 SystemServer,也没有发布 binder 服务。

这是怎么一回事,不慌,我们接着看看和它同包下的 AppWidgetService.java 这个类。

注释就首先吸引了我的目光,“SystemService that publishes an IAppWidgetService”。这个继承自 SystemService,组合了一个 AppWidgetServiceImpl 类型的对象,然后将其发布出去。

27  /**
28   * SystemService that publishes an IAppWidgetService.
29   */
30  public class AppWidgetService extends SystemService {
31      private final AppWidgetServiceImpl mImpl;
32  
33      public AppWidgetService(Context context) {
34          super(context);
35          mImpl = new AppWidgetServiceImpl(context);
36      }
37  
38      @Override
39      public void onStart() {
40          mImpl.onStart();
41          publishBinderService(Context.APPWIDGET_SERVICE, mImpl);
42          AppWidgetBackupBridge.register(mImpl);
43      }
...
62  } 

2.4 服务实现和发布小结

方法的实现一定是在继承了 .Stub 的类中,方法的发布一定是在继承了 SystemServer 的类中,。总共有三种情形:

  • 首先是在同一个 Java 类中的情况
    1. 外部类继承 .Stub,内部类继承 SystemServer,此时 IBinder 对象是外部内的实例。方法的实现在外部类中,发布则在内部类中。这种方法写的比较死,适合整个服务就只实现一个 AIDL 服务的情形。
    2. 外部类继承 SystemServer,内部类继承 .Stub,此时 IBinder 对象就是内部内的实例。方法实现在内部内中,发布在外部内中。这种写法具有可拓展性,因为可以有多个内部类,所以可以同时发布多个 AIDL 服务。
  • 然后是写在两个 Java 类中的情况 此时一个 java 类继承自 SystemServer,它的内部必须要维和一个继承了 .Stub 的类对象(也就是 IBinder 对象),这样才能发布相应服务。另一个 java 类继承 .Stub,只用来实现具体方法。同方法 2 一样,这种方法也具有较高的灵活性,当维护多个 IBinder对象时,也就能发布多个 AIDL 服务。

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

需要这份系统化的资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 25
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值