自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(22)
  • 收藏
  • 关注

原创 Kotlin中的inline、noinline、crossinline

inlineinline表示声明的函数是内联的,调用内联函数时,内联函数的函数体会被复制到调用它的地方。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 241

原创 ARouter执行流程分析

一.初始化ARouter的初始化通过执行ARouter.init(Application application)完成,ARouter具体实现由_ARouter完成。//ARouter.initpublic static void init(Application application) { //是否初始化 if (!hasInit) { logger = _ARouter.logger; _ARouter.logger.info(Consts.TAG

2020-08-15 00:14:30 325

原创 Dagger2的使用

一.@Inject1.用户自定义的类在构造函数使用@Inject注解。public class Student { @Inject public Student(){ }}2.新建一个接口,名称一般以Activity名称加Component组成,使用@Component修饰,其中包含一个injectTo方法,表示将对象注入到某个类中。@Componentpublic interface Test1ActivityComponent { void injectT

2020-08-11 00:35:38 202

原创 Jetpack组件之LiveData解析

LiveData执行流程LiveData通过observe添加观察者,方法如下:@MainThreadpublic void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) { //判断是否在主线程 assertMainThread("observe"); //判断LifecycleRegistry的状态 if (owner.getLifecycle().g

2020-08-01 09:19:08 253

原创 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 494

原创 App启动时的白屏优化

1.app启动方式app启动分为冷启动和暖启动:冷启动:当app安装后第一次启动或app被完全终止后再启动,此时,程序系统需要为app创建进程。暖启动:app仍然在内存中,只是从后台运行转为前台运行,此时app进程已经被创建。app冷启动到显示第一个Activity,需要进行进程创建、资源加载等操作,会耗费一定时间,为了不让用户感觉到延迟,系统在app打开时,会展示一个空白页面,使用户...

2020-01-02 23:18:15 1079

原创 OkHttp源码分析--执行流程

1.创建OkHttpClientOkHttpClient okHttpClient = new OkHttpClient.Builder().build();OkHttp的创建采用了构建者模式,OkHttpClient.Builder()无参构造方法为 OkHttpClient的属性提供了默认值。public Builder() { dispatcher = new Dispa...

2019-12-15 14:16:51 160

原创 Android9.0下Hook式插件化改动

1.IActivityManager1启动Activity执行到Instrumentation的execStartActivity方法时,Android 26以下版本的代码为:public ActivityResult execStartActivity(Context who, IBinder contextThread, IBinder token, Activity target,Int...

2019-12-08 19:04:02 1308 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 499

原创 Activity的Hook式插件化

一.Activity启动过程当在应用程序中调用startActivity方法进行Activity跳转时,最终会调用startActivityForResult方法:public void startActivityForResult(@RequiresPermission Intent intent, int requestCode, @Nullable Bundle ...

2019-11-30 11:59:00 223

原创 占位式插件化框架

一.原理在插件化中,宿主是安装在手机中的正在运行的APP,插件是没有经过安装的APK文件。插件化可以实现宿主APP直接加载插件APK,使插件APK不用安装就可以运行在宿主APP中。由于插件APK没有安装,它是没有上下文(Context)环境的,想要运行插件APK,需要把宿主的Context传递给插件APK。在占位式插件化中,当需要启动插件的Activity时,实际是创建了宿主APP中的代理Ac...

2019-11-24 10:58:00 377

原创 Android动态换肤实现

一.原理动态换肤是将多种资源文件放在皮肤包中,皮肤包本质上就是打包成的APK文件,与静态换肤相比,动态换肤将皮肤资源分离出来单独打包,可以有效减少APP的大小。下图是APK文件的内部组成:其中classes.dex文件中的内容对应的是Java代码,在皮肤包中这部分内容是不需要的。resources.arsc文件中的内容是资源文件,如下图所示:每一个资源文件都有一个ID,如“0x7f040...

2019-11-24 10:47:11 1310

原创 Android静态换肤实现

静态换肤是在APP应用内部放置多套资源,进行资源的切换,静态换肤一般用在APP的日夜间模式切换中。一.原理当在Activity中使用setContentView加载布局时,会调用到AppCompatDelegateImpl的setContentView方法,该方法代码如下: @Override public void setContentView(int resId) { ...

2019-11-24 10:43:59 1567

原创 数据结构与算法--二叉树

二叉树遍历的非递归实现1.前序遍历二叉树前序遍历时,按照中、左、右的顺序遍历。非递归遍历时,新建一个栈,把头节点放入栈中,当栈不为空时,循环从栈里取节点,对于取出的每个节点,先把其右子树放入栈中,再把其左子树放入栈中。因为栈是先入后出的,后放入的左子树,就会先于右子树遍历,从而实现前序中、左、右顺序的遍历。代码:public static void prePrint(TreeNode tr...

2019-11-24 10:36:41 168

原创 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 205

原创 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 229

原创 数据结构与算法-栈和队列

LeetCode_20 判断括号是否合法Given a string containing just the characters ‘(’, ‘)’, ‘{’, ‘}’, ‘[’ and ‘]’, determine if the input string is valid.Input: “()[]{}”Output: trueInput: “{[]}”Output: true新建...

2019-11-02 16:27:02 137

原创 数据结构与算法--链表

LeetCode_206:逆序一个链表Reverse a singly linked list.Example:Input: 1->2->3->4->5->NULLOutput: 5->4->3->2->1->NULL该题目为反转一个链表,首先判断给定的链表head是否为null或者head.next是否为null,如果成立...

2019-10-27 13:27:17 181

原创 Handler原理

在Android中,耗时任务一般放在子线程中处理,而UI的更新则在主线程中进行,通常在子线程和主线程之间的切换使用Handler完成。Handler的消息机制主要包括Handler、MessageQueue、Message、Looper,四者的关系如下图所示。MessageQueue是一个消息队列,内部使用单向链表维护消息列表,主要有两个方法:enqueueMessage用于往消息队列中插入一...

2019-10-18 21:58:18 128

原创 ThreadLocal原理与使用

ThreadLocal用于提供线程内部的局部变量,这种变量在线程间是相互独立的,通过调用ThreadLocal的set和get方法可以实现变量的存取。基本使用:public class ThreadLocalTest { private static ThreadLocal<String> threadLocal = new ThreadLocal<String&gt...

2019-10-16 22:41:25 105

原创 JVM类加载机制

1.类加载器的双亲委托模型在JVM中,类加载器使用双亲委托机制进行类加载,每一个类加载器实例都有一个与之对应的父类加载器,当类加载器需要加载类时,类加载器在加载类之前会把加载类的操作委托给父类加载器执行。类加载器的层次结构如下图所示。虚拟机内建的类加载器称为启动类加载器(bootstrap class loader),它没有父类加载器,但可以作为其他类加载器的父类加载器。它主要加载存放在&l...

2019-09-29 00:31:53 92

原创 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 501

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除