十道经典面试题,插件化框架解读之android系统服务实现原理,Android开发必会技术

}

我们看到程序首先通过sCache这个HasMap中去取,如果不存在就通过getIServiceManager().getService(name)去取,而getIServiceManager()返回的是一个IServiceManager接口,他的具体实现是在ServiceManagerNative#ServiceManagerProxy这个内部类中的,看下源码:
源码路径:xxx/frameworks/base/core/java/android/os/ServiceManagerNative#ServiceManagerProxy

public IBinder getService(String name) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IServiceManager.descriptor);
data.writeString(name);
mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
IBinder binder = reply.readStrongBinder();
reply.recycle();
data.recycle();
return binder;
}

至此,我们就知道了ServiceManager.getService(Context.WIFI_SERVICE)中返回的IBinder是怎么来的了,这里的Parcel大家先不用关心,这个东西只不过是一个容器而已,我们只要知道这里是通过Context.WIFI_SERVICE这个字符串标识获取到了对应的IBinder对象即可,但是直到此处,我们依然没能知道这个IBinder对象到底是什么,这个时候别急,既然是容器,能取出来东西自然也要能存东西,取出来的时候不知道是什么,存进去的时候总该知道吧,继续往下走。。。

4、ServiceManager.addService()

细心的朋友应该已经发现了ServiceManager中还有另一个方法addService(),这个方法就是我们创建服务之后注册到系统去管理的方法,他的调用是在SystemServer.java中,那我们去SystemServer找找看。。。找了半天是否发现没有在SystemServer中找不到哪个是队Wifi服务进行注册的?别急,其实他是通过了WifiService这个东西进行注册的!

private static final String WIFI_SERVICE_CLASS = “com.android.server.wifi.WifiService”;

/**

  • Starts a miscellaneous grab bag of stuff that has yet to be refactored
  • and organized.
    */
    private void startOtherServices() {
    //省略很多。。。
    mSystemServiceManager.startService(WIFI_SERVICE_CLASS);
    //省略很多。。。
    }

这里我们看到 mSystemServiceManager.startService(WIFI_SERVICE_CLASS)怎么一句代码,查看其定义发现mSystemServiceManager是SystemServiceManager:
源码路径: xxx/frameworks/base/services/core/java/com/android/server/SystemServiceManager.java

  • Starts a service by class name.
  • @return The service instance.
    */
    @SuppressWarnings(“unchecked”)
    public SystemService startService(String className) {
    final Class serviceClass;
    try {
    serviceClass = (Class)Class.forName(className);
    } catch (ClassNotFoundException ex) {
    Slog.i(TAG, "Starting " + className);
    throw new RuntimeException("Failed to create service " + className
  • ": service class not found, usually indicates that the caller should "
  • "have called PackageManager.hasSystemFeature() to check whether the "
  • "feature is available on this device before trying to start the "
  • “services that implement it”, ex);
    }
    return startService(serviceClass);
    }

这里我们看到,通过反射的方式返回了WifiService的Class对象,然后作为参数传给了startService(serviceClass):

/**

  • Creates and starts a system service. The class must be a subclass of
  • {@link com.android.server.SystemService}.
  • @param serviceClass A Java class that implements the SystemService interface.
  • @return The service instance, never null.
  • @throws RuntimeException if the service fails to start.
    */
    @SuppressWarnings(“unchecked”)
    public T startService(Class serviceClass) {
    final String name = serviceClass.getName();
    Slog.i(TAG, "Starting " + name);

// Create the service.
if (!SystemService.class.isAssignableFrom(serviceClass)) {
throw new RuntimeException("Failed to create " + name

  • ": service must extend " + SystemService.class.getName());
    }
    final T service;
    try {
    Constructor constructor = serviceClass.getConstructor(Context.class);
    service = constructor.newInstance(mContext);
    } catch (InstantiationException ex) {
    throw new RuntimeException("Failed to create service " + name
  • “: service could not be instantiated”, ex);
    } catch (IllegalAccessException ex) {
    throw new RuntimeException("Failed to create service " + name
  • “: service must have a public constructor with a Context argument”, ex);
    } catch (NoSuchMethodException ex) {
    throw new RuntimeException("Failed to create service " + name
  • “: service must have a public constructor with a Context argument”, ex);
    } catch (InvocationTargetException ex) {
    throw new RuntimeException("Failed to create service " + name
  • “: service constructor threw an exception”, ex);
    }

// Register it.
mServices.add(service);

// Start it.
try {
service.onStart();
} catch (RuntimeException ex) {
throw new RuntimeException("Failed to start service " + name

  • “: onStart threw an exception”, ex);
    }
    return service;
    }

