自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

门徒07的博客

Android 技术交流qq群 238530915,欢迎各位大牛。

  • 博客(76)
  • 资源 (1)
  • 问答 (5)
  • 收藏
  • 关注

原创 okhttp post请求 header post参数加密遇到的两个问题

Caused by: java.lang.IllegalArgumentException: Unexpected char 0x0a

2023-10-31 18:21:07 943 1

原创 网络安全https

答:分两种,一种是单向认证,像访问普通网站比如百度(https),百度网站上安装有网站证书(私钥),用户端的计算机预装有根证书(公钥),也就是签发那个百度网站证书的上级CA的证书,用来验证网站证书,这是单向认证。另一种是双向认证,客户端要验证服务器的证书,反过来服务器也要验证客户端的证书,像访问网上银行比如工行企业网银(https),网站上有证书,用户端的计算机预装有(签发网站证书的CA的)证书,此外,用户持有的U盾帮助提供用户端证书,这是双向认证。这时候中间人介入后,他只能自己造一个证书。

2023-10-24 12:39:36 1041

原创 Kotlin 知识点小结

supervisorScope 表示主从作用域,会继承父协程的上下文,它的特点就是子协程的异常不会影响父协程,内部的 子协程挂掉 不会影响外部的父协程和兄弟协程的继续运行,它就像一道防火墙,隔离了异常,保证程序健壮,但是如果外部协程挂掉还是可以取消子协程的,即 单向传播。coroutineScope 表示 协同作用域, 内部的协程 出现异常 会向外部传播,子协程未捕获的异常会向上传递给父协程, 子协程 可以挂掉外部协程 , 外部协程挂掉也会挂掉子协程,即 双向传播。

2023-10-20 12:11:49 172

原创 java.lang.IllegalAccessError: class org.jetbrains.kotlin.kapt3.base.KaptContext cannot access class

Task :app:kaptGenerateStubsDebugKotlin FAILEDe: java.lang.IllegalAccessError: class org.jetbrains.kotlin.kapt3.base.KaptContext (in unnamed module @0x4d1ecff7) cannot access class com.sun.tools.javac.util.Context (in module jdk.compiler) because module jd

2023-09-27 18:40:51 3189 2

原创 Android最好用的日志打印库(自动追踪日志代码位置)

给大家推荐一个自己写的日志打印的库,我愿称之为最强日志打印库:BytUtilLog Byt是Big一统的缩写,大一统日志打印库,哈哈!关于它的功能:它可以控制整个日志是否输出,打印的日志可以直接跳转到代码的位置,方便查看调试,同时解决输入内容一样的时候不知道是哪一处的日志的问题,自动追踪日志代码位置。也看过前辈们写的日志打印库,我对自己的库在多线程的情景下的表现,还是有担心的,如果有遇到问题,可以github或者csdn 本篇上留言都可以,看到会及时回复处理的。

2023-09-25 22:26:56 299

原创 LeakCanary 源码详解(3)

我没法理解这样的解释,我个人理解是这个算法用的是广度优先算法(因为与深度优先算法比,广度优先的长处是速度快,缺点是占用空间),从下面一层一层的查,找到最近最短的路径,这个肯定是泄漏的,是要我们处理的。如果你是直接刷到这篇的,建议还是从1开始看,然后2,然后是这篇3,如果你只关注这篇的重点hprof 文件定位泄漏位置的感兴趣,可以试试直接读这篇,如果中间没发觉有难理解的就算了,要是发觉无法理解了就建议从1 2篇读起,经典的库的代码没那么简单,不要害怕花时间。

2023-09-24 22:34:25 140

原创 Android 图片加载框架Glide源码详解

值得看的是currentGenerate是下图中3个的哪一个呢,从逻辑上看3个会依次遍历,分别是先处理过的resource缓存,然后是data缓存,最后是Source网络加载, 这也是glide的三级缓存。下面就要开始讲根据model,data找modelloader的逻辑了,做好心理准备,不简单,网上大都是一笔带过(因为他们也弄不清,的确有点复杂,绕来绕去),好不容易全网找到一篇,不知道是他的版本旧的,还是他理解的不对,珍惜吧,我认为是全篇最难的地方了。给你们看一下添加的listener。

2023-09-17 20:03:31 428

原创 Android 线程池源码详解(一)

