2024年安卓最全深入研究源码:Android10(2),android 网络面试

总结

这次面试问的还是还是有难度的,要求当场写代码并且运行,也是很考察面试者写代码
因为Android知识体系比较庞大和复杂的,涉及到计算机知识领域的方方面面。在这里我和身边一些朋友特意整理了一份快速进阶为Android高级工程师的系统且全面的学习资料。涵盖了Android初级——Android高级架构师进阶必备的一些学习技能。

附上:我们之前因为秋招收集的二十套一二线互联网公司Android面试真题(含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。)

里面包含不同方向的自学编程路线、面试题集合/面经、及系列技术文章等,资源持续更新中…

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

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

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

SystemServer是由Zygotefork出来的第一个进程,我们在上篇文章中也提到了,这里我们再来回顾下,在ZygoteInit类的main函数中,通过调用forkSystemServer(),内部采用硬编码的方式创建相关参数,启动SystemServer,由此正式进入SystemServer的相关业务逻辑中

ZygoteInit.java

private static Runnable forkSystemServer(String abiList, String socketName,
ZygoteServer zygoteServer) {

/* Hardcoded command line to start the system server */
// “通过硬编码的方式提供相关的参数”
String args[] = {
“–setuid=1000”, //用户id
“–setgid=1000”,//用户组id
“–setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,”

  • “1024,1032,1065,3001,3002,3003,3006,3007,3009,3010”,
    “–capabilities=” + capabilities + “,” + capabilities, //进程权能
    “–nice-name=system_server”, //进程niceName
    “–runtime-args”,
    “–target-sdk-version=” + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
    “com.android.server.SystemServer”, //需要启动的类
    };
    ZygoteArguments parsedArgs = null;

int pid; //processId,进程id

try {
parsedArgs = new ZygoteArguments(args); //“创建ZygoteArguments对象,把args解析为需要的参数”
Zygote.applyDebuggerSystemProperty(parsedArgs);
Zygote.applyInvokeWithSystemProperty(parsedArgs);

boolean profileSystemServer = SystemProperties.getBoolean(
“dalvik.vm.profilesystemserver”, false);
if (profileSystemServer) {
parsedArgs.mRuntimeFlags |= Zygote.PROFILE_SYSTEM_SERVER;
}

/* Request to fork the system server process */
pid = Zygote.forkSystemServer( // “fork创建SystemServer”
parsedArgs.mUid, parsedArgs.mGid,
parsedArgs.mGids,
parsedArgs.mRuntimeFlags,
null,
parsedArgs.mPermittedCapabilities,
parsedArgs.mEffectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}

}

SystemServer的主要流程

我们先来看一下整体的梳理 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 从上面这张流程图可以看到,SystemServer的主要流程其实还是比较简单的:

  1. 设置相关系统属性,并做一些准备工作

  2. 对Vm进行相关设置

  3. 创建主线程Looper

  4. 创建SystemServiceManager

  5. 创建ActivityThread及系统上下文Context

  6. 开启各种服务

//使用ServiceManger开启服务,并对这些服务进行管理
startBootstrapServices(); //引导服务
startCoreServices();//核心服务
startOtherServices(); //其他服务

  1. 进入Looper.loop的无限循环中

我们来看看SystemServer具体开启了哪些服务

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 可以看到这里面开启了很多的服务,所以,分成了三个函数类分类进程开启,

  1. 引导服务
  2. 核心服务
  3. 其他服务

这些服务,是通过调用SystemServiceManger.startServeice(),获取到参数传递的Class对象,使用反射的方式,获取到该类的构造器,创建该类的实例对象,并把该service对象添加到一个ArrayList列表中进行维护,最终调用service.onstart(),完成服务的开启任务

这里还要说一下,所有的服务,都是SystemService的子类对象,SystemService是一个抽象类,内部的onstart()是一个抽象方法,最终真正执行的逻辑是其子类对象自己去定义的

那么我们这里就可以先思考下,如果我们想添加一个自定义的系统服务,应该如何去做?这里先不做深究

具体源码

"ssm"中根据Class对象反射创建指定的Service对象

public T startService(Class serviceClass) {
try {
final String name = serviceClass.getName();
Slog.i(TAG, "Starting " + name);
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartService " + 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);
    }

startService(service);
return service;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
}

添加到mServices的列表中进行维护,并维护这些服务的生命中周期事件,执行该服务的onStart()函数

// Services that should receive lifecycle events.
private final ArrayList mServices = new ArrayList();

public void startService(@NonNull final SystemService service) {
// Register it.
mServices.add(service);
// Start it.
long time = SystemClock.elapsedRealtime();
try {
service.onStart();
} catch (RuntimeException ex) {
throw new RuntimeException("Failed to start service " + service.getClass().getName()

  • “: onStart threw an exception”, ex);
    }
    warnIfTooLong(SystemClock.elapsedRealtime() - time, service, “onStart”);
    }

SystemServer相关的主要系统服务

ActivityManagerService是如何启动的

ActivityManagerService是在startBootstrapServices函数中开启的服务,我们来具体看下,它是如何被创建和启动的

这里主要涉及到了三个类,ActivityTaskManagerServiceActivityManagerServiceSystemServiceManager

private void startBootstrapServices() {

//此处是通过"ssm"反射创建"atm"的静态内部类对象,并通过"Lifecycle"提供的"getService()“获取到"atm"实例对象
ActivityTaskManagerService atm = mSystemServiceManager.startService(
ActivityTaskManagerService.Lifecycle.class).getService();
//调用"ams"的静态内部类的静态方法"startService"函数,把"ssm"和"atm"传递过去
mActivityManagerService = ActivityManagerService.Lifecycle.startService(
mSystemServiceManager, atm);//内部还是使用"ssm"来创建的"ams”

}

具体如何启动的上面的代码注释已经解释的很清楚了,其中ATM和AMS中有着相似的设计,都是通过静态内部类Lifecycle来创建和获取本类对象,即当前系统服务的,关于AMS和Lifecycle我们后面有机会再做深究

WindowManagerServices是如何启动的

WMS是通过调用startOtherServices在其他服务中开启的, 可以看出来这里的开启方式跟AMS不太一样了,这里并不是使用SSM的StartService()函数来开启的,而是先通过WMS的静态工厂函数main()先创建出WMS对象,再通过ServiceManageraddService()函数,通过Binder机制进行进程间通信,把WMS注册到系统的服务表中

创建WMS对象并添加到ServiceManger

private void startOtherServices() {
// WMS needs sensor service ready
ConcurrentUtils.waitForFutureNoInterrupt(mSensorServiceStart, START_SENSOR_SERVICE);
mSensorServiceStart = null;
wm = WindowManagerService.main(context, inputManager, !mFirstBoot, mOnlyCore,
new PhoneWindowManager(), mActivityManagerService.mActivityTaskManager);
ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false,
DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO);
ServiceManager.addService(Context.INPUT_SERVICE, inputManager,

写在最后

很多人在刚接触这个行业的时候或者是在遇到瓶颈期的时候,总会遇到一些问题,比如学了一段时间感觉没有方向感,不知道该从哪里入手去学习,对此我整理了一些资料

如果你熟练掌握以下列出的知识点,相信将会大大增加你通过前两轮技术面试的几率!这些内容都供大家参考,互相学习。

①「Android面试真题解析大全」PDF完整高清版+②「Android面试知识体系」学习思维导图压缩包,最后觉得有帮助、有需要的朋友可以点个赞

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

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

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

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值