InputManagerService的InputDispatcher机制
概述源码分析1234bool InputDispatcherThread::threadLoop() { mDispatcher->dispatchOnce(); return true;}
时间分发流程图
dispatchOncethreadLoop()函数只是调用了InputDispatcher的dispatchOnce()函数,这个函数的代码如下:
1234567891011121314151617void InputDispatcher::dispatchOnce() { nsecs_t nextWakeupTime = LONG_LONG_MAX; { // 加锁 AutoMutex _l(mLock); mDispatcherIsAliveCondition.broadcast(); if (! haveCommandsLocked()) { // 如果mCommandQueue队列不为NULL dispatchO ...
ImputManagerService之业务进程和IMS的通信的交互
文章参考:http://gityuan.com/2016/12/24/input-ui/
概述前面文章都是介绍了两个线程InputReader和InputDispatcher的工作过程。
在InputDispatcher的过程讲到 调用InputChannel通过socket与远程进程通信,本文便展开讲解这个socket是如何建立的。
对于InputReader和InputDispatcher都是运行在system_server进程; 用户点击的界面往往可能是某一个app,而每个app一般地都运行在自己的业务进程,这里就涉及到跨进程通信,app进程是如何与system进程建立通信。
要解答这些问题,从Activity最基本的创建过程开始说起。我们都知道一般地Activity对应一个应用窗口, 每一个窗口对应一个ViewRootImpl。窗口是如何添加到Activity的,从Activity.onCreate()为起点讲解。
众所周知,Activity的生命周期的回调方法都是运行在主线程,也称之为UI线程,所有UI相关的操作都需要运行在该线程。
Activity.onCreate1234 ...
Android之WindowManager基础学习
[TOC]
文章参考:https://juejin.cn/post/6844904146227691527
概述本文主要分析 Activity、Window、PhoneWindow、WindowManager 之间的关系,为我们后面的文章 「如何在 Andorid 系统里添加自定义View」 等等文章奠定基础,先来了解一下它们的基本概念
WindowManager:它是一个接口类,继承自接口 ViewManager,对 Window 进行管理
Window:它是一个抽象类,它作为一个顶级视图添加到 WindowManager 中,对 View 进行管理
PhoneWindow:Window唯一实现类,Window是一个抽象概念,添加到WindowManager的根容器
DecorView: 它是 PhoneWindow 内部的一个成员变量,继承自 FrameLayout,FrameLayout 继承自 ViewGroup
Activity、Window、WindowManager 的关系在 Activity 内部维护着一个 Window 的实例变量 mWindow
1234567/ ...
01.面试题-大文件上传如何做断点续传
[TOC]
概述不管怎样简单的需求,在量级达到一定层次时,都会变得异常复杂
文件上传简单,文件变大就复杂
上传大文件时,以下几个变量会影响我们的用户体验
服务器处理数据的能力
请求超时
网络波动
上传时间会变长,高频次文件上传失败,失败后又需要重新上传等等
为了解决上述问题,我们需要对大文件上传单独处理
这里涉及到分片上传及断点续传两个概念
分片上传分片上传,就是将所要上传的文件,按照一定的大小,将整个文件分隔成多个数据块(Part)来进行分片上传
如下图:
上传完之后再由服务端对所有上传的文件进行汇总整合成原始的文件。
大致流程如下:
将需要上传的文件按照一定的分割规则,分割成相同大小的数据块;
初始化一个分片上传任务,返回本次分片上传唯一标识;
按照一定的策略(串行或并行)发送各个分片数据块;
发送完成后,服务端根据判断数据上传是否完整,如果完整,则进行数据块合成得到原始文件
断点续传断点续传指的是在下载或上传时,将下载或上传任务人为的划分为几个部分
每一个部分采用一个线程进行上传或下载,如果碰到网络故障,可以从已经上传或下载的部分开始继续上传下载未完成的部分,而没有必要 ...
实现 ART 即时 (JIT) 编译器
文章转自:https://source.android.com/devices/tech/dalvik/jit-compiler?hl=zh-cn
概述Android Runtime (ART) 包含一个具备代码分析功能的即时 (JIT) 编译器,该编译器可以在 Android 应用运行时持续提高其性能。JIT 编译器对 Android 运行组件当前的预先 (AOT) 编译器进行了补充,可以提升运行时性能,节省存储空间,加快应用和系统更新速度。相较于 AOT 编译器,JIT 编译器的优势也更为明显,因为在应用自动更新期间或在无线下载 (OTA) 更新期间重新编译应用时,它不会拖慢系统速度。
尽管 JIT 和 AOT 使用相同的编译器,它们所进行的一系列优化也较为相似,但它们生成的代码可能会有所不同。JIT 会利用运行时类型信息,可以更高效地进行内联,并可让堆栈替换 (OSR) 编译成为可能,而这一切都会使其生成的代码略有不同。
JIT 架构
JIT 编译JIT 编译涉及以下活动:
图 2. 配置文件引导的编译。
MultiDex工作原理分析和优化方案
[TOC]
文章转自:https://zhuanlan.zhihu.com/p/24305296
概述动态加载技术(插件化)系列已经坑了有一段时间了,不过UP主我并没有放弃治疗哈,相信在不就的未来就可以看到“系统Api Hook模式”和插件化框架Frontia的更新了。今天要讲的是动态加载技术的亲戚 —— MultiDex。他们的核心原理之一都是dex文件的加载。
MultiDex是Google为了解决“65535方法数超标”以及“INSTALL_FAILED_DEXOPT”问题而开发的一个Support库,具体如何使用MultiDex现在市面已经有一大堆教程(可以参考给 App 启用 MultiDex 功能),这里不再赘述。这篇日志主要是配合源码分析MultiDex的工作原理,以及提供一些MultiDex优化的方案。
Dex的工作机制在Android中,对Dex文件操作对应的类叫做DexFile。在CLASSLOADER 的工作机制中,我们说到:
对于 Java 程序来说,编写程序就是编写类,运行程序也就是运行类(编译得到的class文件),其中起到关键作用的就是类加载器 Class ...
Android系统控制CPU调用逻辑
查看系统所有的CPU
123456blueline:/sys/devices/system/cpu $ lscore_ctl_isolated cpu2 cpu5 cpufreq hang_detect_gold isolated offline powercpu0 cpu3 cpu6 cpuidle hang_detect_silver kernel_max online presentcpu1 cpu4 cpu7 gladiator_hang_detect hotplug modalias possible ueventblueline:/sys/devices/system/cpu $ cat possible0-7
查看所有正在运行的核
123blueline:/sys/devices/system/cpu $ cat online0-7blueline:/sys/devices/system/cpu $
查看所有的 ...
Android系统控制之设置CPU锁频
123blueline:/sys/devices/system/cpu/cpu0 # lscore_ctl cpufreq cpuidle hotplug isolate of_node online power rq-stats sched_load_boost subsystem ueventblueline:/sys/devices/system/cpu/cpu0
查看当前核心的频率
123456789:/sys/devices/system/cpu/cpu0/cpufreq # lsaffected_cpus cpuinfo_transition_latency scaling_boost_frequencies scaling_max_freq statscpuinfo_cur_freq related_cpus scaling_cur_freq scaling_min_freqcpuinfo_max_freq scaling_available_frequencies scaling_driver ...
Java并发编程之线程池基础学习
[TOC]
概述线程池好处首先,我们先来思考一个问题:我们为什么要是使用线程池??
当我们有很多耗时任务需要处理的时候,很自然我们会想到使用子线程来进行处理,防止阻塞主线程。创建线程很自然我们使用new thread() 来创建一个线程。
但是,每增加一个耗时任务,我们就要创建一个线程。耗时任务执行完毕之后,gc又会适时的继续线程的回收。创建/销毁线程伴随着系统开销,过于频繁的创建/销毁线程,会很大程度上影响处理效率。
例如:记创建线程消耗时间T1,执行任务消耗时间T2,销毁线程消耗时间T3如果T1+T3>T2,那么是不是说开启一个线程来执行这个任务太不划算了!
正好,线程池缓存线程,可用已有的闲置线程来执行新任务,避免了过多创建线程消耗时间T1+销毁线程消耗时间T3T3带来的系统开销。线程并发数量过多,抢占系统资源从而导致阻塞。
我们知道线程能共享系统资源,如果同时执行的线程过多,就有可能导致系统资源不足而产生阻塞的情况运用线程池能有效的控制线程最大并发数,避免以上的问题。
同时,在原有线程的基础上,线程池增加了针对线程的调度,使得操作调度线程更加方便。比如 ...