当线程数超过核心线程数就会调用poll方法,当poll方法阻塞了keepAliveTime指定的时间后就会返回null,getTask方法返回null,线程进行销毁。I/O密集型:核心线程数=2*CPU核心数(或 核心线程数=CPU核心数/(1-阻塞系数)) 阻塞系数在0.8~0.9之间。,里面是一个双向链表实现的FIFO队列, HashSet 来管理这些work,hashset的特点无序,是基于hash表的。CPU密集型:核心线程数=CPU核心数(或 核心线程数=CPU核心数+1)

2023-09-06 21:37:51 127

原创 java锁杂谈

如在操作的数据上加上版本version属性,每次操作版本递增,在取得数据的同时获取版本属性,在操作完数据后保存前,将之前的版本号与当前的版本号进行对比,如果一致则进行更新操作,否则代表数据以被修改,重试更新操作。重量级锁是指当锁为轻量级锁的时候,另一个线程虽然是自旋,但自旋不会一直持续下去,当自旋一定次数的时候,还没有获取到锁,就会进入阻塞,该锁膨胀为重量级锁。但是需要注意的是,在使用读写锁时,需要考虑锁的粒度和性能问题,避免因为锁的过多或者过少导致程序的性能下降或者数据不一致。

2023-09-05 17:36:54 115

原创 Hashmap源码详解

接着putVal函数的逻辑走,注释里面写了逻辑,table就是前面所说的Hashmap里面的数组,item就是链表的节点Node,还有一个数组下标用 index = (n - 1) & hash 来计算的原因,因为n是table的长度,是2^N,所以 这里的(n-1)就是11111,这样的,那么(n-1)&hash就是取hash的后N位,这样的下标index一定小于2^N ,不会下标数组越界。链表:一种在物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。

2023-08-27 12:29:14 103

原创 Android类加载机制

通常我们在手机看到,app即使热修复了,最后还是要全量更新版本,因为一个是安装包热修复后变大,还有热修复之后的应用性能,稳定兼容性上还是不如整体包安装的应用。下面这个图还是比较好表达了类加载流程,但如果不看我红色画的线,就会感觉有点乱,需要注意是采用的是双亲委派模式,class加载要先一层层询问是否加载过没有就传到它的上层加载,加载不到的开始往下传,是否可以加载,最后都没能加载的not found。要说Android的类加载机制 ,就离不开 类加载器ClassLoader,它是一个抽象接口。

2023-08-22 17:57:15 752

原创 EventBus3.0源码详解

详解之前要说明一下,LivedataBus 比EventBus更适合目前jetpack化的app,因为考虑到组件的生命周期处理,性能方面,EventBus还是要反射invoke的调用的,网上找不到有实测过的博文,我想来个性能对比实测,然后写一篇博文分享给大家,想看的可以评论留言,我看看有多少人支持。好了步入正题,整个框架运用了多个设计模式:首先从Eventbus的使用入手Eventbus.getDefault()方法,使用了带volatile的双重检验的单例模式,是线程安全的。

2023-08-20 18:07:05 80

原创 LiveDataBus 其中的一个库LiveEventBus库的源码解析

那我们接着说,那整个的精华就是这个bus 的map了,key是string的 ,value是LiveEvent 的,看下图一个LiveEvent是有一个livedata来负责观察的,也就是多个消息的时候就是多个livedata,然后是bus这个map在管理。注意,我们发送消息和接收消息都是调用了get方法,也就是下面的with方法,看看,这里可是get set方法集成到一起的,就很怪,作者这里弄的,讲道理,不符合单一职责。

2023-08-16 17:40:34 164

原创 Jetpack之MutableLiveData和LiveData源码分析

接着我们着重看一下liveData的源码,先看setValue方法吧,assertMainThread是判断当前是不是主线程,如果不是就抛出异常:这就是为什么postvalue可以在任何线程调用,setPost只能在主线程调用的原因,也是这两个方法的区别。上图我们知道这两个方法都是调用了livedata的各自对应的方法,我们点进去看看livedata的这两个方法是protect 的。允许子类和自己调用,而MutableLiveData重写的时候用的是public,开放出去了。下图是它的item哦。

2023-08-15 16:21:29 189

原创 Java反射机制,动态代理,hook以及在Retrofit源码中的应用

Java的反射机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。然后我们回过头来看反射机制是 基础,动态代理里面也是用反射来实现的,动态代理对类里面的所有方法统一动态加入操作代码,java使用更多是对接口的,是生成了你想往里面塞的代码,hook把hook对象勾出来,换成自己想塞进去的,是一种手法。1.1.3使用对象.getClass() 方法,返回对象所属的类的 Class 对象。

2023-08-11 11:00:21 583

原创 Handler源码详解

