- 博客(266)
- 收藏
- 关注
原创 某通信巨头Android一面备忘
【面试官的宝典】小程序Kotlin章节有介绍。(这道题很基础但是没有去总结过很难回答全面)异步消息可以采用内存屏障保障优先级。
2025-04-03 17:51:26
144
原创 某Ai上市公司Android岗现场一面
(JVM)中,堆内存分为新生代(Young Generation)和老年代(Old Generation)。随着应用程序的运行,老年代的数据会越来越多,可能导致频繁的全局垃圾回收(Full GC),影响应用程序的性能。解决这个问题需要采取一系列措施。
2025-04-02 20:10:39
338
原创 上海某海外视频平台Android高级工程师视频一面
答:如果客户端不随机产生一个密钥,拿到公钥就可以直接破解发送的数据了。面试官又问了一个很好的问题:为什么客户端还要产生一个密钥?小程序【面试官的宝典】里面Android基础部分有讲到。都是对象锁,没什么本质的不同。
2025-04-01 18:46:29
322
原创 Android 导出CSV文件乱码问题处理
最近有一个需求,需要在Android端导出CSV文件,自测是用的WPS,没啥问题。可到了测试那边,用Excel直接打开就是乱码,需要在Excel数据里面用【从文件/CSV】打开。这样就显示非常的不方便。解决方案:使用UTF-8 BOM。
2025-01-16 13:45:23
365
原创 Android Studio历史版本下载
最新的版本默认已经开始使用compose,Gradle的默认语言也发生了变化,但是实际工作中其实大家的使用习惯还没有跟上。
2024-10-27 04:37:33
971
原创 leetcode 72-编辑距离
长度为i的word1的index是i-1,长度为j的word2的index是j-1。如果在这个index上字符一样的话,就是不需要操作的意思:dp[i][j] = dp[i - 1][j - 1]。最后一种情况不是很好理解,这里重点说明以下:简单来说,我们在word1增加一个字符,这个字符肯定是word2的字符。然后这个字符我们就不需要考虑了。dp[i][j]表示长度为i的word1转换为长度为j的word2最小编辑次数。这道题如果不用动态规划去解决,将是一个极其复杂的问题。
2023-07-25 18:00:08
264
原创 Android 11以下DialogFragment里弹出PopWindow显示问题
最近在写UI的时候发现一个非常有意思的事情,Android 11以下在DialogFragment里面弹出PopWindow,最终会被截取。应该是Android 11后这里默认设置成了true。
2023-07-19 17:26:43
1108
原创 Android无线调试
同学们应该都知道USB调试,但是有时候我们需要通过USB传输数据的时候,USB会被占用,这个时候我们该如何调试呢?这个时候就可以断开USB,愉快的使用无线调试了。这个时候我们就需要用到无线调试。
2023-04-03 18:01:50
378
原创 ViewBinding基类封装的正确打开方式
我们在日常开发中,为了避免findViewById这种低效的代码编写,可以基于ViewBinding库封装基类。但是网上很多是不正确的,今天就贴出正确的打开方式。Boolean对于java来说并不是基本数据类型,对于Kotlin才是基本数据类型。特别注意不要写成这样!
2023-01-05 17:30:23
572
原创 谈一谈Android适配(从蓝湖切图模糊问题说开去)
最近在新的项目画UI的时候,从蓝湖导出切图后,发现显示很模糊。最后发现是蓝湖设置问题,没有正确计算不同dpi目录下的图片像素值。适配问题看起来很简单,但是很多细节却很容易被忽略,而且网上也有一些文章讲解的并不准确。意思是屏幕纵向上有1920个像素,横向上有1080个像素。一个5英寸屏幕的手机,分辨率是1920*1080。这样计算得到的是实际dpi,但是Android适配用的是系统dpi。如果对应文件夹下的图标小太多,就会导致图片模糊问题,一定要注意。屏幕尺寸的单位是inch(英寸),是指对角线的尺寸。
2022-11-15 20:33:43
2431
原创 宏银信息Android视频面试复盘
【1】DVM中的应用每次运行时,字节码都需要通过JIT编译器编译为机器码,这样会使应用程序的运行效率降低。而在ART中,系统安装应用程序时会进行一次AOT,将字节码预编译成机器码并存储在本地,这样应用程序每次运行时就不需要执行编译了,会大大增加效率。但是AOT不是完美的,它的缺点主要有两个:第一个是AOT会使安装应用的时间变长,尤其是复杂的应用。应用程序安装时并不会将字节码全部编译成机器码,而是在系统运行中将热点代码编译成机器码,从而缩短应用程序安装时间,并且节省内存。
2022-10-20 22:50:27
2
原创 Android应用程序进程启动流程
有一点需要注意:本文讲的是应用程序进程的启动流程不是应用程序启动流程,应用程序启动流程(根activity启动流程)后面会有专门文章讲解。
2022-10-10 17:45:40
1549
原创 Android系统启动(下篇)
路径:frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java。路径:frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java。路径:frameworks/base/core/java/com/android/internal/os/ZygoteInit.java。
2022-10-10 15:11:52
1510
原创 Android系统启动(上篇)
前面我准备开始讲性能优化,讲到一半发现根本讲不下去。性能优化是基于对Framework深入理解的基础上的应用,如果对Framework没有深入的理解的话,又怎么能去很好的去做性能优化呢?所以,我调整了一下顺序。先讲清楚Framework这一块,然后再去补充性能优化专题。我们也是从开机到应用程序画面显示在我们面前这一流程开始。
2022-10-09 22:48:12
2144
原创 Android性能优化之【启动优化】
我们都知道,现在的App已经由增量阶段转化为存量阶段。所以做好一款App是比做出一款App更重要的事情,这也是我写性能优化这个专栏的初衷。我先大概讲一下性能优化我准备讲那几块,大家都知道性能优化的方向有很多,不可能都去讲解。删繁就简就显得尤为重要,大家不管是看源码还是学技术,学到核心才是最关键的,这也是我最近一段时间才逐渐领悟到的。文章更新的顺序也会按这个顺序来,我个人感觉性能优化掌握这几块通用的基本差不太多,如果后面有从事性能优化专项工作的同学可以在这个基础上深入。
2022-09-26 22:47:50
944
原创 EventBus 一篇文章就够了
我们知道Android开发早期各种Activity之间,Fragment之间,Activity和Fragment之间传递数据显得不是那么的友好。EventBus的出现大大提高了组件之间的数据传递效率,大大降低了接口回调传递数据所带来的代码耦合。EventBus很小巧,运行效率高,因此早期被大量运用在各种项目中。早年我写过一篇关于EventBus的文章,基本上把原理也讲的差不多了,今天再次捡起来做一个总结。
2022-09-19 22:02:54
600
原创 Retrofit原理 一篇文章就够了
我们知道Retrofit是基于OkHttp的一层封装,Retrofit本身不负责网络请求,而是将请求交给OkHttp处理。我们知道,Retrofit的请求是写在一个个接口里面的,这样同样baseUrl的请求就可以写在一个接口里面,非常方便拓展和管理。而且直接将数据解析到javaBean,并且自动切换线程。这样就有效的解决了OkHttp的使用问题。我们网络访问已经有了OkHttp,那为什么还需要一个Retrofit呢?上图是对Retrofit职责的一个很好的描述。
2022-09-15 23:21:04
598
原创 OkHttp原理 一篇文章就够了
我们学习技术的时候,一开始是会用,进阶就是深入理解其原理,然而各路框架源码,系统源码又极为庞大,我们就必须知道如何去领会其中的核心思想。今天我们就一起来理一理OkHttp的核心源码,做到知其然知其所以然!一开始我们需要初始化OkHttpClient,这里使用的是一个无参构...这篇两年前的文章我仔细看了一下,基本上调度器这一块已经讲的很透彻了,今天就不再浪费时间去讲调度器相关知识了。那么今天接着重点讲一下拦截器,我看以前的文章里面一笔带过了,估计当时我也不太理解。
2022-09-07 22:38:49
611
原创 databinding 一篇文章就够了
关于IDE自动转databinding布局的说明:将鼠标停在最外层的constraintLayout的布局的里面的空闲位置,然后同时按option+enter(Mac),就会出现convert to data binding layout提示。name是名称,可以随便写,一般最好与bean一致,type就是具体定义的类型。@{user.***}实现了数据的引用。注意,原有的设置布局的方式要换成通过DataBindingUtil的方式。运行一把:这样就完成了最基本的databinding的使用了。
2022-09-01 23:25:35
746
原创 LiveData粘性事件原理解析
有些同学可能有这样的疑惑:第二个activity还没有创建(还没有observe),为啥在第二个activity还能监听到livaData的数据变化?注释1处:将SecondActivity对象和Observer对象封装到LifecycleBoundObserver对象里面去;注释2处:将Observer对象作为键,LifecycleBoundObserver对象作为值放到mObservers里面去;大家觉得SecondActivity的吐司会不会弹呢?注释3处:将wrapper和owner生命周期绑定。
2022-08-20 10:05:12
477
原创 LiveData 一篇文章就够了
通过runnable方法通过Handler在主线程执行,最后也是调用了setValue。注意注释1处,看下mDelegate为何物?注意:子线程要用postValue。使用是不是非常的简单!
2022-08-17 23:43:56
205
原创 谈谈WorkManager线程池的设计
activity里面先构建data,然后通过setInputData传入data,最后woker里面从params里面接收data。注意:这个doWork方法是异步的,后面分析源码时会讲到。我不知道大家在看WorkManager源码的时候有没有这样一个疑惑,就是一个线程池里面执行一个Runnable,然后这个Runnable里面好像又有一个线程池执行Runnable,这样不就是线程里面套线程了吗?很显然,Google是不可能犯这样低级的错误的,那么我们就一起来看下这个线程池倒计时怎么设计的吧!...
2022-08-14 16:44:25
326
原创 WorkManager 一篇文章就够了
activity里面先构建data,然后通过setInputData传入data,最后woker里面从params里面接收data。既然activity可以向worker里面发送data,那么woker里面该如何回传data呢?我们工程中一定会有大量activity和WorkManager传递参数的场景,那么该如何传递参数呢?很明显,WorkManager里面又封装了LiveData,是通过LiveData监听数据返回的。注意:这个doWork方法是异步的,后面分析源码时会讲到。......
2022-08-13 16:55:39
1377
原创 Glide缓存核心原理详解
我们的APP中想要加载某张图片时,先去LruCache中寻找图片,如果LruCache中有,则直接取出来使用,并将该图片放入WeakReference中,如果LruCache中没有,则去WeakReference中寻找,如果WeakReference中有,则从WeakReference中取出图片使用,如果WeakReference中也没有图片,则从磁盘缓存/网络中加载图片。最近最少使用算法,设定一个缓存大小,当缓存达到这个大小之后,会将最老的数据移除,避免图片占用内存过大导致OOM。...
2022-08-09 23:38:05
1087
原创 Glide监听Activity生命周期源码分析
我们来理一理:Glide.with()里面传入一个activity,with方法里面先通过单例获取一个RequestManagerRetriever对象,然后通过这个对象的get方法获取一个RequestManager对象。将Set转化成集合,其实目前的使用来看这个集合就一个对象,就是RequestManager对象。先来通过Tag找这个Fragment,如果没找到,再去pending~里面找(HashMap),如果还没有找到,就创建一个对象,然后加到activity里面。很明显,这是一个单例。...
2022-08-07 22:41:16
191
原创 你所不知道的WMS
如果有不理解的同学,可以看看我的Framework专栏的其他文章,这里默认大家都是有这方面基础的了。打开我的sublimeText,搜索invalidate(),出来很多东西,然后右击,Gotodefinition。首先我们来看一下invalidate的英文是什么意思,一开始可能大家都会去猜这应该是刷新的意思,但是实际却是废弃的意思。我们知道activity是通过window来管理view的,activity是管理生命周期的,view负责具体显示。这个方法代码非常长,是不是似曾相识了!...
2022-07-26 23:29:40
395
原创 深入理解Java Binder
如果对AIDL有不理解的,可以先看看这一篇文章再探AIDL_AD钙奶-lalala的博客-优快云博客我们还是延续前面一篇文章的例子来讲解,我们创建的AIDL文件如下然后Build->MakeProject,会自动在build->generated-注释1和注释2处将Java的Parcel对象转换为Native的Parcel对象,注释3处从BinderProxy获取mObject,也就是BpBinder,注释4处调用BpBinder的transact方法。...
2022-07-25 23:29:58
1017
原创 深入理解Native Binder
我在前面的一篇文章中已经对Binder有一个概述,下面就开始来深入研究Binder吧。上一篇文章链接:听宇哥讲Binder(Binder核心原理最全解析)_AD钙奶-lalala的博客-优快云博客前面写了一篇关于AIDL的文章,那我们就从AIDL谈起吧。如果对AIDL有不理解的,可以先看看这一篇文章:再探AIDL_AD钙奶-lalala的博客-优快云博客我们还是延续前面一篇文章的例子来讲解,我们创建的AIDL文件如下:然后Build->Make Project,会自动在build->generated-
2022-07-10 23:20:40
574
原创 听宇哥讲Binder(Binder核心原理最全解析)
前面写了一篇关于AIDL的文章,那我们就从AIDL谈起吧。如果对AIDL有不理解的,可以先看看这一篇文章:再探AIDL_AD钙奶-lalala的博客-优快云博客我们还是延续前面一篇文章的例子来讲解,我们创建的AIDL文件如下:然后Build->Make Project,会自动在build->generated->aidl_source_output_dir里面生成固定格式的文件。想了解Binder的原理,就先来了解一下AIDL吧。生成的文件如下:这段生成的代码比较长,我们来拆解分析......
2022-07-05 23:50:26
859
原创 再探Handler(下)(Handler核心原理最全解析)
我们都知道可以在主线程直接创建Handler,那么问题来了:我们可以在子线程创建一个Handler吗?如何去做呢?方式1:这种方式肯定是可以实现主线程到子线程的通信的,但是这种方式很不友好。首先我们不确定handler对象何时创建好,第二个这个handler只能用在一个地方。那我们就应该思考如何去改进。系统其实给我们提供了一个类HandlerThread,我们可以参考这个类来优化我们的代码。方式2:我们来思考一下,这个类为什么要这样设计?首先我们要明白notifyAll()和wait()必须要都
2022-06-23 23:42:26
696
原创 再探Handler(上)(Handler核心原理最全解析)
很久之前也写过Handler的相关文章,现在回过头去看,理解的还是较为浅薄。于是乎,决定再来深入研究一遍Handler。首先抛出一个问题:子线程到主线程的通信方式有哪些?子线程到主线程通信的原理是什么?你可能会回答:RxJava,Handler,EventBus,广播。但是这些表象背后的本质都是一套机制,就是Handler。可以这么说,Android线程间通信的核心就是Handler。首先我们来看Handler的使用,具体的我就不说的,大家想必都很清楚:子线程:handler.sendMessage()主线
2022-06-22 03:18:54
336
原创 Kotlin协程核心原理终极理解
我们先来看一段代码,就拿最常见的网络请求为例子:首先问大家一个问题:标记1和标记2分别执行在哪个线程里面?我们来查看viewModelScope源码:注意Dispatchers.Main,可见通过viewModelScope启动的协程是运行在Android主线程上的。所以标记1和标记2都是运行在主线程里面的。我们再来看uploadFile这个函数:我们使用了Retrofit请求,这又是一个suspend函数。那么第二个问题来了:suspend有什么用?suspend能够触发挂起吗?然
2022-06-15 23:51:37
1042
1
原创 Linux虚拟内存和物理内存
最近一直在研究Binder机制,但是Binder机制对一些初学者来说并不是很友好。我分析了一下原因,很多人最基本的问题都没有搞清楚。都知道Binder通信只需要拷贝一次数据,然后又是通过内存映射实现的。那么问题来了,什么是内存映射?大概率很多人都不清楚,知其然而不知其所以然。今天,就带你彻底了解内存映射背后的原理。现代操作系统是有虚拟内存和物理内存的概念区分的,但是并不是一开始就有。比如在80年代,那个时候程序是会被全部加载进内存的,所以只有物理内存的概念。但是只有物理内存很明显有很多弊端,比如说每一个
2022-05-02 19:33:18
777
原创 再探AIDL
我记得我前几年写过关于AIDL的文章,但是现在看起来这个文章很有问题。AIDL本质上是要解决IPC的问题,而以前的文章并没有很好的体现这一点。最近也在重新从更深的角度去学习IPC机制,所以决定再探AIDL。IPC,全称Inner-Process Communication。我们一般称为进程间通信。首先,第一步是要解决的是AS如何生成一个AIDL文件?我们按以下步骤操作:我们首先定义一个AIDL接口,鼠标选中main,直接new->AIDL->AIDL File。我们在生成的接口里
2022-04-29 22:01:43
588
原创 Android arr依赖以及ModuleVersionNotFoundException问题解决
第一种情况,我们需要在ModuleA引入arr文件,步骤很简单:首先将arr文件放在ModuleA的libs目录下ModuleA添加api依赖dependencies { ··· api(name: '***', ext: 'aar') ···}android { compileSdkVersion 28 buildToolsVersion "28.0.3" ··· repositories { flatDir {
2022-04-13 05:00:17
2457
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人