zBug - android深入
type: channel
link: https://zbug.cc/index.php/category/android深入
items: Android之ActivityThread
items: Android之WMS
items: Android之Init
items: Android之Zygote
items: Android之PMS
items: Android之AMS
items: Handler是如何传递消息的

Android之ActivityThread
type: item
date: 2023-01-05T01:55:00+00:00
description: 每一个App在启动时，都会由Zygote fork出一个进程，进程具有独立的资源空间，用于承载App上运行的各种Activity/Service等组件。当进程创建后就要真正去启动一个App了，会调用ActivityThread的main方法。 frameworks/base/core/java/android/app/ActivityThread.java ActivityThread分析:main方法public static void main(String[] args) { ...... //1.创建主线程looper,主线程初始化 Looper.prepareMainLooper(); //2.主线程Handler初始化 ActivityThread thread = new ActivityThread(); thread.attach(false); if (sMainThreadHandler == null) { sMainThreadHandler = thread.getHandler(); } Looper.loop(); }主线程初始化frameworks/base/core/java/android/os/Looper.java//主线程Looper的初始化 public static void prepareMainLooper() { prepare(false); synchronized (Looper.class) { if (sMainLooper != null) { throw new IllegalStateException("The main Looper has already been prepared."); } sMainLooper = myLooper(); } } //普通线程初始化 public static void prepare() { prepare(true); } private static void prepare(boolean quitAllowed) { if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(new Looper(quitAllowed)); } public static @Nullable Looper myLooper() { return sThreadLocal.get(); }从上面的代码中可以看出，主线程初始化时，prepare传入false，而普通线程初始化时传入true，这个参数为quitAllowed，表示线程是否可以退出，主线程无法退出。prepare函数中创建一个Looper对象，并将对象保存在ThreadLocal中。在prepare之后，又将主线程Looper赋值给了成员变量sMainLooper，这个成员变量的作用是向其他线程提供主线程Looper对象。public static Looper getMainLooper() { synchronized (Looper.class) { return sMainLooper; } }这样当我们调用Looper.getMainLooper()时可以获取到主线程的Looper对象了。主线程Handler初始化在main方法下创建了ActivityThread对象，并获取了主线程的Handler。final H mH = new H(); final Handler getHandler() { return mH; }由此可见主线程的Handler作为ActivityThread的成员变量，是在ActivityThread的main方法被执行，ActivityThread被创建时而初始化。ActivityThread.attch()frameworks/base/core/java/android/app/ActivityThread.javafinal ApplicationThread mAppThread = new ApplicationThread(); private void attach(boolean system) { ...... final IActivityManager mgr = ActivityManagerNative.getDefault(); try { mgr.attachApplication(mAppThread); } catch (RemoteException ex) { throw ex.rethrow…

Android之WMS
type: item
date: 2023-01-05T00:53:00+00:00
description: WindowManagerService简称WMS，WMS是属于Android系统的其他服务，但是它的重要性和AMS在同一级别，作为“窗口管理员”，它负责窗口的创建、调度、显示以及触摸事件分发。也是一个Android程序猿必须了解的系统服务。在SyetemServer启动时会调用startOtherServices:private void startOtherServices() { WindowManagerService wm = null; //InputManagerService traceBeginAndSlog("StartInputManagerService"); inputManager = new InputManagerService(context); Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); traceBeginAndSlog("StartWindowManagerService"); wm = WindowManagerService.main(context, inputManager, mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL, !mFirstBoot, mOnlyCore); ServiceManager.addService(Context.WINDOW_SERVICE, wm); ServiceManager.addService(Context.INPUT_SERVICE, inputManager); Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); mActivityManagerService.setWindowManager(wm); inputManager.setWindowManagerCallbacks(wm.getInputMonitor()); inputManager.start(); wm.displayReady(); wm.systemReady(); }可以看到，InputManagerService作为参数传递给了WMS，而WMS又作为参数传给了AMSWMS.mainpublic static WindowManagerService main(final Context context, final InputManagerService im, final boolean haveInputMethods, final boolean showBootMsgs, final boolean onlyCore) { final WindowManagerService[] holder = new WindowManagerService[1]; //运行在"android.display"线程 DisplayThread.getHandler().runWithScissors(new Runnable() { @Override public void run() { holder[0] = new WindowManagerService(context, im, haveInputMethods, showBootMsgs, onlyCore); } }, 0); return holder[0]; }WindowManagerServiceprivate WindowManagerService(Context context, InputManagerService inputManager, boolean haveInputMethods, boolean showBootMsgs, boolean onlyCore) { mContext = context; mHaveInputMethods = haveInputMethods; mAllowBootMessages = showBootMsgs; mOnlyCore = onlyCore; ...... //保存传进来的IMS mInputManager = inputManager; mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class); mDisplaySettings = new DisplaySettings(); mDisplaySettings.readSettingsLocked(); mDisplayManager = (DisplayManager)context.getSystemServ…

Android之Init
type: item
date: 2023-01-04T09:06:00+00:00
description: init是Linux系统中用户控件的第一个进程,init的职责：1.init进程创建系统中的几个关键进程，如zygote进程2.Android系统中有很多属性，于是init提供了一个property service来管理它们。init的工作流程：解析两个配置文件，我们将分析其中对init.rc文件的解析执行各个阶段的动作，创建zygote的工作就是在其中的某个阶段完成的调用property_init初始化属性相关的资源，并且通过property_start_server启动属性服务init进入一个无限循环，并且等待一些事情发生。重点关注init如何处理来自socket和来自属性服务器的相关事情解析配置文件: init会解析两个配置文件，一个是init.rc，另一个与硬件平台相关。解析配置文件调用的parse_config_file函数。这个函数中主要是读取配置文件（read_file），读取结束后调用parse_config函数进行真正的解析keyword.h文件中定义了init中使用关键字通过两次包含得到了一个keyword_info结构体数组。zygote是由init进程fork并且execv（这时会传入一个环境变量，在ZygoteInit.java的main方法中会用到）后创建的。zygote进程死后、它的父进程init会找到代表zygote的那个service并且杀掉zygote创建的所有子进程，Java世界也就崩溃了zygote的重启，zygote死的时候会将service结构体的flags设置为SVC_RESTARTING;inti.c::main函数中有一个代码片段zygote就重启for（;;）{ int nr, i, timeout = -1; for (i = 0; i < fd_count； i++} ufds[i].revents = 0； drain_action_queue () ； //poll A数返回后，会进入下一轮的循环 restart_processes () ； // 这里会重启所有 flag 标志为 SVC_RESTARTING的 service。 }init.rc是一个配置文件，是由Android初始化语言编写的脚本，主要包含五种类型语句：Action、Command、Service、Option、ImportAction动作由一组命令（Commands）组成，动作还包含了一个触发器,决定了运行这个动作的时机。通过触发器trigger,即通过以on开头的语句来决定执行相应的service的时机,具体有如下时机：on early-init; 在初始化早期阶段触发；on init; 在初始化阶段触发；on late-init; 在初始化晚期阶段触发；on boot/charger： 当系统启动/充电时触发；on property:<key>=<value>: 当属性值满足条件时触发；CommandCommand是action 的命令列表中命令，或者是service中的选项onrestart的参数命令，命令将在所属事件发生时被一个一个的执行。常用命令如下：class_start <service_class_name>： 启动属于同一个class的所有服务；class_stop <service_class_name> : 停止指定类的服务start <service_name>： 启动指定的服务，若已启动则跳过；stop <service_name>： 停止正在运行的服务setprop <name> <value>：设置属性值mkdir <path>：创建指定目录symlink <target> <sym_link>： 创建连接到<target>的<sym_link>符号链接；write <path> <string>： 向文件path中写入字符串；exec： fork并执行，会阻塞init进程直到程序完毕；exprot <name> <name>：设定环境变量；loglevel <level>：设置log级别hostname <name> : 设置主机名import <filename> ：导入一个额外的init配置文件Service服务Service,以service开头，由init进程启动，一般运行在init的一个子进程中，所以启动service前需要判断对应的可执行文件是否存在。命令：service <name><pathname> [ <argument> ]* <name>：表示service的名称<pathname>：表示此 service 所在的路径（ service 为可执行文件，所以存在存储路径）<argument>：表示启动 service 所带的参数 ：表示对此 …

Android之Zygote
type: item
date: 2023-01-03T07:13:00+00:00
description: Zygote是Android系统创建新进程的核心进程，负责启动Dalvik虚拟机，加载一些必要的系统资源和系统类，启动system_server进程，随后进入等待处理app应用请求。Zygote进程由init启动：# /vendor/default.prop ro.zygote=zygote64_32 # /init.rc import /init.${ro.zygote}.rc on zygote-start && property:ro.crypto.state=... # A/B update verifier that marks a successful boot. exec_start update_verifier_nonencrypted start netd start zygote start zygote_secondary # /init.zygote64_32.rc service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote class main priority -20 user root group root readproc reserved_disk socket zygote stream 660 root system onrestart write /sys/android_power/request_state wake onrestart write /sys/power/state on onrestart restart audioserver onrestart restart cameraserver onrestart restart media onrestart restart netd onrestart restart wificond writepid /dev/cpuset/foreground/tasks service zygote_secondary /system/bin/app_process32 -Xzygote /system/bin --zygote --socket-name=zygote_secondary --enable-lazy-preload class main priority -20 user root group root readproc reserved_disk socket zygote_secondary stream 660 root system onrestart restart zygote writepid /dev/cpuset/foreground/tasks 属性 ro.zygote 的值包括zygote32、zygote64、zygote32_64、zygote64_32，对应区别如下：init.zygote32.rc：zygote进程对应的执行程序是app_process(纯32bit模式)init.zygote64.rc：zygote进程对应的执行程序是app_process64(纯64bit模式)init.zygote32_64.rc：启动两个zygote进程，对应的执行程序分别是app_process32(主模式)、app_process64init.zygote64_32.rc：启动两个zygote进程，对应的执行程序分别是app_process64(主模式)、app_process32zygote和zygote_secondary其实大同小异，都是执行/system/bin/app_process，其执行的的应用及参数如下:app_process64 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygotemain() AppRuntime::AppRuntime() AndroidRuntime::AndroidRuntime() SkGraphics::Init() // 创建Dalvik缓存 maybeCreateDalvikCache() AndroidRuntime::start("com.android.internal.os.ZygoteInit", args, ) // JniInvocation位于libnativehelper JniInvocation::JniInvocation() /* * 初始化虚拟机环境 * - 加载libart.so, 由art/runtime生成 * - 导出JNI_GetDefaul…

Android之PMS
type: item
date: 2023-01-03T01:21:00+00:00
description: PMS全称PackageManagerService，PMS是Android系统核心服务之一，处理包管理相关的工作，常见的比如安装、卸载应用等。PMS是系统服务，那么应用层肯定有个PackageManager作为binder call client端来供使用，但是这里要注意，PackageManager是个抽象类，一般使用的是它的实现类：ApplicationPackageManager。因此PackageManager功能的具体实现还是ApplicationPackageManager这个实现类。PMS主要功能：安装、卸载应用查询permission相关信息查询Application相关信息(application、activity、receiver、service、provider及相应属性等)查询已安装应用增加、删除permission清除用户数据、缓存、代码等在SystemServer启动时会调用startBootstrapServices()来启动引导服务，在startBootstrapServices中会启动PackageManagerService:... mPackageManagerService = PackageManagerService.main(mSystemContext, installer, mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore); 这里PMS的构造方法：public static PackageManagerService main(Context context, Installer installer, boolean factoryTest, boolean onlyCore) { // Self-check for initial settings. PackageManagerServiceCompilerMapping.checkProperties(); //初始化PMS PackageManagerService m = new PackageManagerService(context, installer, factoryTest, onlyCore); m.enableSystemUserPackages(); //将package服务注册到ServiceManager大管家 ServiceManager.addService("package", m); return m; }PMS的构造方法一共有700多行，在代码中，将PMS的构造流程分为了5个阶段，每个阶段会使用EventLog.writeEvent打印系统日志。BOOT_PROGRESS_PMS_START（开始阶段）BOOT_PROGRESS_PMS_SYSTEM_SCAN_START（扫描系统阶段）BOOT_PROGRESS_PMS_DATA_SCAN_START（扫描Data分区阶段）BOOT_PROGRESS_PMS_SCAN_END（扫描结束阶段）BOOT_PROGRESS_PMS_READY（准备阶段）开始阶段(BOOT_PROGRESS_PMS_START)public PackageManagerService(Context context, Installer installer, boolean factoryTest, boolean onlyCore) { //打印开始日志 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START, SystemClock.uptimeMillis()); if (mSdkVersion <= 0) { Slog.w(TAG, "**** ro.build.version.sdk not set!"); } mContext = context; mPermissionReviewRequired = context.getResources().getBoolean( R.bool.config_permissionReviewRequired); mFactoryTest = factoryTest; mOnlyCore = onlyCore; //用于存储屏幕的相关信息 mMetrics = new DisplayMetrics(); //创建Settings对象 (1) mSettings = new Settings(mPackages); // 添加system, phone, log, nfc, bluetooth, shell这六种shareUserId到mSettings； mSettings.ad…

Android之AMS
type: item
date: 2023-01-03T01:11:00+00:00
description: AMS全称ActivityManagerService，AMS是Android中最核心的服务，主要负责系统中四大组件的启动、切换、调度及应用进程的管理和调度等工作，其职责与操作系统中的进程管理和调度模块相类似，因此它在Android中非常重要。统一调度所有应用程序的Activity的生命周期启动或杀死应用程序的进程启动并调度Service的生命周期注册BroadcastReceiver，并接收和分发Broadcast启动并发布ContentProvider调度task处理应用程序的Crash查询系统当前运行状态ActivityManagerService是在SystemServer.java中启动的。SystemServer会根据顺序依次启动各个服务： // Start services. try { traceBeginAndSlog("StartServices"); startBootstrapServices(); startCoreServices(); startOtherServices(); SystemServerInitThreadPool.shutdown(); } catch (Throwable ex) { Slog.e("System", "******************************************"); Slog.e("System", "************ Failure starting system services", ex); throw ex; } finally { traceEnd(); }执行startBootstrapServices函数:// Activity manager runs the show. traceBeginAndSlog("StartActivityManager"); mActivityManagerService = mSystemServiceManager.startService( ActivityManagerService.Lifecycle.class).getService(); mActivityManagerService.setSystemServiceManager(mSystemServiceManager); mActivityManagerService.setInstaller(installer); traceEnd(); ……这里启动了ActivityManagerService.Lifecycle.class服务， public static final class Lifecycle extends SystemService { private final ActivityManagerService mService; public Lifecycle(Context context) { super(context); mService = new ActivityManagerService(context); } @Override public void onStart() { mService.start(); } public ActivityManagerService getService() { return mService; } }在startService中调用了ActivityManagerService的onStart()方法来启动该服务:public void startService(@NonNull final SystemService service) { // Register it. mServices.add(service); // Start it. long time = System.currentTimeMillis(); try { service.onStart(); } catch (RuntimeException ex) { throw new RuntimeException("Failed to start service " + service.getClass().getName() + ": onStart threw an exception", ex); } warnIfTooLong(System.currentTimeMillis() - time, service, "onStart"); }

Handler是如何传递消息的
type: item
date: 2020-04-21T04:31:00+00:00
description: 先认识下跟Handler有关的几个类：MessageQueue,Message,Runnable,Looper。Runnable和Message可以被传入某个MessageQueue中；Looper不断地从MessageQueue中取出Object然后传给Handler进行处理，依次循环，如果队列为空，就会进入休眠；Handler利用自身的处理机制对传入的Object进行相应的处理。认识这几个类后，再了解下Handler和Thread的关系一个Thread对应一个Looper;一个Looper对应一个MessageQueue;一个MessageQueue对应N个Message;一个Message中对应一个Handle来处理事件；由此可以看出，Thread和Handler是一对多的关系；而Handler主要有两个功能，处理message和将message传入MessageQueue中。Looper从MessageQueue中取出一个Message后，首先会调用Handler.dispatchMessage进行消息分发，默认情况下Handler的分发流程是：Message.callback(Runnable obj) 如果不为空会优先调用callback处理Handler.mCallback 如果不为空会调用mCallback.handleMessage如果以上两个对象都不存在，则会调用Handler.handleMessage如果项目中有需要改变handler的默认行为，可以重载dispatchMessage或handleMessage。Handler发送消息有两种方式，分别是post和send，这两种方式都是负责将message传入MessageQueue，区别在于send处理的参数直接是message,而post需要先把其它信息转换成message,再调用send来执行下一步,看源码：public final boolean post(Runnable r){ return sendMessageDelayed(getPostMessage(r),0); }因为调用时会传一个Runnable对象，post需要先将其封装成一个Message，接着通过对应的send把它传到MessageQueue里。private static Message getPostMessage(Runnable r){ Message m=Message.obtain();//Android系统会维护一个全局的Message池，当用户需要使用Message时，可以调和obtain获得，不用去自行创建，这样可以避免不必要的资源浪费 m.callback=r;//将Runnable对象设置为Message的回调函数 return m; }拿到Message后，再调用sendMessageDelayed来发送消息，这个函数可设置多长时间后再发送，在其内部又调用sendMessageAtTime来发送。public boolean sendMessageAtTime(Message msg, long uptimeMillis) { MessageQueue queue = mQueue; if (queue == null) { RuntimeException e = new RuntimeException(this + " sendMessageAtTime() called with no mQueue"); Log.w("Looper", e.getMessage(), e); return false } msg.target = this; return enqueueMessage(queue,msg,uptimeMillis);//将message传入MessageQueue }这样就将一条由Runnable组成的Message通过Handler成功传入MessageQueue。