Linux pipe/epoll机制,简单说就是在主线程的MessageQueue没有消息时,便阻塞在loop的queue.next()中的nativePollOnce() 方法里,这也是为什么Looper是一个死循环但没有崩溃的原因。整个看下来就是一个生产者消费者模式,还有一个细节 post(Runable)的message是 Message.obtain()获取的,这个message可以复用,所以在使用的时候尽量也用这种方式,节约资源,算是个小技巧吧。message入队列。

2023-08-02 17:19:07 165

原创 Activiity跳转startActivity源码分析Activity启动流程(下)

这样Zygote进程就会fork出一个应用进程,然后执行应用进程的入口函数也就是我们熟悉的ActivityThread.main()函数。然后是第二种情况,新启动一个App应用的Activity:调用了AMS的.startProcessLocked方法。接着会执行translacationExecutor的execute方法。然后就是application的创建和oncreate方法的调用。然后调用了 Process.start方法,开启一个进程。调用了自己的startProcess方法。

2023-08-02 11:38:38 148

原创 Activiity跳转startActivity源码分析Activity启动流程(上)

分为两种情况,一种是app已经启动,只是app内部activity跳转走 realStartActivityLocked方法,否则就拉起一个新的app,像从桌面点击一个app,就属于这种情况走的就是AMS的 startProcessLocked。6.IActivityManager 是AMS 的IBinder 实现是在AMS中,最后走的是ActivityStartControl的链式调用。3.实际还是startActivityForResult 带option的方法,只不过null传过去的。

2023-08-01 22:43:05 301

原创 Android系统启动流程

Binder方式虽然高效,但是Binder的使用看起来就像是客户端直接通过所持有的引用对象调用了服务端的方法,类似于一种强引用调用。Zygote进程负责孵化出各个子进程,其地位非常重要,出于安全性的考虑,该场景下的Zygote进程的交互采用Socket会更合适。被SystemServer进程启动的AMS会启动Launcher,Launcher启动后会将已安装应用的快捷图标显示到界面上。注意,Zygote进程与其它进程的交互方式是Socket方式,不是Binder方式,这是出于安全性上的考虑。

2023-07-28 20:26:12 189

原创 Java三大特性,设计的五大原则的理解

抽象不应该依赖细节;封装的目的是隐藏类的内部实现细节,将类的内部状态和行为进行封装,使得外部代码无法直接访问和修改类的内部数据,只能通过类提供的公有接口(也称为类的方法)进行间接访问和操作。1.封装 指的是将类的成员变量(属性)和成员方法(方法)隐藏起来,通过使用访问修饰符(如private、public、protected等)来限制外部对类的直接访问,从而保护类的内部状态和行为。3.多态 指的是父类可以引用接受不同子类的对象实例,父类调用相同的方法,由于子类对方法的实现不同,产生不同的行为。

2023-07-26 20:29:49 236

原创 Ndk c++层 crash问题分析

拿到这个文件了,可以看到上面记录的是crash .so 的地址,有两种方式处理,但也要分情况选择,如果你有设备来测试,并且知道如何去复现这个crash 那你可以用ndk-stack来直接将crash翻译成指向代码的容易理解的log,现在是指向地址的tomstone,其实这种也就不需要tomstone了,前提是你要判断出来,crash时因为c++ native层的,我就不具体解释ndk-stack怎么使用了,如果后面观众老爷留言有需要我再补吧,也是ndk带的一个工具。

2023-06-25 13:47:59 521

原创 W Failure to open libjavacore.so, try next. 华为真机崩溃问题。

原因是项目中使用了腾讯的性能监测工具Matrix Matrix 的原理是会去hook .so的库。当我把matrix的初始化去掉之后华为真机就不会崩溃了,其他的设备则不会。

2023-05-17 16:41:19 456

原创 Android源码编译FAILED: out/target/product/generic/dex_bootjars/system/framework/arm/boot.art

下面是成功的喜悦,哈哈,两年前就把源码下载好了,现在才编译通过,一定要坚持啊。WITH_DEXPREOPT=false是解决上面问题的。使用的是ubuntu 22的,android版本是9。

2023-04-21 17:42:12 1213

