- 博客(39)
- 收藏
- 关注
原创 如何修改seekBar的样式
进入Android SDK中的values目录D:\AndroidSDK\platforms\android-25\data\res\values进入styles.xml,找到自己想要查看的SDK自带的样式进入drawable文件夹下D:\AndroidSDK\platforms\android-25\data\res\drawable将对应的xml文件拷贝进项目中的drawabl...
2018-11-20 17:07:14 250
原创 DecorView添加进window的流程分析
我们知道一个DecorView的创建是在Activity中调用setContentView后,一步一步实现的。那么,创建好了DecorView后,我们是怎么将它加入进window呢?handleLaunchActivity中的performLaunActivity方法调用startActivity方法时,最终会调用ActivityThread的handleLaunchActivity方法创建A...
2018-11-18 11:10:44 2165
原创 setContentView源码解析
每次新建一个Activity时,我们都得将一个xml文件通过setContentView方法与这个Activity绑定在一起。那么,当我们调用setContentView时,是怎样一步一步创建这个界面的呢?进入这个方法,我们会发现。通过getWindow调用进一步调用setContentView方法。getWindow方法会返回一个mWindow对象,而mWindow对象是在Activity的a...
2018-11-17 19:23:30 537
原创 初步分析Scroller源码
Scroller的构造函数public Scroller(Context context) { this(context, null);}public Scroller(Context context, Interpolator interpolator) { this(context, interpolator, context.getApplic...
2018-11-16 16:53:21 449 1
原创 初步解析View的滑动
View的滑动方式有很多,在学习View的滑动之前,我们先了解下View是怎么定位的。View坐标系1.View自身坐标getTop():获取自身顶部到父布局顶部的距离getLeft():获取View自身左边到父布局左边的距离getRight():获取View自身到父布局左边的距离getBottom():获取View自身到父布局顶部的距离2.确定点击位置坐标当我...
2018-11-15 20:10:31 132
原创 HashMap的源码分析(jdk1.8)
jdk1.8后,HashMap的底层实现由“数组+链表”转换成了“Node【】数组+链表+红黑树的形式”。HashMap中的几个关键点1.转为红黑树后,链表的结构依然存在,通过next属性维持。2.红黑树中,叶子结点也可能有next结点。3.进行红黑树查找时,会反复判断hash值和key值,如果小于则向左遍历,大于向右遍历。4.红黑树中有一个dir属性(int),存储的值表明向左还是向右...
2018-11-10 19:43:12 179
原创 HashMap源码分析(jdk1.8之前)
什么是HashMaphashMap在我们的编程中,应用非常广范。那么HashMap内部到底是怎么存储数据呢,我们先来看看下图。HashMap是通过维护数组和链表的方式,来存储数据。在上图中X轴是数组,每个数组包含一个链表,通过hash值在查找数组的索引和插入数据。HashMap基本原理我们在向HashMap中插入一个数据时,首先会判断key是否为空,为空则查找Entry[0],不为nu...
2018-11-06 17:12:32 161
原创 几种常用的单例模式
单例模式的作用是使该类在全局中只存在一个实例。目的是当有其他类需要访问时,不需要重复创建该实例,并且可以共享该类数据。1.饿汉式public class Singleton { private final static Singleton INSTANCE = new Singleton(); private Singleton(){} public static...
2018-11-04 11:28:21 274
原创 ListView更新界面的原理
ListView是我们经常使用的一个控件。那么,当我们删除或者添加ListView中的一个item时,界面是如何更新的呢?为了及时更新界面,ListView使用了观察者模式,在我们数据源发生改变时,我们调用了notifyDatasetchange方法,界面发生改变。下面,我们一起看看notifyDataSetChanged的源码实现。 既然,更新界面需要调用noti...
2018-11-01 17:20:17 716
原创 AlertDialog源码解析
AlertDialog是我们平时使用很多de空间。那么,这个控件是怎么实现的呢?AlertDialog继承自Dialog,实现了很多扩展功能。首先,我们先来看一下AlertDialog类的构造器。protected AlertDialog(Context context) { this(context, resolveDialogTheme(context, ...
2018-10-31 15:19:27 212
原创 DNS域名解析过程
DNS提供将主机名和域名与IP地址的相互转换的工作。 1.输入一个域名后,首先会判断客户机的HOSTS文件是否存在相应映射文件。存在就返回2.不存在的话,查询本地DNF解析缓存。3.查询TCP/IP中设置的首个DNS服务器,查询本地区域是否存在相应映射。4.如果查询的域名不由本地区域管理,查看本地DNS缓存中是否存在映射。5.跳转至根DNF服务器,查询负责该请求的顶级域,并返回一个负责该...
2018-10-29 16:44:59 228
原创 RecycleBin缓存机制
在学习Android开发的过程中,大家应该或多或少的会接触到ListView这个控件。那么,大家有没有思考过,一个屏幕只能显示一定的item,每次下滑后,消失的item去哪里了?当再次回到原来的位置的时候,加载出来的item是重新获取的还是从缓存空间里提取的呢?接下来,我们通过分析RecycleBin机制来探寻ListView的缓存机制。RecycleBin的基本原理RecycleBin中有两...
2018-10-22 11:03:19 1645
原创 初步探索View的绘制和原理
在学习View的绘制原理之前,我们需要知道当我们切换至一个Activity界面时,该界面是有什么组成的,如下图: 首先我们需要知道,我们看到的控件视图等都是通过window界面来展示的,当一个Activity获得焦点时,会通知frameWord层来绘制这个window界面,而PhoneWindow是抽象类window的唯一实现类。在PhoneWindow中包含一个D...
2018-10-21 15:00:43 193
原创 AsyncTask源码解析
AsyncTask用于在Android中异步处理耗时操作,用法上非常简单。那么,我们不仅要会用,还要知道AsyncTask内部是怎么实现的。首先我们需要知道的是AsyncTask的内部包含哪些变量。 private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - ...
2018-10-18 12:32:41 96
原创 初步认识IntentService
IntentService继承自Service,用于异步处理一些后台耗时操作。在谷歌的建议中,我们不应该在Service中进行大量耗时操作,因为Service位于主线程,容易引起ANR。所以谷歌官方推出IntentService用于处理耗时操作。 在IntentService中,有一个继承自Handler的ServiceHandler内部类,此工作线程用来处理耗时操作...
2018-10-14 13:27:22 105
原创 Activity的生命周期
在Activity中,生命周期分为正常启动的生命周期和异常生命周期。首先,我们来梳理一下正常启动的生命周期。 Activity是通过Activity栈来进行管理的,栈里的Activty有4中状态:Active,Pause,Stop,Kill状态。当一个Activity启动时,首先会调用onCreate()方法,用于初始化一些数据,实...
2018-10-13 20:19:33 140
原创 Bitmap优化方案
在Android中,我们可以通过Bitmap来将一张图片加载至ImageView,可以使用的API有decodeFile,decodeResource,decodeStream,decodeByteArray。 高效的加载大图主要策略是避免图片尺寸超过控件所需的尺寸。我们可以通过设定BitmapFactory.Option中的inSampleSize来修改图...
2018-10-10 21:16:53 231
原创 Android性能优化之内存泄露优化
1.静态变量持有对象导致泄露。 2.单例模式持有对象导致泄露。 3.属性动画无线播放,未在onDestory()中调用关闭方法导致内存泄露。...
2018-10-09 19:56:32 112
原创 Android性能优化之绘制优化
避免在onDraw()中做太多的耗时操作: 1.避免在onDrow()中创建局部变量,onDraw()可能会被频繁调用,因此会产生大量临时变量,造成占用过多内存,引起频繁GC。 2.避免在onDraw()中做耗时任务,避免大量循环,抢占CPU时间片,造成绘制不流畅。...
2018-10-09 19:31:19 179
原创 Android性能优化之布局优化
布局优化可以通过减少布局层级来提高,尽量减少使用性能低的布局,LineaLayout的效率最高,在可以使用LinearLayout或者RelativeLayout时,选择LinearLayout。因为RelativeLayout测量较为复杂,需要测量水平和垂直控件。当需要嵌套布局的时候,使用RelativeLayout,因为嵌套LinearLayout相当于多了一个View层级...
2018-10-09 19:08:32 98
原创 进程的交流机制——AIDL
Binder是Android的一个类,实现了IBinder接口。在FrameWork层,Binder用于连接各种Manager(WindowManager,ActivityManager等),比如在启动一个Activity时,ApplicationThread就是一个Binder机制,用于ActivityThread与ActivityManagerService之间进行交流。在应用层,...
2018-10-09 15:58:26 118
原创 探索Handler之秘
经历了一段时间的学习和总结,在这篇博客中写下自己对Handler的理解。话不多说,直接上图。 首先,我们需要知道的是,如果一个线程想要使用Looper,需要调用Looper.prepare()。刚开始学的时候,我便异或,为什么主线程里面没有调用这个方法呢。原来在我们启动一个Activity时,通过ActivityTh...
2018-09-25 20:30:15 182
原创 产生死锁的条件和解决方法
产生死锁的4个必要条件: 1.一个进程获得了锁,那么他所占有的资源是其他进程不能获取的。 2.一个进程获取了资源,只能主动释放,不能被其他进程抢占。 3.一个进程已经有资源了,仍然去请求其他资源,导致阻塞。 4.造成等待循环队列,一个线程的资源被后一个线程请求。解决方案: 1.控制加锁和释放锁的顺序。 2.控制请求时间,当请求时间过长时,...
2018-09-13 13:35:50 172
转载 本地缓存DiskLruCache学习总结
本地缓存数据一般缓存在 /sdcard/Android/data/<application package>/cache,因为存储在SDK上,所以不会对手机内存空间产生影响,并且这个是Android系统认定的应用程序缓存路径,程序卸载的时候,这里的数据也会被一同清理掉。创建DiskLruCache需要调用它的open(File directory,int appVersion,in...
2018-08-30 15:27:04 264
原创 wait()和sleep()的区别
1.sleep()不会释放线程锁,wait()会释放线程锁。2.sleep()会设置一个时间,线程休眠达到时间后或者使用interrupt()打断后继续执行。而wait()调用后会导致线程挂起,需要在其他线程中调用该对象的notify()唤醒线程。3.wait(),notify(),notifyAll()必须在线程同步块里面执行,sleep()可以在任何地方执行,但需要try-catch。slee...
2018-06-21 10:11:26 138
原创 View绘制流程学习总结
一个应用界面是一个Activity,通过一个实现了Window抽象类的PhoneWindow和DecorView相互关联,DecorView本质上是一个FrameLayout,他有一个唯一的子View,是LinearLayout,包含两个子View,TitleView和ContentView。我们在onCreate(Bundle bundle)方法中调用的setContentView就是填充的这个...
2018-06-14 10:25:07 130
原创 自定义View和ViewGroup学习总结
1.自定位View在onMeasure(int widthMeasureSpec,int heightMeasureSpec)方法中的这两个参数,包括测量模式和测量的信息。int类型占用32个bit,这里将前2个bit用于区分不同的布局模式,后面30个bit存放的是尺寸的数据。可以通过MeasureSpec.getMode(widthMeasureSpec) MeasureSpec.getSize...
2018-06-13 19:33:50 161
原创 Fragment的坑以及从源码角度分析为什么会重复加载
1.在导入Fragment的包时候,记到导入支持V4的包。2.getActivity()空指针,有时候在调用getActivity()时,该Fragment已经调用了onDetach()。在pop了Fragment后,该Fragment的异步任务任然在执行,在执行完成后调用了getActivity()。我们应该在onDetach()后取消这些异步任务。或者在Fragment中设置一个Activit...
2018-06-13 11:26:26 272
原创 Volley,Okhttp,Rerofit的区别学习记录
1.Voller底层封装的是HttpUrlConnection,支持图片加载,网络请求排序,优先级处理,缓存,与Activity生命周期联动。扩展性好,支持httpclient,HttpUrlConnection,OkHttp,在频繁请求和加载数据量少的时候优势,不适合大数据加载,Request和Response都是使用byte数组存储数据,大数据=大数组,消耗内存。2.Okhttp底层基于原生h...
2018-06-10 14:54:52 1523
原创 三次握手和四次挥手学习记录
1.三次握手三次握手中,是由客户端发起的,客户端首先发起一个SYN=1,ACK=0的请求,服务器端返回一个ACK=1的响应,客户端在发送一个ACK=1的响应,建立连接。三次握手而不是两次握手的原因:如果存在网络延迟等意外情况,客户端发送的ACK=0,SYN=1的请求,在连接释放后的某个时间短才发送给服务器,这是服务器返回一个ACK=1的响应建立连接,但是客户端并没有发送响应,因此不会发送消息,而服...
2018-06-10 09:48:42 173
原创 网络的一次请求过程学习记录
网络请求的过程为域名解析,TCP三次握手,三次握手后的TCP连接后,发送http请求,服务器端的http响应,浏览器解析html代码,同时请求html中的资源。1.域名解析浏览器会首先访问浏览器本身保存的dns缓存,但本身dns缓存量少,存活时间短,如果有,则直接解析,没有则去访问操作系统所保存的DNS缓存,没有的话在访问C盘下的hosts文件,如果在没找到,则首先去找TCP/IP中设置的本地DN...
2018-06-10 09:32:34 174
原创 基于MVP框架+GreenDao的简易登录注册demo
1.首先添加GreenDao的依赖。添加后整体如下:apply plugin: 'com.android.application'apply plugin: 'org.greenrobot.greendao'buildscript { repositories { mavenCentral() } dependencies { clas...
2018-06-07 16:01:15 868
原创 使用Retrofit2.0同时向服务器上传文字和图片(一张)
首先定义一个接口。public interface PostInterface { @POST("addPost") @Multipart// Call<MediaBrowserServiceCompat.Result<String>> testFileUpload(@Part("content") String content,@Part() Re...
2018-06-02 15:51:48 1647
原创 学习无锁并发策略:比较交换记录
锁是一种悲观策略,无锁是一中乐观策略。它会假设对资源的访问时没有碰撞的,其检测冲突的一种策略为比较交换(CAS)策略。在CAS算法中有三个参数,CAS(V,E,N)V表示要更新的变量,E表示预期值,N表示V达到E后,将V设置为N。如果V和E的值不同则表示已经有其他线程做了更新。多个线程同时更新时,只有一个线程会成功。...
2018-05-28 15:08:05 105
原创 学习JDK的并发容器记录
一些好用的工具类ConcurrentHashMap:一个搞笑并发的HashMap,线程安全.CopyOnWriteArrayList:一个List,和ArrayList是一族的,适用于读多写少的场合,好与Vector.ConcurrentLinkedQueue:高效并发队列,使用链表实现,可以看成一个线程安全的LinkedList。BlockingQueue:一个接口,通过链表,数组等方式实现,是...
2018-05-05 16:26:22 120
原创 学习JVM的个人理解以及总结--垃圾收集器与内存分配策略
虚拟机栈,程序计数器,本地方法栈随线程的生和死而决定,垃圾收集一般不考虑这个区域。引用计数算法当其他对象引用它时,计数器就加1,引用失效就减去1.但是存在一个缺陷,就是互相引用后让两个对象不再被访问时,导致计数器不为0.可达性算法分析,可以作为GC Roots的对象包括:虚拟机栈(栈帧中的本地变量表)中引用的对象。方法区中类静态属性引用的对象。方法区中常量的引用对象。本地方法栈中JNI引用的对象。...
2018-04-19 08:57:35 101
原创 学习JVM的个人理解以及整理——自动内存管理机制
java虚拟机所管理的内存区域划分为堆,方法区,虚拟机栈,本地方法栈,程序计数器。每个虚拟机栈中有一个私有的程序计数器,程序计数器占用很小的一块内存,在执行一个java方法时,记录正在执行的虚拟机字节码的地址。虚拟机栈中有一个栈帧,用于存放局部变量表,操作数栈,动态链表,方法出口等。常量池用于存放编译期期间生成的各种字面量和符号,在类加载后进入方法区的运行时常量池。Java语言并不要求常量一定在编...
2018-04-17 15:24:49 188
原创 学习View事件分发机制的个人理解
View事件分发机制是从上级向下级传递,总流程是Activity->Window->View.首先传递给顶级View(ViewGroup),分发机制在由ViewGroup向其子View进行分发,以树的形式,从跟结点依次向下级分发。每次到达一个View时,首先调用dispatchTouchEvent方法,在ViewGroup中,此方法的返回结果受拦截后的OnTouchEvent(...
2018-04-15 10:50:05 127
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人