- 博客(22)
- 收藏
- 关注
原创 Kotlin中的inline、noinline、crossinline
inline inline表示声明的函数是内联的,调用内联函数时,内联函数的函数体会被复制到调用它的地方。 fun main() { method1 { println("main") } } inline fun method1(block: ()->Unit){ block() } 以上代码的main函数调用了内联函数,经过反编译后的代码如下: public final class HelloKotlinKt { public static fin
2020-09-26 22:17:29
269
原创 ARouter执行流程分析
一.初始化 ARouter的初始化通过执行ARouter.init(Application application)完成,ARouter具体实现由_ARouter完成。 //ARouter.init public static void init(Application application) { //是否初始化 if (!hasInit) { logger = _ARouter.logger; _ARouter.logger.info(Consts.TAG
2020-08-15 00:14:30
354
原创 Dagger2的使用
一.@Inject 1.用户自定义的类在构造函数使用@Inject注解。 public class Student { @Inject public Student(){ } } 2.新建一个接口,名称一般以Activity名称加Component组成,使用@Component修饰,其中包含一个injectTo方法,表示将对象注入到某个类中。 @Component public interface Test1ActivityComponent { void injectT
2020-08-11 00:35:38
255
原创 Jetpack组件之LiveData解析
LiveData执行流程 LiveData通过observe添加观察者,方法如下: @MainThread public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) { //判断是否在主线程 assertMainThread("observe"); //判断LifecycleRegistry的状态 if (owner.getLifecycle().g
2020-08-01 09:19:08
283
原创 Jetpack组件之Lifecycle的使用与解析
一.使用方式 Lifecycle可以感知Activity和Fragment的生命周期,使用方法如下。 首先新建一个类实现LifecycleObserver接口,该接口不提供任何方法,而是依靠OnLifecycleEvent注解实现生命周期感知。 public class CustomLifeCycle implements LifecycleObserver { private String TAG; public CustomLifeCycle(String tag) {
2020-07-29 23:02:09
519
原创 App启动时的白屏优化
1.app启动方式 app启动分为冷启动和暖启动: 冷启动:当app安装后第一次启动或app被完全终止后再启动,此时,程序系统需要为app创建进程。 暖启动:app仍然在内存中,只是从后台运行转为前台运行,此时app进程已经被创建。 app冷启动到显示第一个Activity,需要进行进程创建、资源加载等操作,会耗费一定时间,为了不让用户感觉到延迟,系统在app打开时,会展示一个空白页面,使用户...
2020-01-02 23:18:15
1249
原创 OkHttp源码分析--执行流程
1.创建OkHttpClient OkHttpClient okHttpClient = new OkHttpClient.Builder().build(); OkHttp的创建采用了构建者模式,OkHttpClient.Builder()无参构造方法为 OkHttpClient的属性提供了默认值。 public Builder() { dispatcher = new Dispa...
2019-12-15 14:16:51
176
原创 Android9.0下Hook式插件化改动
1.IActivityManager 1启动Activity执行到Instrumentation的execStartActivity方法时,Android 26以下版本的代码为: public ActivityResult execStartActivity(Context who, IBinder contextThread, IBinder token, Activity target,Int...
2019-12-08 19:04:02
1338
1
原创 Activity的LoadedAPK式插件化
一.原理 ActivityThread类中有一个内部类H继承自Handler,当启动Activity时,H会发送LAUNCH_ACTIVITY消息,从而执行到H的handleMessage方法,LAUNCH_ACTIVITY事件的处理如下: case LAUNCH_ACTIVITY: { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ...
2019-12-08 18:07:00
534
原创 Activity的Hook式插件化
一.Activity启动过程 当在应用程序中调用startActivity方法进行Activity跳转时,最终会调用startActivityForResult方法: public void startActivityForResult(@RequiresPermission Intent intent, int requestCode, @Nullable Bundle ...
2019-11-30 11:59:00
245
原创 占位式插件化框架
一.原理 在插件化中,宿主是安装在手机中的正在运行的APP,插件是没有经过安装的APK文件。插件化可以实现宿主APP直接加载插件APK,使插件APK不用安装就可以运行在宿主APP中。 由于插件APK没有安装,它是没有上下文(Context)环境的,想要运行插件APK,需要把宿主的Context传递给插件APK。在占位式插件化中,当需要启动插件的Activity时,实际是创建了宿主APP中的代理Ac...
2019-11-24 10:58:00
393
原创 Android动态换肤实现
一.原理 动态换肤是将多种资源文件放在皮肤包中,皮肤包本质上就是打包成的APK文件,与静态换肤相比,动态换肤将皮肤资源分离出来单独打包,可以有效减少APP的大小。下图是APK文件的内部组成: 其中classes.dex文件中的内容对应的是Java代码,在皮肤包中这部分内容是不需要的。resources.arsc文件中的内容是资源文件,如下图所示: 每一个资源文件都有一个ID,如“0x7f040...
2019-11-24 10:47:11
1350
原创 Android静态换肤实现
静态换肤是在APP应用内部放置多套资源,进行资源的切换,静态换肤一般用在APP的日夜间模式切换中。 一.原理 当在Activity中使用setContentView加载布局时,会调用到AppCompatDelegateImpl的setContentView方法,该方法代码如下: @Override public void setContentView(int resId) { ...
2019-11-24 10:43:59
1632
原创 数据结构与算法--二叉树
二叉树遍历的非递归实现 1.前序遍历 二叉树前序遍历时,按照中、左、右的顺序遍历。非递归遍历时,新建一个栈,把头节点放入栈中,当栈不为空时,循环从栈里取节点,对于取出的每个节点,先把其右子树放入栈中,再把其左子树放入栈中。因为栈是先入后出的,后放入的左子树,就会先于右子树遍历,从而实现前序中、左、右顺序的遍历。 代码: public static void prePrint(TreeNode tr...
2019-11-24 10:36:41
197
原创 RxJava的基本使用和操作符
一.基本使用 1.链式调用 首先在build.gradle中添加依赖: implementation 'io.reactivex.rxjava2:rxandroid:2.0.1' implementation 'io.reactivex.rxjava2:rxjava:2.0.7' RxJava的使用步骤包括: 创建被观察者进行事件发送 创建观察者进行事件响应 通过订阅方法连接观察者和被观察者 ...
2019-11-10 22:47:13
223
原创 EventBus使用与源码分析
一.EventBus的使用 1.基于反射 1)非粘性事件 首先在build.gradle中加入EventBus的依赖: implementation 'org.greenrobot:eventbus:3.1.1' 定义消息事件实体类: public class MessageEvent { private String name; private int age; p...
2019-11-03 11:47:34
261
原创 数据结构与算法-栈和队列
LeetCode_20 判断括号是否合法 Given a string containing just the characters ‘(’, ‘)’, ‘{’, ‘}’, ‘[’ and ‘]’, determine if the input string is valid. Input: “()[]{}” Output: true Input: “{[]}” Output: true 新建...
2019-11-02 16:27:02
154
原创 数据结构与算法--链表
LeetCode_206:逆序一个链表 Reverse a singly linked list. Example: Input: 1->2->3->4->5->NULL Output: 5->4->3->2->1->NULL 该题目为反转一个链表,首先判断给定的链表head是否为null或者head.next是否为null,如果成立...
2019-10-27 13:27:17
203
原创 Handler原理
在Android中,耗时任务一般放在子线程中处理,而UI的更新则在主线程中进行,通常在子线程和主线程之间的切换使用Handler完成。Handler的消息机制主要包括Handler、MessageQueue、Message、Looper,四者的关系如下图所示。 MessageQueue是一个消息队列,内部使用单向链表维护消息列表,主要有两个方法:enqueueMessage用于往消息队列中插入一...
2019-10-18 21:58:18
155
原创 ThreadLocal原理与使用
ThreadLocal用于提供线程内部的局部变量,这种变量在线程间是相互独立的,通过调用ThreadLocal的set和get方法可以实现变量的存取。 基本使用: public class ThreadLocalTest { private static ThreadLocal<String> threadLocal = new ThreadLocal<String>...
2019-10-16 22:41:25
127
原创 JVM类加载机制
1.类加载器的双亲委托模型 在JVM中,类加载器使用双亲委托机制进行类加载,每一个类加载器实例都有一个与之对应的父类加载器,当类加载器需要加载类时,类加载器在加载类之前会把加载类的操作委托给父类加载器执行。类加载器的层次结构如下图所示。 虚拟机内建的类加载器称为启动类加载器(bootstrap class loader),它没有父类加载器,但可以作为其他类加载器的父类加载器。它主要加载存放在&l...
2019-09-29 00:31:53
111
原创 DataBinding使用与分析
一.使用方式 1.单向绑定一 1)首先在module的gradle中加入以下内容: dataBinding{ enabled = true } 2)新建一个实体类User,里面有两个成员变量: public class User { public ObservableField<String> name = new ObservableField<>(...
2019-09-22 23:56:26
526
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人