Android
文章平均质量分 72
brycegao321
Android/iOS/后台/H5全栈
展开
-
冷启动治理-启动框架原理
一、背景从点击桌面图标到首页渲染完成的平均时间应在3秒以内。 为什么是3秒? 统计数据表明超过3秒后用户跳失率陡增。冷启动优化有很多技术手段, 百度上都能查到,不再赘述。二、启动框架简介启动框架的作用是充分利用前3秒的CPU, 即打满CPU.为什么出现“bad case”的情况呢? 这是本文要解决的问题。 通常因为在进程启动阶段出现各种锁和信号量, 导致线程间的相互等待。上图Wall Duration是142.421ms,但self time是4.251ms。该函数等待时间远远超过自身的执行原创 2020-06-21 11:25:28 · 864 阅读 · 0 评论 -
Android性能优化系列-监听View inflate周期并动态替换
LayoutInflater hook点在Activity里执行setContentView或者inflate布局文件最终都会走到如下代码:LayoutInflater.java View createViewFromTag(View parent, String name, Context context, AttributeSet attrs, boolea...原创 2019-10-13 16:20:15 · 1080 阅读 · 0 评论 -
贝壳找房app使用Glide替换Picasso
贝壳找房app使用Glide替换Picasso现状改造成本原理Glide比Picasso的2个优势:展望现状操作步骤:打开贝壳找房,设置城市为“徐州”, 然后点击“二手房”图标进入“二手房列表页”, 向上滑动列表。使用Picasso使用Glide 上图是Android Profiler抓取的运行时内存, 使用Picasso时Java堆占用了220.7M字节, 使用Glide时J...原创 2018-09-22 08:28:11 · 588 阅读 · 0 评论 -
安卓适配动态权限说明
一、背景: 从Android6.0版本开始google将权限分为普通权限和特殊权限,app必须在AndroidManifest.xml添加引用权限的语句。 在安装apk时安卓会将普通权限授予该app,但特殊权限需要运行时申请。 安卓按照权限类别分为权限组和权限, 每个权限都隶属于一个权限组。 当安卓系统授权一个权限时, 那么该权限所属权限组的权限都会自动被授权。 ...原创 2018-11-26 22:12:25 · 1096 阅读 · 0 评论 -
自定义lint规则解决开发中的问题
一、背景在发贝壳2.1.1版本第一次灰度时遇到了一个崩溃(崩溃在租房),第二次灰度版本时发生了相同原因的崩溃(崩在了二手)。 当时的做法是发现一处解决一处, 但没发现的隐藏问题是个定时炸弹。日志:java.lang.RuntimeException: Parcelable encountered IOException writing serializable object (name = ...原创 2019-01-08 19:30:22 · 1644 阅读 · 1 评论 -
贝壳找房FEED流曝光策略
摘要:目前贝壳找房的曝光策略边界条件比较单一, 都是APP端写死的逻辑;对标一线公司解决方案, 是由API下发每种卡片/Feed的门限条件, 从而得到更精准的数据。一、背景目前贝壳找房APP端的曝光时机是写死的, 触发条件:卡片必须要完整展示在界面上; 在列表界面上下/左右滑动时单次/多次曝光同一个卡片。现有方案的不足:1、门限条件应改为API下发的; 2、缺少卡片在界面上显示的时长;...原创 2019-02-16 22:29:19 · 1671 阅读 · 0 评论 -
一个小Demo带你理解安卓事件分发
安卓事件分发是个老生常谈的话题, 在ScrollView高度测量原理介绍Android View测量原理, 现在再用个实例讲解事件分发原理。 本文要搞懂2个问题。1、 事件是怎么产生的?2、事件是怎么传递的? 手指在屏幕上一滑, framework层的ViewRootImpl中广播监听WindowInputEventRecevier最先收到事件, 将native层传...原创 2019-02-17 10:04:14 · 520 阅读 · 0 评论 -
ScrollView高度测量原理
在使用Lint扫描工程时,看到这个提示。 Google推荐将ScrollView的子View高度设置为wrap_content, 但实际业务开发时可能根节点是LinearLayout(layout_height="match_parent"), 然后发现屏幕显不下就包了一层ScrollView。 运行看到ScrollView能正常上下滑动,就没改LinearLayout的layou...原创 2019-02-14 14:18:59 · 3404 阅读 · 1 评论 -
删除TextView上下内边距
原理参考: https://blog.csdn.net/harvic880925/article/details/50423762通过自定义控件删除上下内边距, UI走查时就不用担心间距不对了。代码:public class MyTextView extends TextView { public MyTextView(Context context) { super(con...原创 2019-03-08 16:55:55 · 2289 阅读 · 0 评论 -
360 Replugin Binder实现原理
在安卓日常app开发过程中一般自定义Service并实现Binder, 且常用的ActivityManager/WindowManager/TelephonyManager最终都是通过ServiceManager.getService取到IBinder对象。 那么是不是离开Service, 就用不了Binder了呢? 在看Replugin源码前, 我是这么认为的。 但R...原创 2018-09-13 13:52:19 · 418 阅读 · 0 评论 -
自定义Android Gradle插件的3种方式
因为gradle插件是在编译过程中生效, 不用修改代码就能实现很多功能, 几乎每个app都使用了gradle插件。 下面就介绍一下自定义gradle插件的3种方式。https://docs.gradle.org/current/userguide/custom_plugins.html#example_a_build_for_a_custom_plugin 按照官网说明...原创 2018-09-18 11:32:54 · 2997 阅读 · 0 评论 -
不用WindowManger显示全局悬浮窗
Android7.1、Android8.0对WindowManager的限制越来越多, 想显示个SYSTEM_ALERT类型的window需要用户授权, 不同安卓版本可以使用TYPE_PHONE、TYPE_TOAST、TYPE_SYSTEM_OVERLAY类型, 但国内各厂商手机对悬浮窗可能单独做处理,运行时可能出现各种坑。 权限问题详见https://blog.csdn...原创 2018-08-18 20:16:58 · 1356 阅读 · 1 评论 -
Android ScrollView滑动监听
因为项目里用到了ScrollView, 并需要实现类似于ListView的滑动监听回调,所以自定义了一套实现方式支持这些事件, 基本满足了业务需求;public interface OnMyScrollListener { int SCROLL_STATE_FLING = 2; //手指滑动后松开,自动滑动 int SCROLL_STATE_IDLE = 0; /...原创 2018-07-08 07:41:08 · 6208 阅读 · 4 评论 -
VirtualApk加载插件原理
在VirtualApk官方文档https://github.com/didi/VirtualAPK/wiki/第三方技术文章中介绍了加载插件四大组件和资源的原理, 我想总结一下加载插件的原理并画了个流程图。为了加深对VirtualApk的理解, 考虑问题:1、插件中的类是被哪个classloader加载的? 答:跟Constants.COMBINE_CLASSLOA...原创 2018-04-24 11:04:07 · 1270 阅读 · 0 评论 -
为什么推荐使用注解代替枚举?
在做内存优化时, 推荐使用注解代替枚举, 因为枚举占用的内存更高。 这是为什么呢?编写一个最简单的枚举类, 请问问什么枚举是静态的单例? 脑子有点懵~~~public enum Numbers { One, Two, Three;}javac编译Numbers后生成字节码, 我们想看看到底Numbers.class到底有什么。 因为字节码比较晦涩难懂, ...原创 2018-04-10 15:12:41 · 4897 阅读 · 0 评论 -
Android5.0以上app进程保活的正确姿势
有图有真相, 亲测锤子T2、华为Mate8手机杀掉进程后能自启, 我设置的自启时间间隔为500ms(仅仅是为了测试)。 首先要明确保活的概念: 1、非android核心进程(例如com...原创 2016-08-25 10:48:33 · 16954 阅读 · 8 评论 -
Android GC深度分析
分析工具gc和代码gc不同的原因原创 2017-12-06 16:31:14 · 7089 阅读 · 1 评论 -
LruCache为什么要用LinkedHashMap?
LruCache原理和LinkedHashMap的使用, 双向链表header是“哨兵结点”原创 2017-08-19 19:06:18 · 1645 阅读 · 0 评论 -
HTTPS的一点思考
基础篇: 网上关于HTTPS的介绍有很多, 其实就是在HTTP基础上加了一层证书校验(SSL/TLS)。功能主要包括: 1、数据传输过程是加密的(对称加密算法); 2、客户端/服务端互相验证对方的真实性(HTTPS提供了单向/双向验证); 如上图所示HTTPS=HTTP+SSL/TLS , 仍然是应用层协议;HTTP协议默认端口是80,HTTPS协议默认端口是443;而SSL...原创 2018-01-16 21:00:07 · 7193 阅读 · 0 评论 -
HTTP302丢Session
安卓app在打开第一个H5页面时app设置了Session, H5返回302跳转到相同域下的另一个H5, 这时丢了Session。public class MainActivity extends Activity { private WebView mWebView; @Override protected void onCreate(Bundle savedInstanceSt...原创 2019-03-17 10:08:11 · 918 阅读 · 0 评论 -
贝壳找房APP安装包瘦身
一、背景在满足产品、UI要求的前提下,尽量减少安装包体积。以customer插件为例:插件大小为5MB, 其中1MB是dex,而bkbase占了dex的580KB;3.1MB是图片。 减少res目录体积效果会更明显。二、方法1、删除冗余代码、资源文件, 可使用lint扫描; 安卓端在编译release包时设置shrinkResources为true, 即不会打包冗余资源到输出物;...原创 2019-03-12 19:41:42 · 496 阅读 · 0 评论 -
ButterKnife R2作用和删除
在使用ButterKnife时library工程的注解会使用R2, 为什么使用R2而不是R呢?如上图所示R.class中参数定义使用了final关键字, 即R.class里全部是常量; 而R2.class里全部是变量。PS:Java语言在编译时常量内联, 即使用常量值替换参数;Java 注解的属性和 switch-case 中的 case 表达式,必须使用常量或者值,否则会报语法错误。...原创 2019-10-06 20:02:49 · 3350 阅读 · 0 评论 -
sqlitedatabase is locked
在操作Orm数据库sqlite时, 当存在多线程/多进程并行写时报错。 支持同一时刻多个读, 但同一时刻只能有一个写(不能有读); 简单记: 读写、写写是互斥的, 读读是可以并发的。 因为多线程、多进程可以通过数据库名称操作同一个数据库, 建议只在一个进程中实例单例访问同一个数据库, 从而实现互斥判断逻辑; 什么是写? 增加insert、删除delete、更新up...原创 2019-09-25 19:49:52 · 305 阅读 · 0 评论 -
Activity渲染完成第一帧时机
Activity第一帧渲染涉及知识点setContentView流程、帧绘制流程和帧率监听等。开始时间:hook ActivityThread的Instrumentation, 得到Activity各个生命周期的开始、结束时间; 参考: Activity的生命周期是谁调用的?注意: ActivityLifecycleCallbacks的回调函数是执行结束后触发的, 无法得到开始执行时间...原创 2019-09-22 10:25:53 · 3692 阅读 · 0 评论 -
安卓View点击/曝光的监听方式
Android点击、曝光事件的监听分散在代码的各个角落, 不利于开发维护。其实可以将这2种行为收敛到一起, 运行时监听Activity的生命周期,即ActivityLifeCallBack回调; 在onResume或onStart函数里判断当前acitivity是否添加了自定义ViewGroup(暂且命名为TrackerViewGroup), 如果未添加则添加;在onDestory函数中移除...原创 2019-09-15 19:12:39 · 2064 阅读 · 0 评论 -
安卓9启动Activity流程分析和优化建议
Android在从9.0版本开始修改了启动Activity流程, 跟以往版本的主要区别在于使用了Translation。Android9.0代码:clientTransaction.addCallback函数传入了LaunchActivityItem。final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord a...原创 2019-08-24 18:05:03 · 848 阅读 · 0 评论 -
Android性能优化系列-IdleHandler
IdleHandler是在主线程空闲时执行同步任务, 即可以做优先级低的业务逻辑。对于启动新Activity可以在cmd窗口执行adb logcat -s ActivityManager | grep “Displayed” 得到时长。用法:public DemoActivity extends Activity { IdleHandler mHandler1 ; IdleHand...原创 2019-08-19 21:08:56 · 1931 阅读 · 1 评论 -
Android Drawable缓存
Android获取Drawable对象方式为getResources().getDrawable(@DrawableResId int res), 只可能返回ColorDrawable、BitmapDrawable对象, 当然id不存在会抛异常。public abstract class Drawable { ... }在/framework/base/graphics/java/an...原创 2019-08-02 10:39:20 · 1408 阅读 · 0 评论 -
Android View座标
手机屏幕左上角座标是(0, 0), 右下角座标是(w,h)即屏幕宽和搞。获取View位置:View方法说明getLocationOnScreen获取View左上角距离屏幕左上角的距离x和ygetLocationInWindow获取View左上角距离PhoneWindow左上角的距离x和y,只有Dialog模式activity时有区别, 其它情况下返回值与get...原创 2019-07-22 07:46:43 · 448 阅读 · 0 评论 -
Live Template撸码利器
参考:https://www.jianshu.com/p/488f2d73e71d手动输入代码太辛苦, 拼敲键盘速度? 赶快试用代码补全功能吧。IntelliJ idea和Android Studio都支持代码自动补全功能, 如上面所示的几个场景。 在工作中可以把常用的代码块总结到模板里, 输入几个字符自动生成代码,从而提高撸码效率;例如在创建dart文件后, 文件内容是空的。 这时有代码...原创 2019-07-20 18:13:06 · 2118 阅读 · 0 评论 -
Java调用Kotlin函数的坑
看下这段代码执行main函数结果如何, 会打印"执行了method函数"么?class DemoClass { fun method(str: String) { System.out.println("执行了method函数") System.out.println(str) }}public class HelloJava { p...原创 2019-07-20 17:46:21 · 3240 阅读 · 0 评论 -
可拖拽的ListView
长按拖拽item并实现变更排序;说明: WindowManager在addView时尚未测量完成, 获取宽高都是0。 可以这样测量: view.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);int width = view.getMeasuredWidth();使用getViewTreeOb...原创 2019-07-05 20:28:49 · 1523 阅读 · 1 评论 -
地图类业务优化方法
一、背景在百度地图、高德地图上显示Marker, 如果显示数量很多时,滑动地图会出现卡顿的现象。 根本原因是地图是个耗内存的功能, 我们看到的地图和marker都是Bitmap。 想想在手机屏幕上添加100个小的Bitmap和背景的大Bitmap需要多少内存? 这些图片没有复用机制,都是储存在Java堆里,显示的Marker越多占用的内存越多。滑动地图时可能出现卡顿甚至ANR的现象, 其实就...原创 2019-06-16 18:31:19 · 556 阅读 · 0 评论 -
ByPhoto-秒开的安卓图片选择库
一、背景ByPhoto是个安卓图片选择库, 在启动渲染速度上做了很多优化; 荣耀8真机测试,图库里有3000多张图片。 冷启动图片选择页渲染完成需800ms左右, 热启动(即第二次打开Activity)渲染需要300ms。 真正实现了秒开的用户体验。二、需求1、支持图片预加载, 即将图库的前几张图片加载到内存中; 使用了Glide的preload;2、数据库分段回调, 即图片有几千张...原创 2019-06-12 19:43:32 · 1272 阅读 · 0 评论 -
Android根据座标找到对应的View
在界面上点击按钮时,想想安卓是如何找到能响应事件的顶层View的?如果给你坐标x、y, 你能找到对应的顶层View么?首先安卓布局根节点是DecorView,并呈现为多叉树结构; 每个顶层View都是一个页节点;需求:手指在界面上滑动时显示对应的顶层View。<?xml version="1.0" encoding="utf-8"?><LinearLayout xml...原创 2019-05-30 09:50:46 · 1747 阅读 · 0 评论 -
Java和Kotlin编译基础知识
Java和Kotlin都是跨平台语言, 归功于在编译时生成的字节码与平台无关, jvm在装载字节码后即可运行。JavaKotlin编译javackotlinc运行javakotlinJava语言使用javac编译为字节码, Kotlin使用kotlinc编译为字节码;在Android Studio的安装目录下保存着Kotlin插件, Kotlin目...原创 2019-05-27 15:47:52 · 1380 阅读 · 0 评论 -
Long monitor contention with owner
安卓Activity在finish后出现黑屏, 大概率是因为主线程卡死。 抓trace和logcat。04-16 16:18:17.359 W/m.lianjia.beik(30714): Long monitor contention with owner Binder:30714_6 (32307) at void java.lang.Object.wait(long, int)(Obje...原创 2019-04-16 17:27:56 · 18549 阅读 · 1 评论 -
Glide preload和into的区别
一、背景 贝壳2.6.0版本使用Glide preload方法替换了部分显示图片的方式, 在灰度期间发现控件显示了错误的图片或者崩溃问题。Fatal Exception: java.lang.RuntimeException:Canvas: trying to use a recycled bitmap android.graphics.Bitmap@25e89bf at android...原创 2019-04-08 18:17:19 · 1212 阅读 · 0 评论 -
Android开发的一些知识点(随时更新)
一、 布局篇1.1 RelativeLayout会执行2次onMeasure函数, 一次是横向测量、一次是纵向测量。因此建议尽量使用LinearLayout。1.2 LinearLayout如果子View没有layout_weight属性则执行1次onMeasure函数; 如果设置了layout_weight属性则执行2次onMeasure, 第一次测量没有layout_weight属性的子vi...原创 2016-08-22 21:06:33 · 2033 阅读 · 0 评论 -
Activity的生命周期是谁调用的?
我们知道Activity的生命周期包括onCreate、onStart、onResume、onRestart、onStop、onDestory、onSaveInstanceState、onRestoreInstanceState等等, 那么是谁调用了它呢? 答:是ActivityThread调度的, 具体逻辑封装在Instrumentation类里。 好好看看这2个类就明白了...原创 2018-01-15 10:49:52 · 1951 阅读 · 0 评论