- 博客(49)
- 收藏
- 关注
原创 AsyncTask源码分析
1、一个超级简单的用法,就从这里分析吧2、构造方法中确定looper3、execute方法4、sDefaultExecutor对象及execute方法5、线程池6、由exec.execute(mFuture);这句看下构造函数中mFuture的初始化7、从线程池源码中我们知道调用的是mWorker的call方法所以...
2020-07-11 21:37:08 139
原创 view显示总结
1、Activity在被启动时调用attach方法生成PhoneWindow2、在onCreate生命周期调用setContentView3、初始化DecorView,并根据设置的主题填充SDK中的布局,然后findViewById固定的id视图并返回该View赋值给mContentParent4、填充resId,获得到viewTree后添加到mContentView中5、onResume执行后,WM添加View...
2020-07-10 23:55:55 199
原创 在WMS中创建与Client中相同的Surface
1、开始建立连接2、将生成的window与surface传给AMS中的session3、mWindowSession的赋值4、通过WMS对mWindowSession5、Session对象6、所以mWindowSession就是通过WMS获取的IWindowSession的binder引用,看下 其中的relayout7、在WMS中创建Surface的管理类...
2020-07-09 23:59:16 192
原创 View的测量、布局、绘制过程
1、onMeasure,View的测量以DecorView为例可以看出每次都会获取测量模式,测量模式如下图比较好理解测量模式是根据int的最高两位,分别对应00,01,102、接下来传入onMeasure的参数3、makeMeasureSpec,在高于17的版本上确保模式一定在0-2之间,因为如果size的最高两位不为0在对测量模式会有影响4、测量子控件5、全部测量完毕后,设置控件的大小6、从调用规则上看是链式调用,故最先设置的是子View的大小,
2020-07-08 22:38:03 192
原创 View的测量、布局、绘制被调用过程
1、获取WindowManager并向window中添加视图2、WindowManager的真正实现,在activity中的attach方法中会执行下面的方法3、接下来看WindowManagerImpl中的addView方法4、开始请求布局5、直接看TraversalRunnable最终调用performTraversals方法6、最终会调用onMeasure、onLayout、onDraw...
2020-07-08 01:06:11 116
原创 View的填充解析过程
1、在onCreate生命周期会调用setContentView2、在activity启动的过程中已经知道了attach方法中window的真正实现是PhoneWindow3、初始化DecorView(继承与FrameLayout)以及我们要展示界面的父控件4、mLayoutInflater的初始化5、context在activity启动时已经分析其真正实现是ContextImpl,所以获得的LayoutInflater是PhoneLayoutInflater..
2020-07-06 23:52:56 164
原创 activity启动四-总结
1、启动桥梁 Intentintent初始化时启动信心封装在ComponentName中,包括包名和类的完整名称2、Instrumentation 仪表类启动Activity时获取AMS的引用(binder)Activity各生命周期调用3、AMS持有活动栈管理对象(ActivityStackSupervisor)要启动的类检测完毕后让启动的Activity进入 onPause状态检测应用程序进程是否已经存在,不存在就将启动信心通过socket传入zygote进程,让其孵化应
2020-07-05 16:49:14 159 1
原创 Activity启动三
1、application初始化后就要真正的启动activity了2、realStartActivityLocked3、AMS所在进程调用 ActivityThread中的Stub实体对象中的scheduleLaunchActivity方法4、处理消息5、加载类6、看到ClassLoader是一阵狂喜的,因为项目中用到了Replugin插件化,这里hook了mClassLoader,加载插件中的类也就一清二楚来了,因为校验已经完成,加载哪个类就生成哪个类对象
2020-07-04 19:42:13 845
原创 Activity启动二
1、开始处理让目标activity进入onResume生命周期的事宜2、目标activity要启动前先让启动者进入onPause状态3、通过进程间通信调用client端让启动者onPause4、上图调用点是4、mH既然是handler,已经分析过sendMessage最终会调用到5、activity进入调用onPause生命周期6、看到这不难看出activity的生命周期调用都是通过 mH这个对象放入其对应的消息队列处理7、启动activity
2020-07-04 00:13:34 204 1
原创 Activity启动过程一
1、启动入口2、Instrumentation对象3、ActivityManager4、通过ServiceManager获得ActivityManagerService(AMS)、5、AMS中的startActivity6、ActivityStarter7、ActivityStackSupervisor8、LocalServices9、启动组件的关键步骤检查启动的类是否存在,这个是由PackManagerService管理的,生成过程请看
2020-07-03 00:43:58 291
原创 IntentService、HandlerThread与ThreadLoccal、ThreadLocalMap
1、IntentService2、从上图看出是个服务,所以看下onCreate方法,初始化了一个HandlerThread对象,以及一个Handler,注意Handler传入的Looper对象是HandlerThread对象3、onStart方法 ,注意msg属性的赋值4、接下来看下onHandleIntent执行时所在的线程上面说了Handler传入的是HandlerThread中的Looper,那么HandlerThread是什么 呢?5、HandlerThread.
2020-07-01 00:42:37 132
原创 app性能优化
1、启动优化(1)在app主题上设置一个与欢迎界面一样的图片,可以解决白屏问题,从视觉上优化(2)在第一次启动时会初始化Application,而我们引入的许多第三方都会在onCreate中初始化,可以对这些初始化的框架进行分析,除非必须延迟初始化或在非主线程初始化https://blog.csdn.net/qian520ao/article/details/819085052、过度绘制优化开发者选项中打开GPU过度绘制选项,查看页面布局,根据颜色不同查看绘制情况进行优化通过计算两个
2020-06-28 23:35:54 147 1
原创 apk构建过程
1、首先我们知道Android运行的是dex文件,java是.class文件,而且我们通过分析apk包括以下几个部分那么哪个部分先生成呢?程序肯定是从dex文件中获取执行的数据的,而我们编写代码的时候经常会引用.R的报名,所以在打包dex前自然对应的r.java已经生成,还有resources.arsc是我们引用比如图片名称的id对应部分,不然我们在构建中如果图片不存在就无法编译通过(以上是个人理解)所以第一步是生成这两个部分:R.java和resources.arsc,生成的工具是aapt,比如我
2020-06-27 23:26:54 478
原创 apk瘦身
1、查看apk体积分布2、DEX文件优化,直接在debug中优化3、res目录在Android中为适配不同分辨率以及国际化,会放图片到不同的目录,所以app的value对应数据只需配置所需语言 比如只有中文,那么只保留value一个文件目录即可,而对于图片资源 则可只保留一套资源,比如只在XXH中保留资源图片,而对于图片本身则要压缩文件,图片格式用webp等4、由上面的截图我们RE看下AndroidManifest、META-INF5、resource.arsc文
2020-06-26 23:07:09 113
原创 JVM知识点
1、程序计数器 线程执行的字节码指令,线程私有2、虚拟机栈每个线程会生成一个虚拟机栈(线程私有),每个方法是一个栈帧方法的调用就是进栈出栈的过程栈帧包含:局部变量表、出口(返回值)、动态链接、操作数栈3、本地方发展4、方法区5、堆6、类加载过程7、内存回收与泄漏堆的划分、回收算法、GC Root8、内存泄漏定位9、Java引用类型强引用、软引用、弱引用、虚引用...
2020-06-25 22:41:20 156
原创 代码混淆
1、代码混淆https://blog.csdn.net/sdfsdfdfa/article/details/810582702、代码混淆遇到的坑与其他网元有数据交互,根据对象生成json,如果没有对整个包下禁止混淆,则json解析就会出问题,而且在项目中一般debug是不开启混淆的,导致线上版本出问题而不易察觉对于同一类的已经在混淆规则中不允许,比如继承了Activity的,但是内部类可能被混淆而导致程序崩溃在混淆规则中定义了程序某个方法不执行,因为debug未开启混淆所以debug还是
2020-06-24 20:11:41 252 1
原创 网络相关知识学习
1、网络结构物理层、数据链路层、网络层、传输层、会话层、表示层、应用层2、TCP/IP、Http、Https3、三次握手四次挥手4、Http原理、Https加密过程5、CDN原理
2020-06-23 23:09:30 190
原创 Android之AIDL
1、AIDL 是Android 接口定义语言第一步就是定义AIDL文件AIDL支持基础数据类型、String、实现了Parcelable接口的对象、可以设置双向或单向、CS模式2、Service启动3、服务端4、AIDL定义后系统生成的代码,首先我们看到服务端返回的binder生成是Stub 类,所以继承Binder就很好理解了,而Aidl是接口描述性语言自然会实现定义的接口,描述符完整类名5、既然是CS模式,我们看到C端iMyAidlInterface = IMy
2020-06-22 23:31:40 199
原创 基本数据类型
1、boolean true false2、byte 8位 -128 - 127 10000000表示负零,与00000000相同切负零没有意义所以这里指 1283、short 16位 -32768 - 327674、short 16位 0 - 655355、int 32位 -2^31 - 2^31 - 16、float 32位7、long 64位8、double 64位参考链接:https://www.cnblogs.com/oldthree3/p/9088029.html
2020-06-21 16:48:42 73
原创 编码格式与加密方法
1、编码格式ASCIIISO-8859-1GBKGB2312UTF-16UTF-82、Base643、RSA4、AES5、MD56、SHA2567、白盒加密
2020-06-21 00:31:48 340
原创 位操作
1、与运算 & 同为1时为1其余为02、或运算 | 同为0时为0其余为13、非运算 ~ 一元运算 对二进制取反4、异或运算 ^ 相同取0,不同取15、>> 右移 >>> 无符号右移6、<< 左移注意:没有无符号左移,移位的大小要在JVM的位数内,short、char会先转换为int,所以-16高位为1...
2020-06-19 20:11:39 145
原创 设计模式之行为型模式二
1、命令模式顾名思义“命令”行为是该模式的重点,调用者发送命令,然后接收者执行显然调用者要持有命令对象,根据依赖倒置原则,命令模式是一个接口,通过命令模式让接收者执行,故而命令对象要持有接收者。2、中介者模式中介这个词大家应该都熟悉,比如 房子的中介,买房、卖房者通过中介完成交易那么显然卖房与中介、买房与中介要相互持有常见的框架如MVP3、迭代器模式提供了一种遍历集合对象的接口,它将集合功能实现与遍历分离开来。比如LinkedHashMap与HashMap,前者继承了后者
2020-06-18 23:45:14 75
原创 设计模式之行为型模式一
1、模板模式实现共同的部分,不同的部分(多态的体现)抽象成方法,有子类实现,这种场景是典型的抽象类这个比较常见,比如项目中会有共同的基类。2、观察着模式分为观察者、被观察者,根据Java多态性质,对象都会对应接口或抽象类被观察者中有个集合,用来注册观察者,自然也有个删除方法。一旦触发条件执行,就会遍历集合将符合条件的方法执行如 常见的EventBus:主要是注册、发布、解绑、注册的类处理事件3、责任链模式责任链从字面上看就不难想到有个链,那么什么是链,Java中没有指针,是.
2020-06-17 23:56:08 91
原创 设计模式之结构型模式二
1、桥接模式从字面意义上就给人一种拼接、连接的感觉。这里认为是合成复用原则,比如绘图时有各种形状的图形,而每个图形又有各种颜色,如果我们不拆分那么就要生成图形 * 颜色个类,而且每新增一个 图形,就要新增颜色数量的类,这显然是不合理的。所以桥接模式就很好的解决了这个问题我们定义个颜色接口,实现需要的颜色类然后定义图形抽象类,抽象类引用颜色接口,在绘图前设置进来。这样就巧妙的解决了问题,而且新增图形就新增一个实现类即可,符合开闭原则。这里谁引用谁并没有什么限制,主要是某个模块更可能扩展。
2020-06-16 23:41:44 104
原创 设计模式之结构型模式一
1、代理模式、装饰模式这两个模式写法基本相同,在网上看到很多例子,写法上的区别就是代理直接引用了具体对象,但这样就违反了依赖倒置原则。两个模式都要继承同一个接口,所以代理模式完全也可以使用接口然后在构造或者提供set方法去设置,但是两个模式的功能是有区别的。代理模式是对接口中的方法访问控制 ,装饰模式是扩展功能。2、享元模式内部状态:不会改变的部分,保存到缓存中(比如说字符串)外部状态:会随着外界改变的部分(字体的样式)...
2020-06-15 23:40:59 109
原创 设计模式原则及应用
1、单一原则2、里氏替换原则3、依赖倒置原则4、接口隔离原则5、迪米特法则6、开闭原则1、工厂模式(简单工厂、工厂模式、抽象工厂模式)简单工厂模式工厂自然是生产产品的,假设有一个产品接口,那么 不同的实现类自然需要一个标识来区分返回具体的实现对象,简单工程就是在生成产品的地方有个switch...case分支来返回具体的产品,如果有新产品就在方法中加一个新分支,显然违反了开闭原则。那么为什么违反了开闭原则呢?因为简单工厂模式是直接用工厂的具体实例来生成产品的而且生成了多个产品
2020-06-14 18:53:24 139
原创 设计模式之单例模式
1、饿汉式定义私有静态变量并初始化静态方法返回这样就不用加锁,缺点就是只要加载了该类就初始化数据,占用资源,如果创建单例是要传参的,只能获取后再设置2、饿汉式最简单的就是静态方法加锁,性能差于是延伸出了双重检测锁来生成单例,注意变量要加volatile关键字,写法繁琐综合饿汉和懒汉有点可以在单例中定义静态内部类,内部类中有初始化好的私有静态变量单例方法中返回静态内部类中的变量即可,这样在未用到该变量时是不会加载的内存中的,但是缺点也是有的,就是传参问题...
2020-06-13 20:48:34 80
原创 异常总结
1、与Error一样继承了Throwable2、Exception分为运行时异常和受检异常RuntimeException : 空指针异常、ArithmeticException(除法运算或取模时除数为0),强转异常、数组越界运行时异常是程序内部运行时出现的异常,是程序本身的错误,不应通过捕获异常处理,良好的编程习惯遇到对象判空、除数做非0判断,强转时用instanceof,判断索引>0 && < lengthCheckException:受检异常一般是外部错
2020-06-12 23:20:21 209
原创 常用数据集合—Queue
1、实现队列的类2、阻塞式队列已经写过了,这里看下优先级队列PriorityQueue新建优先级队列对象将数据添加到队列队列的类型必须实现Comparable数据,从最底层向树的上层比较取数据,返回队列头部数据,并重新将最小(大)数据放到队列头部删除数据时...
2020-06-11 23:48:06 115
原创 常用数据集合—Map
1、实现Map的类2、数据结构数组 + 链表(红黑树)3、HashMap源码构造函数tableSizeFor决定了集合大小均是2的指数幂所有集合存储方式都是在添加元素时决定了数据结构,所以接下来看下put如果要将hash冲突用红黑树存储,数组长度小于64则要扩容,因为hash冲突严重2、节点数据结构3、get和remove就比较简单这里就省略了吧4、线程安全的Map ,HashTable、ConcurrentHashMapHa.
2020-06-10 22:00:28 394
原创 常用数据集合Set
1、Set中没有重复的数据,主要是利用对应的Map、List实现2、实现Set的类3、HashSet、LinkedHashSet、TreeSet、ArraySet、EnumSet均是利用了对应Map中Key不同原理实现4、CopyOnWriteArraySet是利用CopyOnWriteArrayList5、ConcurrentSkipListSet就是利用ConcurrentNavigableMap...
2020-06-09 23:34:36 195
原创 常用数据集合—List
1、List、Map、Set、Queue、Array2、数据结构:数组、链表3、实现List方法的类Ctrl + T(设置的是Eclipse快捷键)或右键查找4、这里就简单看下最常用的ArrayList5、构造方法一目了然6、添加数据,一条条添加或者添加集合良好的代码习惯,数组判断边界,可以确认大小的,给定初始大小(默认大小是10)获取数据:防止数组越界修改数据:删除数据:正常遍历时删除须跳出循环,否则会报错,修改方法比较常见,自行
2020-06-08 22:41:29 656
原创 多线程之阻塞式队列
1、以ArrayBlockingQueue为例将元素放入队里2、下面看下offer中的代码如果有阻塞节点就去唤醒Node节点会记录对应的线程,所以阻塞式队列中的Condition可以唤醒阻塞队列断点线程2、获取数据方法一般要当前线程阻塞时要用take如果队列为空则阻塞队列将node节点记录阻塞的线程,以便加入队列时唤醒线程...
2020-06-07 19:02:48 186
原创 多线程之加锁
常用的加锁方式1、Synchronized2、ReentrantLocktry { lock.lock();} finaly { lock.unlock();}下面看下源码,构造函数中默认是非公平锁,也可传入true变成公平锁,下面对比下非公平锁与公平锁过程2、调用lock方法可以看出非公平锁第一步是尝试更改state状态,如果更改成功则直接把当前线程赋值给独占线程,再看acquire线程以独占模式生成节...
2020-06-07 01:15:40 449
原创 多线程之Thread中的方法
1、首先创建方法时会执行run方法run就是线程运行的代码块2、start 方法让线程处于就绪状态,抢占到CPU资源后就会处于运行状态start 与 run方法对比,start让线程处于就绪状态,run是要执行的代码,那么能否直接调用run呢?答案是可以的,但是此时和一般类new出对象后调用方法没有两样,Thread.currentThread()放到run中就会发现和当前线程ID一致,调用start后打印出的线程id就会改变3、currentThread获取当前线程信息4、sleep线
2020-06-05 22:20:33 118
原创 多线程之创建线程
1、继承Thread重写run方法2、实现runnable3、线程池1、各参数解释如下,偷个懒吧,构造方法不止一个2、任务执行过程execute、submit下面看下execute源码1、判断当前线程池中核心线程数,如果核心线程数 小于定义的数量直接新建线程2、如果核心线程等于定义的线程,就放入队列3、如果队列满了,就会走else分支,创建非核心线程4、如果添加失败就执行拒绝策略5、接下来看下一个任务工作完成后线程池是...
2020-06-04 22:42:12 91
原创 多线程之volatile、synchronize
1、volatile作用:可见性、禁止指令重排序JVM内存模型:主存、工作内存、线程运行(CPU)可见性:就是在多线程情况下一个线程修改了值,其他线程能够立即看到修改使用场景:懒汉模式双重检测、线程中的标识字段(如退出循环)2、synchronize该模块下的操作变成原子操作在静态方法上加锁(.class)、在方法上加锁(this)、在代码块上加锁(获取mObject锁的线程)锁的特性:非公平锁、可重入锁锁的变化过程:无锁、偏向锁、轻量级 锁、重锁锁的位置:对象组成分
2020-06-03 19:44:41 103
原创 2020-06-02
1、px、dp、sp、ppi、bitmappx就是像素dp 基于密度的屏幕单位在160的密度上1dp = 1px1dp长度 = 1px长度 * ppi / 160F + 0.5sp在系统标准字体下 = dp,会根据系统进行缩放ppi = 高度密度值 / 高度 = 宽度密度值/宽度可以推出ppi = 宽高平方和的平方根 / 对角线长度2、不同文件夹对应的屏幕密度120 160 240 320 480 6403、bitmap的大小计算argb_8888 4字节 rgb_565 2字节 ar
2020-06-02 15:33:17 190
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人