我们发现,代码通过service = constructor.newInstance(mContext)方法创建了WifiService的实例,并且调用了service.onStart();方法,继续查看WifiService的源码:

源码路径:xxx/frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiService.java

package com.android.server.wifi;
import android.content.Context;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiScanner;
import android.util.Log;
import com.android.server.SystemService;
import java.util.List;

public final class WifiService extends SystemService {
private static final String TAG = “WifiService”;
final WifiServiceImpl mImpl;

public WifiService(Context context) {
super(context);
mImpl = new WifiServiceImpl(context);
}

@Override
public void onStart() {
Log.i(TAG, "Registering " + Context.WIFI_SERVICE);
publishBinderService(Context.WIFI_SERVICE, mImpl);
}

@Override
public void onBootPhase(int phase) {
if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
mImpl.checkAndStartWifi();
}
}
}

这里,我们看到了在WifiService的构造方法中创建了WifiServiceImpl实例,并且通过onStart()方法,将WifiServiceImpl实例mImpl传入到 publishBinderService(Context.WIFI_SERVICE, mImpl)中,我们继续到SystemService看看:
源码路径:xxx/frameworks/base/services/core/java/com/android/server/SystemService.java

/**

  • Publish the service so it is accessible to other services and apps.
    */
    protected final void publishBinderService(String name, IBinder service,
    boolean allowIsolated) {
    ServiceManager.addService(name, service, allowIsolated);
    }

历尽千辛万苦,终于看到我们想要找的东西了,原来publishBinderService()方法通过ServiceManager.addService(name, service, allowIsolated)将WifiServiceImpl注册到了ServiceManager中,我们看下注册的方式:

源码路径:xxx/frameworks/base/core/java/android/os/ServiceManagerNative#ServiceManagerProxy

public void addService(String name, IBinder service, boolean allowIsolated)
throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IServiceManager.descriptor);
data.writeString(name);
data.writeStrongBinder(service);
data.writeInt(allowIsolated ? 1 : 0);
mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
reply.recycle();
data.recycle();
}

这个保存方式跟我们getService()的方式是一致的!

至此,我们算是找到总算找到了IWifiManager.aidl的具体实现了,就是WifiServiceImpl,那么也就意味着我们的这整个WIfi的系统服务的接口定义、实现、注册、访问等流程都有两个一个大致的了解!

5、抱着怀疑的态度,我们看下WifiServiceImpl中是否真的实现了disconnect()方法:

源码路径:xxx/frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiServiceImpl.java

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img
img

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

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

如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
img

总结

学习技术是一条慢长而艰苦的道路,不能靠一时激情,也不是熬几天几夜就能学好的,必须养成平时努力学习的习惯。所以:贵在坚持!

最后如何才能让我们在面试中对答如流呢?

答案当然是平时在工作或者学习中多提升自身实力的啦,那如何才能正确的学习,有方向的学习呢?有没有免费资料可以借鉴?为此我整理了一份Android学习资料路线:

这里是一部分我工作以来以及参与过的大大小小的面试收集总结出来的一套BAT大厂面试资料专题包,主要还是希望大家在如今大环境不好的情况下面试能够顺利一点,希望可以帮助到大家。

好了,今天的分享就到这里,如果你对在面试中遇到的问题,或者刚毕业及工作几年迷茫不知道该如何准备面试并突破现状提升自己,对于自己的未来还不够了解不知道给如何规划。来看看同行们都是如何突破现状,怎么学习的,来吸收他们的面试以及工作经验完善自己的之后的面试计划及职业规划。

最后,祝愿即将跳槽和已经开始求职的大家都能找到一份好的工作!

这些只是整理出来的部分面试题,后续会持续更新,希望通过这些高级面试题能够降低面试Android岗位的门槛,让更多的Android工程师理解Android系统,掌握Android系统。喜欢的话麻烦点击一个喜欢再关注一下~

本文已被CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录

一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!

AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算

4304bb5a486d4c3ab8389e65ecb71ac0)

AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值