原创 Android webview Anr com.android.webview.chromium.WebViewChromium.onDraw(WebViewChromium.java:169

这个是日志 :1-30 10:27:38 01-30 10:27:38.601 30384 30405 W System.err: com.github.anrwatchdog.ANRError: Application Not Responding for at least 5000 ms.2023-01-30 10:27:38 01-30 10:27:38.601 30384 30405 W System.err: Caused by: com.github.anrwatchdog.ANRErr

2023-01-30 14:43:59 663

原创 Android Anr traces.txt 最全最完整说明文档

欢迎各位评论补充和指正,还有很多项还没确定含义。----- pid 461 at 2022-11-03 07:12:55 -----// pid 进程id 进程461在 2022-11-03 07:12:55的时候Cmd line: system_server//出问题的程序名称 是system_serverBuild fingerprint: ‘Android/rk3399_all/rk3399_all:7.1.2/NHG47K/server03271642:userdebug/test-keys

2022-11-11 15:44:10 854

原创 com/android/tools/idea/gradle/run/OutputBuildAction has been compiled by a more recent version of th

网上有说gradle java 版本是11 你用的是java 8 55说的是java 11 52说的是java8 让你去设置setting。我的解决方案,排除了上面两个,大概率出问题的是gradle。gradle java 版本设置的,我试过不行。还有说是Android studio 版本不对的,需要更换gradle版本,最好往新版本更新。图上是更新过后的版本,测试就没有这个问题了。

2022-11-11 15:33:59 17846 2

原创 Android 面试java知识小结

三种表示方法均有符号位和数值位两部分,符号位都是用0表示“正”,用1表示“负”,而数值位,三种表示方法各不相同 [1]。-1 转换成二进制是 1000 0001 反码是符号位不变,其他取反 1111 1110 补码是 反码加1 那就是 1111 1111了,需要提醒的是正数的原码,反码,补码,一样。在计算机中,8位带符号二进制数的取值范围是[-128, 127],所以在Java中,byte类型的取值范围也是[-128, 127]。在Java中,byte类型的数据是8位带符号的二进制数。

2022-10-10 15:24:33 674

原创 Android ObjectBox 数据库避坑Duplicate files copied in APK lib/armeabi-v7a/libobjectbox.so

传说比所有的数据库都快点Objectbox ,坑还是有的,搞了一天,官网给的文档真的坑 ,Caused by: org.gradle.api.internal.artifacts.ivyservice.DefaultLenientConfig。你要是按官网的集成,你就入坑了,我是花一天才出来,官网那样还是这个插件在前面了,这样就还会库重复。gradle编译不通过。如图这样才对,网上很多文章也是这样说的,但都少说了 第一个划线的部分。但没提到第一个划线的部分,导致很多小伙伴也进坑了。

2022-08-25 11:43:42 823 2

原创 Android动画详解

为什么要引入属性动画,上面说说的动画,是针对view,这就留下了场景的局限性,很多场景我们都是要针对数值,或者是一个对象,不局限于view。我们先看看使用 ,另外多一句,属性动画是可以代替上面我们所说的传统动画。有4种补间动画:放大缩小scale ,旋转 rotate ,平移 translate,透明度动画alpha。Android动画大方向上分为:View 视图动画(里面又分为补间动画和帧动画)和属性动画。ValueAnimator 的使用,也是可以设置listen监听,从值的变化来驱动动画。...

2022-08-17 11:51:19 265

原创 Android View 加载源码详解

表述一下:一个触摸事件触发,先来到Actvity的DispatchTouchEvent 方法,Activity接着去询问ViewGroup的dispatchTouchEnvent方法,你告诉我,ViewGroup调用onInterceptouchEvent问自己要不要拦截处理,我不拦截,好,那我问我的子view,调用view的dispachTouchEvent方法,view调用onTouchEvent()方法,到底了,开始往上反。还有个问题就是大家都不干的时候,为什么Activity 会来两边。......

2022-08-16 13:33:04 1397

原创 Android Fragment详解(一)——生命周期

第一步我们还是要先看看Fragment的生命周期,fragment 有11个生命周期,执行顺序也要知道,做了fragment的测试,如图,当fragment从无到有,变的可见的生命周期调用顺序:onAttach, onCreate,onCreateView ,onViewCreated(很多文章指这个不是生命周期), onActviityCreated,onStart, onResume。5.onActiivityCreated()方法,这是fragment的activity被创建的时候的回调。...

2022-08-11 14:23:34 940

原创 LeakCanary 源码详解(2)

接着上一篇说的源码部分,分析一下这图中核心代码的意思:moveToRetained方法然后是onObjectRetained方法它其实是在下图的代码中这里添加的这个方法又指向了scheduleRetainedObjectCheck,你也看到了接着调用了heapDumpTrigger.scheduleRetainedObjectCheck(),我们看看 heapDumpTrigger.scheduleRetainedObjectCheck(),看看断点的方法 checkRetainedObjects

2022-06-22 17:02:45 626

原创 LeakCanary 源码详解(1)

leakcanary-android-sample 使用示例leakcanary-object-watcher-android 自动注册LeakCanary 是怎么完成自动注册的,不需要添加任何初始化注入代码?是利用android系统的app的启动流程中先启动contentProvider 然后是Application的oncreate方法。所以注册代码在LeakCanary的一个contentProvider中。插播一个,如果有人遇到无法运行sample模块的,准确说是提示安装成功,但设备上不

2022-06-17 14:36:36 419

原创 Ubuntu 系统Android studio 无法启动模拟器has terminated

可以在Android studio 的help – show log in files 看一下报错原因我第一次是因为存储不够 ,那你清理啊第二次是ANDROID_AVD_HOME is defined but there is no file Pixel_5_API_28.ini in $ANDROID_AVD_HOME那就需要添加系统变量ANDROID_AVD_HOME,主要avd的路径,还有这种export命令是临时的,重启后就又不生效了。第二种,把上面的export命令写

2022-06-08 12:03:03 975

原创 ArrayList源码分析

看一下add方法,大概的意思是扩容(当然里面有需不需要扩容的判断),然后赋值就完了。核心代码是接下来的grow方法:划线的第一部分可以看出来,新容积是由旧容积加上原来的旧容积的1/2,因为是右移。第二部分是copy 旧的数组到新数组中。然后说remove方法 ,采用的是将数组的元素从index+1往前index移一位,去覆盖index上的元素。待续。。。...

2022-06-06 13:57:42 80

原创 Arouter源码解析(三)——Javapoet 生成文件的位置

从Arouter的源码中我一直有一个疑问:module-java里面的Javapoet生成的代码的位置和我自己的测试项目的不同。看下面的图:图一是Arouter的图二是我自己的demo看到kapt底时候也这样推断过这其实是kotlin和java分开了,但我测试了demo,分别用java和kotlin的activity做测试,结果都在kapt下面:所以总觉得不对。后来我发现在Arouter 的module-kotlin模块和我是一致的,下图所示这就印证了,还是把kotlin和java分开的猜想,但当

2022-06-01 16:33:17 385

原创 Arouter源码解析(二)——ASM和JavaPoet

Arouter 在不使用gradle插件的情况下,是使用Apt+JavaPoet 来处理,其中调用java文件里面的方法则是用了反射的技术。这应该也是初始化时间长的问题:apt的autoService 对Animation注解 使用JavaPoet生成新的Java文件,然后反射调用LoadintoJavaPoet是生成java文件的工具,而ASM 是字节码插桩技术,是直接处理.class 文件的,不是生成新文件,是在已有的文件中插入代码看一下官方对于使用gradle插件的解释:接着我们看看grad

2022-05-30 17:52:30 450

原创 Arouter 源码解析(一)

一.Arouter 的结构

2022-05-23 16:08:59 250

原创 Android 执行 ping ip 命令是否通的代码

网上有的说 是android 但命令是windows 的,ping的命令 windows 和linux 以及android 的参数含义会稍有不同,而恰巧会影响这个判断:先看网上的第一种写法:有几个问题, -n 次数 -w deadline时长, linux 中次数用的是 -c ,android 中 参数在前,ip在后面 。所以经过摸索,我修改了一版。如下这样还不行,in读取的是null的然后我在网上搜到了这样的版本:他这个也有问题,划线的两个问题, ping命令 android

2022-05-16 10:57:50 974

原创 Android IPC Binder机制的一次拷贝理解

IPC全称为Inter-Process Communication 进程间通讯 ,android的底层是linux,但是linux ipc却没有binder这种方式 ,我们先讨论linux的进程间的通讯方式还有Android没有选择其中一种的原因:1.socket 不安全可以中途篡改,性能问题 ,网络通信的socket的性能你应该有了解,它的机制决定了它的性能 2. 管道 是一对一的,进程间的多对多的关系,每一个进程提供服务server给所有的client使用,每个进程也都可以是...

2022-04-25 13:40:43 3012

Android ViewPager 平滑过渡实现手动循环和自动循环

Android ViewPager 平滑过渡实现手动循环和自动循环,实现原理是设置最大值,不断+1,%图片的个数实现所谓的循环。虽然不是真正的无限循环(因为到理论的最大值时就会停止),但是足够用的了。效果比网上的真正无限循环要好,过渡很平滑,用二维数组做了缓存,算法很巧妙。

2016-02-04

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

TA关注的人

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