- 博客(24)
- 收藏
- 关注
原创 java.lang.IndexOutOfBoundsException: setSpan ( ... ) ends beyond length 剖析
背景闲来无事,看一下线上的奔溃率,忽然一个Exception引起了我的注意。我们在设置中打开拼写检查工具功能的时候,SuggesttionsPopupWindow这个系统弹窗,就会在我们编辑EditText的时候,自动弹出,提示我们补全。分析看trackstack的信息,应该是点击其中一项候选词的时候发生的奔溃。让我们先看看SuggesttionsPopupWindow在处理点击事件的...
2020-05-10 20:45:45 5872
原创 Android OOM的那些事
基础进程的内存空间是虚拟内存(32位系统最大4G,64位系统4G*4G),然而程序的运行需要的是物理内存,虚拟内存和物理内存的映射关系,是通过内存管理单元(Memory Management Unt,MMU)实现的,主要是采取多级页表的方式。Android 进程...
2020-04-26 16:29:30 828
原创 Hook Transact方法监控IPC流量
背景Binder数据传输是有大小限制的。oneway方式。手写MMAP初始化Binder服务(4M/2),ProcessState初始化BInder服务(1M-8K)/2。非oneway方式。手写MMAP初始化Binder服务(4M),ProcessState初始化BInder服务(1M-8K)。而且BInder的线程池默认是15个,15个线程共享这1MB-8KB的内存空间,所以实际传输大...
2020-04-11 19:53:17 784
原创 Handler.createAsyn作用
结论从API28开始,Handler类增加了静态方法createAsyn。主要作用是使所有通过这个Handler发送的Message,都会被设置为FLAG_ASYNCHRONOUS异步消息(默认是同步消息),在搭配消息屏障使用的情况下,会被优先调用。原理#Handler.java @NonNull public static Handler createAsync(@NonNull...
2020-03-21 23:15:59 1710
原创 Glide4.9.0 任务生命周期管理
一、概述众所周知,Glide会根据一定的条件自动管理任务的开始和暂停,那么这个具体条件是什么呢?这篇文章将会探索其中的秘密。主要根据调用Glide.with(T)的不同分为2种情况。1、可以找到T对应的Activity或者android.app.Fragment(Android3.0版本之前是android.support.v4.app.Fragment或者FragmentActivity),使...
2019-04-01 00:17:29 469
原创 Glide4.9.0 ResourceCacheGenerator 源码解析
一、作用/** * Generates {@link com.bumptech.glide.load.data.DataFetcher DataFetchers} from cache files * containing downsampled/transformed resource data. */根据官方注释,关键词downsampled/transformed,就是我们获取到...
2019-03-19 18:13:00 520
原创 Glide4.9.0 数据转换设计思路
在Glide中,model其实是一个抽象的概念,无论你是缓存读取,还是从网络获取,资源所在的路径就称为model。所以,无论是SourceGenerator,DataCacheGenerator,还是ResourceCacheGenerator在从model(缓存或者网络)中获取数据之后都需要走一次data->transcode过程(ResourceCacheGenerator可以跳过tra...
2019-03-19 12:16:20 482
原创 Glide4.9.0 DataCacheGenerator 源码解析
从Glide4.9.0源码 整体概述(二)可以看到,DataCacheGenerator 的入口方法是startNext,所以我们可以先从这个方法入手。//DataCacheGenerator@Override public boolean startNext() { //modelLoaders为null,或者modelLoaderIndex >=modelLoaders....
2019-03-19 11:34:11 362
原创 GLide4.9.0 buildRequestRecursive 源码解析
先附上代码,后面有空加上注释。private Request buildRequestRecursive( Target<TranscodeType> target, @Nullable RequestListener<TranscodeType> targetListener, @Nullable RequestCoordinat...
2019-03-18 18:01:44 258
原创 Glide4.9.0 getModelLoaders 源码解析
一、概述GLide中所有的下载器,解码器,编码器,转换器等都是通过Registry管理的,在生成Registry实例的时候会把内置的所有注册好,以供后续选择使用。//Registry.java private final ModelLoaderRegistry modelLoaderRegistry; private final EncoderRegistry encoderRegis...
2019-03-17 21:43:12 286
原创 Glide4.9.0 SourceGenerator 源码解析
一、作用/** * Generates {@link com.bumptech.glide.load.data.DataFetcher DataFetchers} from original source data * using registered {@link com.bumptech.glide.load.model.ModelLoader ModelLoaders} and the...
2019-03-14 12:25:38 498
原创 Glide4.9.0源码 整体概述(二)
一、Decodejob的启动在Glide源码 整体概述(一) 中说到调用Engine.load()方法将会真正启动一个任务,接下来看看是如何启动的。//Engine.javapublic synchronized &amp;amp;amp;amp;lt;R&amp;amp;amp;amp;gt; LoadStatus load( GlideContext glideContext, Object model, Key.
2019-03-14 00:59:58 270
原创 Glide4.9.0源码 整体概述(一)
基于源码4.9.0分析,不同版本可能会有所差异,先说整体,后面分节说细节!Glide最简单的使用就是Glide.with(this).load(url).into(view),我们注意分析这个过程发生了什么。一、初始化Glide,创建RequestManagerGlide.with(this),这里主要是使用GlideBuilder生成Glide,通过Glide获取RequestManage...
2019-03-13 12:27:21 816 1
原创 ViewGroup 拦截TouchEvent 源码分析
#ViewGroup#dispatchTouchEvent摘要// Handle an initial down.if (actionMasked == MotionEvent.ACTION_DOWN) { // Throw away all previous state when starting a new touch gesture. // The framework m...
2019-03-06 21:46:35 155
原创 You must call removeView() on the child's parent first 的处理。
这个问题是由于我们想加入的view已经存在parent导致,一般我们只需要调用((ViewGroup)view.getParent()).removeView(view)即可,可是有些时候并不能解决问题。这时候可以参考以下代码。 if (child.getParent() instanceof ViewGroup) { ViewGroup parent ...
2019-01-11 15:20:24 3538
原创 offsetDescendantRectToMyCoords和offsetRectIntoDescendantCoords源码剖析
日常工作中经常需要对坐标系作转换,那么我们应该对这2个方法不会感到陌生。首先我们可以看一下这2个方法的源码。可以看到都调用了同一个offsetRectBetweenParentAndChild方法。然后我们看一下offsetRectBetweenParentAndChild方法。5916行是一个while循环,主要起到一个从子View一直回溯到this的作用。根据源码可以发现,方法一其实就...
2018-10-16 18:47:39 1428
原创 Android源码剖析:FocusFinder
由于工作研究,需要优化一下焦点寻找逻辑,所以首先研究一下Android原生逻辑。从源文件,我们可以看到,FocusFInder类大概1000行左右的代码量,并不多。我们可以发现FucusFInlde使用了单例模式,不过由于使用了ThreadLocal,所以每一个线程都会拥有一个副本。有2个方法可以寻找焦点,一种通过view,另外一种通过view的rec。我们可以看到上述...
2018-10-15 20:27:01 1141 1
原创 具有排序,增加,删除,翻页动画的scrollview
网上主要都是手势拖拽动画,关于按键的动画比较少,因此做了一套。 先来一个效果图:下面是源码: public class HorizontalPageScorllView extends HorizontalScrollView implements OnKeyListener { private boolean mAnimationEnd = true; /*...
2017-04-27 10:18:25 925
原创 读取通知栏消息
android4.4以后的版本出现了一个NotificationListenerService(通知监听服务类),因此,我们只需要继承这个服务,然后在Manifest.xml中注册即可。package com.example.demo;import android.app.Notification;import android.app.Notification.Action;im...
2016-06-06 11:22:26 3221
原创 居中滚动的Recyclerview
RecyclerView出现已经有一段时间了,相信大家肯定不陌生了,大家可以通过导入support-v7对其进行使用。 一定程度上取代了listview,gridview的使用。 下面介绍一下RecyclerView的居中滚动,只需要继承RecyclerView。 然后增加以下函数即可。 @Override public boolean dispa...
2016-05-12 15:49:44 4748 2
原创 下拉刷新+上拉加载的listview
网上关于这方面的内容有很多,但是有些使用比较复杂,有些存在一些BUG,在这里整合网上资源。主要解决了RELEASE--》PULL header状态不正确,footer不正确显示等问题。 header的xml: <?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://...
2016-02-19 15:47:35 472
原创 居中+循环滚动的listview(2)
接上上一篇所说,最后是一个自定义的listview: package com.example.mylistview;import android.content.Context;import android.util.AttributeSet;import android.view.KeyEvent;import android.view.View;import androi...
2016-02-17 17:21:18 1909
原创 居中+循环滚动的listview(1)
之前写过一篇用scrollview实现居中滚动效果的,考虑到listview的列表项的拓展性可能更加好,所以尝试使用listview来实现这个效果,并且加入了循环滚动。 先来看看效果图:源文件就只有这3个: 以下是用到的2个布局文件activity_main.xml : <?xml version="1.0" encoding="utf-8...
2016-02-17 17:01:36 3599 3
原创 居中滚动的scrollview
我们平时用的listview,scrollview都是在边界的时候滚动,可是我们某些时候可能需要把焦点固定在中间一行来进行滚动。网上有很多这种实现,大多利用android的picker来实现,今天我们可以尝试另外一种实现思路,利用scrollview+listview来完成这种需求。这里的demo只是监听了按键进行滚动,并没有监听手势。布局如下,在一个scrollview里面放一个li...
2016-02-14 09:59:11 3481 1
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人