总结
现在新技术层出不穷,如果每次出新的技术,我们都深入的研究的话,很容易分散精力。新的技术可能很久之后我们才会在工作中用得上,当学的新技术无法学以致用,很容易被我们遗忘,到最后真的需要使用的时候,又要从头来过(虽然上手会更快)。
我觉得身为技术人,针对新技术应该是持拥抱态度的,入了这一行你就应该知道这是一个活到老学到老的行业,所以面对新技术,不要抵触,拥抱变化就好了。
Flutter 明显是一种全新的技术,而对于这个新技术在发布之初,花一个月的时间学习它,成本确实过高。但是周末花一天时间体验一下它的开发流程,了解一下它的优缺点、能干什么或者不能干什么。这个时间,并不是我们不能接受的。
如果有时间,其实通读一遍 Flutter 的文档,是最全面的一次对 Flutter 的了解过程。但是如果我们只有 8 小时的时间,我希望能关注一些最值得关注的点。
(跨平台开发(Flutter)、java基础与原理,自定义view、NDK、架构设计、性能优化、完整商业项目开发等)
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
- SystemServer进程
SystemServer进程主要用于创建系统服务,例如AMS、WMS、和PMS都是由它来创建的。
- Service进程启动
-
启动Binde线程池,这样就可以与其他进程进行通信。
-
创建SystemServiceManager,用于对系统的服务进行创建、启动生命周期管理。
-
启动各种系统服务(引导服务、核心服务、其他服务)。
- 时序图
4. Launcher启动过程
- Launcher
当系统启动到最后一步时,会启动一个应用程序,也就是我们通常看到的应用桌面,它被称作Launcher,在Launcher程序启动的时候会请求PackageManagerService来获取当前系统已安装的应用程序,并将其应用信息封装成快捷方式展现在我们的屏幕桌面上,这样用户通过点击应用图标就可以启动应用程序了。
所以Launcher由两个特点:
-
作为Android系统的启动器,用于启动应用程序。
-
作为Android系统的桌面,用于显示和管理应用程序的快捷图标或其他桌面组件。
- 时序图
总结:Android系统启动流程
-
启动电源以及系统启动。(引导芯片从固化在ROM的预定义地方执行,加载主引导BootLoader到RAM)
-
引导程序BootLoader。(把系统OS拉起来)
-
Linux内核启动。(设置缓存、被保护存储器、计划列表、加载驱动。内核完成时,首先在系统文件中寻找init.rc文件,并启动init进程)
-
init进程启动。(初始化和启动属性服务,并启动Zygote进程)
-
Zygote进程启动。(创建Java虚拟机并为Java虚拟机注册JNI方法,创建服务端Socket,启动SystemServer进程。)
-
SystemServer进程启动。(启动Binder线程池和SystemServiceManager,并且启动各种系统服务。)
-
Launcher启动。(被SystemServer进程启动的AMS会启动Launcher,Launcher启动后会将已安装的应用程序快捷方式图标展示到桌面。)
图示:
如果启动一个应用程序,AMS会检测该应用程序进程是否存在,如果不存在则向Zygote进行请求创建。
我们知道Zygote的Java框架层中创建了一个服务端的Socekt,用于等待AMS创建新的应用进程请求。AMS发起请求后,Zygote会fock自身进程来创建应用程序,这样应用程序进程在启动时就拥有了虚拟机实例,同时也创建了Binder线程池和消息循环,这样运行在应用程序进程中的应用程序就可以进行进程间通信以及消息处理了。
1. AMS发送启动应用进程请求时序图
2. Zygote接收请求并创建应用程序进程时序图
我们看到该时序图和上文提到的SystemServer启动过程时序图有相似之处。共同点都是从ZygoteInit调用RuntimeInit的applicationInit开始,后续执行流程一样。
注:为什么Android会选择抛出MethodArgsCall异常的方式来调用方法而不是直接调用SystemService的main方法或ActivityThread的main方法?
是因为抛出异常的处理会清除所有的设置过程需要的堆栈帧(内存优化)
3.消息循环创建过程
ActivityThread是用于管理当前应用程序进程的主线程。其部分关键源码如下:
public static void main(String[] args){
…
// 创建主线程Looper
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
if(sMainThreadHandler == null){
// 创建主线程H类
sMainThreadHandler = thread.getHandler();
}
if(false){
Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, “ActivityThread”));
}
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
// Looper开始工作
Looper.loop();
throw new RuntimeException(“Main thread loop unexpectedly exited”);
}
1. 根Activity启动过程
Activity启动分为:根Activity启动和普通Activity启动。而普通Activity与根Activity启动方式类似,根Activity启动更具有代表性。
根Activity启动过程比较复杂,大致分为3个部分:Launcher请求AMS过程、AMS到ApplicationThread调用过程、ActivityThread启动Activity。
- Launcher请求AMS时序图:
注:IActivityManager为AMS的代理对象,它是在Instrumentation中通过ActivityManager.getService()方法获取的。见下文ActivityManager源码:
public static IActivityManager getService(){
return IActivityManagerSingleton.get();
}
private static final Singleton IActivityManagerSingleton = new Singleton(){
@Override
protected IActivityManager create(){
// Binder类型的AMS引用
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
// 所以此处的IActivityManager实则是AMS的代理对象
final IActivityManager am = IActivityManager.Stub.asInteface(b);
return am;
}
文末
架构师不是天生的,是在项目中磨练起来的,所以,我们学了技术就需要结合项目进行实战训练,那么在Android里面最常用的架构无外乎 MVC,MVP,MVVM,但是这些思想如果和模块化,层次化,组件化混和在一起,那就不是一件那么简单的事了,我们需要一个真正身经百战的架构师才能讲解透彻其中蕴含的深理。
一线互联网Android面试题总结含详解(初级到高级专题)
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
专题)**
[外链图片转存中…(img-qgumotio-1715856598681)]
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!