- 博客(86)
- 收藏
- 关注
原创 【Android性能】Systrace分析
可通过android sdk中自带的systrace抓取,路径一般如下,..\AppData\Local\Android\Sdk\platform-tools,切至python2.7,run,随后进行相关操作,操作完毕后按回车即可获取trace文件,找到run_systrace.py中parse_options方法,对应代码块。此次以Settings冷启动为例,找到com.android.settings。随后trace_files下出现一个ctrace文件,再通过。怎么分析不是本文重点,
2025-03-18 14:43:09
468
原创 【Java】StampedLock浅谈
在多读少写的环境,相比于ReadWriteLoock,StampedLock性能更胜一筹。试着想一下,如果使用ReadWriteLoock,当1万个读请求过来时,写的操作插入,就会被阻塞。但StampedLock不会,后者不基于AQS实现,它采用乐观锁的思维。所谓的乐观,即读取的时候,不会阻塞当前线程,相应会返回一个邮票,state。读取完毕后,只要验证手上的邮票判断数据是否变化即可,随后决定去重新读取数据。本文笔者简单讲下StampedLock的实现思路,以供参考。
2025-02-27 14:47:31
579
原创 【Java】ReadWriteLock浅谈
在多读少写的场景下,可以使用读写锁优化性能。读写锁本质是一种共享锁,即,如果ReadLock获取锁成功,只会阻塞WriteLock锁的获取,不会阻塞其它线程ReadLock锁的获取。
2025-02-26 16:06:06
515
原创 【Android性能】内存泄漏分析策略
Android系统应用+Framework层基于Java进行开发,其无用的对象依赖GC机制回收,如果一个对象被持久对象引用,则不会被GC,导致应用内存持续上涨,直到发生OOM异常。本文,笔者根据自身经验,梳理一些常见的内存泄漏点,以及解决方案。Java采用了多种垃圾收集算法,具体使用的算法可能会根据JVM的实现和配置而有所不同。标记-清除算法(Mark-Sweep):复制算法(Copying):标记-整理算法(Mark-Compact):分代收集算法(Generational Collection):被GC
2025-02-25 11:52:05
672
原创 Android Vsync从何而来
但USE_VSYNC现为true时,信号就直接来自底层,因此,doFrame方法实际在FrameDisplayEventReceiver#onVsync中被调用。DisplayEventReceiver通过nativeInit方法注册receiver。以上,USE_VSYNC为false,android上层计算时间。简单记录一下ChoreographerdoFrame执行时机。从实际堆栈进一步可确认。
2024-12-06 11:12:13
151
原创 【Android】android compat理解
即便是在同一手机上安装的不同apk,其编译的apk不同,也会导致行为上的差异。如SDK34有限制后台启动,但如果安装的apk所依赖的sdk是33,则不会表现出此差异。这是如何实现的呢?其实,本质是依赖系统端的compat config逻辑。简单说,系统会根据客户端的sdk值,判断是否启用某feature,来达到向后兼容的手段。核心实现在/下面。
2024-11-22 14:01:19
691
原创 ForkJoinPool浅析
相比传统的线程池ExecuteService,ForkJoinPool的优势在于能采用分治算法、工作窃取算法高效利用CPU资源,如下图Fork即拆分,Join即合并,通过将大任务拆分成多个小任务,在多个线程中执行后,合并结果即可得到大任务的结果,经典的例子有归并排序、超大数组求和等。ForkJoinPool主要mode如下:ForkJoinPool:ForkJoin线程池。ForkJoinThread:特殊线程池。
2024-06-28 17:02:44
363
原创 线程池FutureTask浅谈
FuturnTask实现了Future与Runnable接口,笔者知道,ThreadPoolExecutor#submit可以传入Callable接口而非Runnable,区别点在于Callable可以返回值,而整个FuturnTask可以理解为Callable设计,用来优雅地异步获取执行结果,无需手动Condition去实现。围绕此,需知道Future接口及其方法的定义,
2024-06-27 15:59:21
773
原创 androidx.preference框架介绍
Preference作为setting核心框架,笔者对此框架做一个简单的解析,androidx.preference本质是对设置领域提供了一层View封装,以android view本身的策略模式进行二次开发,将常用的一些设置样式封装到不同的Preference中,以达到快速开发设置相关功能。并且,此风格与原生setting保持了一致,给用户提供了一致性体验。
2024-06-25 10:20:21
1153
原创 Android Activity因配置改变重建,ViewModel#onClear方法为什么不被调用?
注意到切换语言或字体大小改变时,Activity会发生重建,但对应的ViewModel却不会被clear,甚至在重建的Activity,通过new ViewModelProvider(this).get(ViewModel.class)也是上一个Activity的实例,为什么呢?上述问题发生的条件是当前Activity需要是ComponentActivity的子类。
2024-05-13 10:46:48
566
1
原创 线程池原理简谈
线程池是一种池化技术,本质是减少线程对象创建销毁的开销,同对象池、连接池一样,达到对象复用的效果。那么线程池怎么复用呢?即一个或多个Thread对象怎么执行更多的Task?这里面的关键就涉及到了阻塞队列。其一,所谓阻塞队列,是借助锁实现的生产-消费模型,以BlockLinkedList为例,其taskFirst方法,通过notEmpy,即Condition实现阻塞等待功能,而Condition内部使用了AQS来实现锁的功能,详情可见。
2024-05-11 14:58:37
892
1
原创 写个Android事件分发实际用例(持续更新)
感兴趣的读者,如果对Android事件分发还有不了解的地方,可以阅读笔者写的文章。本文的主要目的,是结合前文所分享事件分发相关原理,在实际案例中使用。
2024-02-01 10:24:33
893
原创 Glide完全解读
glide作为android流行的图片加载框架,笔者认为有必要对此完全解读。glide提供了缓存功能、生命周期结束后自动移除缓存、自动适配ImageView,以及提供了各种对图片修饰的操作,如剪裁等。glide提供了多级缓存,有内存缓存、活动缓存、LRUCache等。
2024-01-29 12:09:24
1705
原创 OkHttp完全解读
OkHttp作为android非常流行的网络框架,笔者认为有必要剖析此框架实现原理,抽取并理解此框架优秀的设计模式。OkHttp有几个重要的作用,如桥接、缓存、连接复用等,本文笔者将从使用触发,解读源码,剖析此功能的实现原理。最后阅读完源码后总结出如下结论,OkHttp是一款优秀的网络请求框架,内部采用优雅的责任链模式、构造模式、桥接模式、享元模式、门面模式等设计模式,符合依赖导致原则、里氏替换原则等面向对象原则,将复杂的网络请求封装从简单的调用,属实优雅。
2024-01-28 14:36:04
1611
原创 Android Handler完全解读
Handler在Android中比较基础,本文笔者将对此机制做一个完全解读。读者可简单参考上述类图与时序图,便于后续理解。
2024-01-27 15:57:04
1320
原创 RecyclerView完全解读
RecyclerView的核心是缓存复用,因此必须搞清楚Recycker的几个缓存池。笔者根据其注释,知mAttachedScrp是仍附着在RecyclerView的ViewHolder,但已经不可见。mChangedScrap也仍附着在RecyclerView中,但可见,不过位置发生了改变,需先标记至此缓存池。mCacheViews中的ViewHolder已经从RecyclerView移除。而mRecyclerPool可以理解为最后一层缓存。DEFAULT_CACHE_SIZE默认大小为2。
2024-01-26 23:45:51
1169
原创 再谈Android View绘制流程
笔者在这里提醒读者,Android的View是UI的高级抽象,我们平时使用的XML文件也好,本质是设计模式中的一种策略模式,其View可以理解为一种底层UI显示的Request。各种VIew的排布,来自于开发者编写的XML文件,或动态增添删除View,这一系列的集合即一种策略。而这种策略最终会被Android系统解析为一种Request请求。什么意思呢?就是应用进程在此充当绘制的客户端,而服务器是谁?记住,即便屏幕前是我们所描绘的某种策略绘制的UI,那也是Surface系统服务器的Response表现。
2024-01-26 11:19:16
1263
原创 再谈android事件分发机制
笔者知道,android事件起源于屏幕触控,随后出发传感器,内核层经过计算,得出触控坐标,这时候事件传至WMS,WMS计算出屏幕坐标上有效应用,获得对于进程takon,随后通过Binder将此事件传至应用进程的ViewRootImpl中。而具体从何起源,笔者暂时忘了,后面会深入源码补充。在此之前,假设事件源来自ViewRootImpl,就从此说起。
2024-01-25 23:52:44
961
原创 Java Lock源码解读
其中的继承关系如下:可能看到,此类是Lock或者所有同步器的抽象父类,锁的粒度是线程对象,其中虽说是抽象类,但没有抽象方法,且提供的独占线程set或get方法均被final修饰,子类无法修改。抽象同步队列,从注释可能看出,这是所有同步器类的基础实现,子类只能实现tryAcquire、tryRelease、tryAcquireShared、tryReleaseShare、isHeldExclusively方法,这些具体的实现稍后再谈。
2024-01-25 13:59:47
1098
原创 【Android】Jni开发部署
jni简单实例 (3)创建Android.mk和Application.mk文件这两个文件是用来指定编译路径、编译平台等配置LOCAL_MODULE是生成so库名。(4)activity中声明native方法System.loadLibrar
2022-06-13 10:53:19
413
原创 【个人Json工具手写类】JsonUtils
package com.zjw.application;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;import java.lang.reflect.*;import java.util.*;/** * conditi.
2022-05-23 16:12:24
484
原创 【Kotlin】协程
1,概述协程是一个轻量级的线程,将调度从系统线程切换拿到用户态,在一定程度上减少了线程切换开销。2,实例(1)基本使用//主协程fun main() = runBlocking { //开启一个新协程 val job = launch { delay(1000) println("task-1") } println("task-0") job.join()//等待job执行完毕,如果此处不join,会退出主协程
2022-03-01 15:32:26
2737
原创 【算法】剑指Offer详解
1,用两个栈实现队列用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead操作返回 -1 )class CQueue { private Stack<Integer> mStack1; private Stack<Integer> mStack2; public CQueue() { .
2022-02-14 16:08:31
1573
原创 【Java基础】多线程编程
1,守护线程设置成守护线程后,如果主线程结束,不保证守护线程执行完整结束。public class Daemon { public static void main(String[] args) { Thread thread = new Thread(new DaemonRunner(),"Daemon"); thread.setDaemon(true); thread.start(); } static class Da
2022-02-14 15:01:11
355
原创 【Android】SDK31 原生api高斯模糊
1,概述高斯模糊数学理论是根据正态分布,对图片进行一遍过滤,本质是一个低通滤波器。在sdk31中,原生提供了两种类型的模糊;Background blur: 模糊区域是窗口Blur behind:模糊区域是整个屏幕API:WindowManager # Background blurandroid.view.Window#setBackgroundBlurRadius(int blurRadius) # Blur behindandroid.view.WindowM..
2022-02-10 11:19:46
6667
3
原创 【Android】Notification相关
1,概述通知功能,不必多说。大致过程是系统app(如systemui)通过NotificationListenerService.registerAsSystemService将自己注册到系统通知观察者中,然后应用发送通知时,会回调如下方法(具体可查看NotificationListener源码),NotificationListener.onNotificationPosted;NotificationListener.onNotificationUpdate;NotificationLi
2022-02-09 10:25:56
1216
原创 【Android】SQLite
1,概述android端提供的轻量级数据库,2,实例I(1)创建SQLiteOpenHelperpublic class DBHelper extends SQLiteOpenHelper { private static DBHelper sDBHelper; public static void init(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.Cursor
2022-02-08 16:54:06
1687
原创 【Android】GreenDao
1,概述同Jetpack的Room,该框架封装了Sqlite,减少代码冗余;依赖导入如下:(1)插件导入classpath 'org.greenrobot:greendao-gradle-plugin:3.3.0'(2)插件applyapply plugin: 'org.greenrobot.greendao'(3)依赖导入implementation 'org.greenrobot:greendao:3.3.0'(4)配置gree...
2022-02-08 16:23:37
2230
原创 【三方库】Gson
1,概述Gson框架主要作用是将json与java对象之间互相转换,有如下转换,object->json,json->object,list->json,json->list,2,简单实例public class GsonTest { public void test() { Gson gson = new Gson(); UserInfo userInfo = new UserInfo("zjw", "chon
2022-02-07 17:00:22
414
原创 【Android】getDimension相关记录
1,概述一直以为调用context.getResources().getDimension(R.dimen.xxx)只会获取dimens.xml中写入的值,但其实已经转换为屏幕desity对应的像素值了;2,源码public float getDimension(@DimenRes int id) throws NotFoundException { final TypedValue value = obtainTempTypedValue(); try {
2022-02-07 09:33:05
729
原创 【Android】SharedPreferences
1,概述android平台提供的轻量级数据存储类,类似window配置文件,本文旨在讲解基本使用、一些注意事项。2,简单实例public void useSharedPreferencesDemo(Context context){ //通过context获取的SharedPreferences可以在同一应用访问数据, //如果是Activity,使用 ((Activity) context).getPreferences(Context.MODE_PRIVAT
2022-01-28 09:54:20
1546
原创 【Android】View.startDragAndDrop
1,概述原生api,提供跨进程拖拽数据,需提供剪切板、DragShadowBuilder等参数。简单理解,调用该方法会在系统层次上生成阴影,默然与拖拽view大小相同,阴影中心位置与触摸点重合。2,核心方法public final boolean startDragAndDrop(ClipData data, DragShadowBuilder shadowBuilder, Object myLocalState, int flags) {......}...
2022-01-26 09:28:18
2388
1
原创 【Android】EventBus
1,概述为了更加方便的模块管理,替代类似本地广播类实现,采用观察者模式实现的三方库,2,简单实例使用很简单,在Context的start周期注册,stop周期注销,因业务而定;在任意线程调用post方法发布通知,如下。public class BusEventDemoActivity extends AppCompatActivity { private static final String TAG = "BusEventDemoActivity"; @Overr
2022-01-19 15:54:29
2431
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人