自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(134)
  • 收藏
  • 关注

原创 Android SQLite基于APT的封装实现

APT是一种能够在代码编译时处理注解,并且按照一定的规则生成新的Java代码的技术,假如在新的Java代码中又存在有APT需要处理的注解,APT就会继续执行直到新生成的代码没有要处理的注解为止。目前很多优秀的开源框架比如ButterKnife 、EventBus 和Dagger2 等都采用APT编译时生成代码,取代它们之前的反射实现,提高框架的执行效率。APT和反射生成代码的原理很相似,但它们使用的接口差别很大,而且由于APT是在编译时运行的很多运行时的数据结构都不存在比如数据实体类Student.clas

2021-03-08 08:43:45 284

原创 Android SQLite反射封装

Java的源代码通过javac工具编译后生成.class文件,在运行Java应用时虚拟机会把.class文件加载到内存中,在JVM中会生成对应的Class类型对象。开发者可以通过Class对象查看类中定义的属性(Field)、方法(Method)和构造函数(Constructor)等成员对象,也可以利用Field属性对象访问类实例中定义的属性值,Method方法对象调用类实例的方法,Constructor构造函数用来创建类实例对象。像这种能够在运行时动态获取类成员并且调用它们的功能就是Java的反射机制,有

2021-03-08 08:26:55 288

原创 Android SQLite数据库访问

Android中提供了对SQLite数据库操作的辅助类SQLiteOpenHelper,它内部封装了SQLiteDatabase的创建和升级操作,里面对数据库容量已满、内部文件损坏等错误都做了异常处理,由于SQLiteOpenHelper事一个抽象类开发中需要继承它并覆盖其中的onCreate()创建方法和onUpgrade()升级方法,当用户调用getReadableDatabase()或getWritableDatabase()时如果数据库还未创建或者数据库版本更改就会执行onCreate()或onUp

2021-03-08 08:20:21 646

原创 HTTPS网络请求原理与实现

HTTP协议属于明文传输,在公共网络上传输数据时很容易被不法分子截获到,对于像登录、转账之类比较私密的信息传输不适合用HTTP协议,为此业界又推出了HTTPS协议,它实际在HTTP协议和TCP协议之间添加了安全套接字(SSL,Secure Socket Layer)层,SSL层借助于加密解密过程实现网络上传输加密内容,不法分子即使获取到了密文,在没有正确的解密秘钥情况下无法获的真正的用户数据信息。...

2019-10-23 22:00:12 1284

原创 Android HTTP编程基础

HTTP协议是一种请求响应式通信协议,通常是客户端向服务器端发送资源请求,服务器接收到客户端请求后返回对应资源响应,两端不断重复请求响应的过程就完成了客户端与服务器端的会话操作。HTTP是运行与TCP协议之上的应用层协议,它定义自己独特的报文格式,HTTP报文在网络发送时传输层使用了TCP协议,TCP协议重传和确认机制能够确保HTTP报文到达接收端,因而HTTP协议是一种可靠的数据传输协议。H...

2019-10-23 21:41:56 731

原创 下拉刷新实现

下拉刷新在Android应用开发中是一种很常见的交互方式,在实际开发中都会引用第三方的下拉刷新库来实现,第三方库通常都经过多个应用程序集成测试,有着相对较高的稳定性和可靠性,里面的代码逻辑也相对比较庞杂,对新手相对不太友好,学习起来比较费时费力,本节就通过前面学习的Android视图基本原理来实现自定义的下拉刷新库。补白和边距补白(Padding)指的是视图内部的内容与视图边界之间的距离,通常...

2019-10-22 23:05:39 1123

原创 不规则布局实现

布局控件继承自ViewGroup类,它可以包含多个控件并能够按照自己的规则排列控件的位置。不规则布局控件来自笔者开发过程中遇到的业务问题,设计人员希望客户端能够根据返回的数据条数不同而展示不同的布局样式,返回的数据可能有二三四五四种情况如下图所示,如果少于或多于二三四五就视为错误返回值不展示布局。在开发时考虑到当时的界面已经非常复杂,如果采用普通的布局嵌套方式实现会增加视图树深度,导致界面渲染速度...

2019-10-22 22:51:00 844

原创 自定义评分控件实现

评分控件在开发中算是使用率比较高的组件,Android自身也包含默认的评分控件,不过自带的评分控件可定制性并不高,现在就通过自定义View的方式来实现简单评分控件。自定义的评分控件继承自View类型,它需要覆盖View的三个构造函数:只带有Context类型的构造函数通常是开发者在代码中直接new创建,带有Context和AttributeSet的构造函数在LayoutInflater从XML中创...

2019-10-22 22:42:54 536

原创 Android视图绘制原理

Android中的图形界面通常都是由Activity负责展示,实际上Activity内部展示视图还分成了三大部件,最外层的Activity负责生命周期、应用上下文资源,最内层的View负责界面展示和用户触摸消息派发处理,中间层的Window负责界面设置、消息转发,粘合Activity和View对象,通过三层设计明确了每个部件的分工,而且由于Activity的Context上下文体系和View的视图...

2019-10-22 22:35:11 536

原创 Java简单线程池实现

需要开启新线程执行异步代码的时候通常都是new Thread()创建新的线程对象,创建线程过程中会向系统申请资源,造成任务启动变慢,直接开启的线程没有统一的管理机构,如果用户不断的创建新线程也没办法控制最多启动的线程数;直接开启的线程运行结束后还要做垃圾回收操作,影响整个应用的性能。针对这些问题Java类库中提供了线程池功能,在线程池中会预先分配一些启动好的线程对象,当用户有任务要执行时向线程池...

2019-10-20 23:12:05 220

原创 Android加载图片占用内存

图片在内存中的存储基于位图模式(通常也称作Bitmap),它把图片的长宽定义成多个像素点,每个像素点的颜色值有几个像素来保存,对那些尺寸比较大的图片一张可能就占据十兆左右的空间,应用只要多存储一些大尺寸照片就会导致内存溢出。Android的应用运行在JVM虚拟机上,每个JVM虚拟机进程分配的内存有限,这样才能保证多个应用同时运行时每个程序都有机会执行。系统究竟为每个应用分配的内存值大小是多少,Ja...

2019-10-20 23:01:45 726

原创 Java职责链模式

职责链模式中有多个能够处理请求的对象RequestHandler,这些处理对象按照先后顺序连接成一条处理链。在发送请求时只需要把请求传递给排在链表头部的RequestHandler对象,请求对象会在处理链内部传递最终由某个RequestHandler对象处理,也可能最终不处理。现在假设程序员(Programmer)遇到一个自己解决不了的问题,他会把问题交给自己的组长(Leader)帮忙解决,组长...

2019-10-19 21:12:05 143

原创 Android中异步消息和同步屏障

Android消息队列MessageQueue中加入的消息分成同步消息和异步消息,在平常开发中接触到的消息基本上都是同步消息,同步消息会被放到消息队列的队尾,Looper在消息循环时从队列头部不断取出同步消息执行。在Android系统中存在一个VSync消息,它主要负责每16ms更新一次屏幕展示,如果用户同步消息在16ms内没有执行完成,那么VSync消息的更新操作就无法执行在用户看来就出现了掉...

2019-10-19 21:07:15 2201 3

原创 Android内存泄漏问题

Java内存垃圾回收由专门的垃圾回收(Garbage Collector,GC)后台线程维护,自动回收机制减轻了开发者的负担,让开发者能够更加专注于业务功能的处理。GC回收已经相对比较智能,能够辨别出简单的垃圾对象和正常使用的对象,但是对于功能逻辑上的垃圾对象还是无能为力的,要想理解内存泄漏产生的原因需要对Java内存回收机制有一定的了解。在早期的系统中想要判断对象是不是垃圾对象通常使用数字引用...

2019-10-19 20:54:04 279

原创 Java线程可见性与原子性

有时候用户希望能够根据需要结束当前的任务,比如某个线程正在下载一个特别大的文件,已经花费了很长时间还是没有下载完成,用户希望取消整个下载操作;可以设置一个停止变量,线程在现在文件期间每读取1M的数据就检查一下停止变量的值,如果停止变量值被用户设置为true,那么就直接从下载任务中退出,否则继续执行下载任务。public class ThreadTest { private static boo...

2019-10-19 18:36:17 229

原创 Java多线程安全

多线程能够提高CPU的使用效率,为用户提供宏观上同时执行多个动作的效果,强大的功能背后也存在线程安全性问题。多个线程同时操作共享变量导致程序输出结果与设计者的初衷不符,编程过程中可以使用以下几种方式实现线程安全。锁同步机制在多线程中很常见的问题就是生产者与消费者问题,生产者负责生产对象并且将对象放到产品队列中,消费者负责从产品队列中取出并消费对象;产品队列是一个容量大小有限制的容器,如果生产出...

2019-10-19 18:14:32 161

原创 Android与Java Thread

Java语言中使用java.lang.Thread类代表线程对象,它继承了Object类型,并且实现了java.lang.Runnable接口,在JVM调度运行Thread的用户代码时就调用Thread.run()方法。在Thread对象内部还包含一个Runnable target对象,如果target对象不为空的话运行Thread.run()方法就会执行target.run()方法。publi...

2019-10-19 17:48:29 356

原创 Android JetPack架构组件介绍(二)

前面已经介绍了Room、WorkManager、Lifecycle、ViewModel和LiveData这些架构组件,接下来介绍Paging分页组件和Navigation导航框架,这两个类库在应用开发过程中也是非常常见的。Paging组件Android应用中列表是一种很常见的展现形式,多条数据展示就会使用多个界面元素,如果大量的数据一次性全部加入应用中会导致内存极度消耗,而且用户也很难一次性完...

2018-12-28 19:27:32 1117

原创 Android JetPack架构组件介绍(一)

Android在2018年的Google大会推出了Android JetPack工具库,这个工具库将常用的功能统一封装起来,提高开发者的开发效率,提高代码的复用性。目前JetPack主要封装的功能包含基础框架、应用架构、应用行为和UI界面四个方面,除了应用架构比较复杂外其他的使用起来都相对简单,这里主要介绍JetPack的架构组件功能。Room数据库框架Android的数据库是基于SQLite...

2018-12-28 14:28:50 3669 4

原创 AppCompatActivity内部生成AppCompatView源码阅读

前言AppCompatActivity中定义的控件可以很容易的支持各种新的特性,但是在源代码中使用的依然是普通的View对象,这里其实是AppCompatActivity在生成控件的过程中做了替换操作将普通的View替换成了CompatView类型。这种技术在很多换肤功能实现中经常会使用到,这里就通过代码阅读来了解具体的实现过程。代码分析AppCompatActivity继承自Fr...

2018-08-09 16:40:40 707

原创 GreenDao源码阅读

前言Android客户端的缓存通常都会放到SQLite数据库中,不过使用原生的API编写CRUD操作既费时又容易出现错误,项目中通常都会引入第三方的开源框架解决问题。GreenDao是一款优秀的ORM框架,只需要简单的配置框架会自动为我们生成DAO访问代码,现在就来简单阅读下它内部的源码实现。代码分析在配置好@Entity实体对象后生成代码,会发现指定的目录下会有DaoMaster...

2018-08-09 13:48:04 388

原创 Activity展示流程源码阅读

前言前面查看了Activity启动的整体流程,现在来看一看Activity里定义的视图树是如何展示到手机屏幕上的。首先开发者通常都会在onCreate里定义setContentView(布局文件ID),再运行Activity就能够将布局文件中的视图展示出来,在底层实际做做展示以及与用户交互都是有WindowManagerService(简称WMS)服务来进行的,与WMS做交互的主要是Windo...

2018-08-03 18:14:31 437

原创 页面折叠效果实现

前言Android手机屏幕相对较小,可能无法一次性将所有的元素都展示给用户,但有些情况下又确实需要将多个元素同时展示给用户。比如在外卖下单之后用户即希望能够查看当前外卖的状态也希望能够直接通过地图查看到外卖骑士的位置,地图控件和订单状态界面都很大,这时后可以通过折叠订单状态界面来展示更多的地图界面。除了上面描述的场景还有很多比如展示某些特殊菜单也可以使用这种交互方式,这里就来简单实现页面折叠效...

2018-08-02 17:45:17 5476

原创 ScrollView嵌套ListView问题解析

前言在MD设计出来之前ScrollView嵌套ListView是很常见的用来处理嵌套滑动解决方案,但是直接将ListView放入到ScrollView它只会展示一行,无法正常显示出一屏幕的的条目。现在通过阅读ScrollView和ListView的源码来查看这个问题出现的原因。代码分析我们知道View对象都需要经历measure、layout和draw三个阶段才能够展示出来,而Li...

2018-08-02 15:29:57 213

原创 自定义TextView实现

前言文本展示在Android开发中非常常见,大部分都是用TextView来实现,不过有些文本展示必须要手动调用Canvas来绘制,如果不了解绘制文本的原理很难把展示的文本对齐,这里就来记录一下文本绘制的各种技巧。文本测量在Android中调用Canvas绘制图形图像提供的坐标都代表对象的左上角位置,但绘制文本的坐标却不是左上角而是文本基线的左下角,下面的图详细展示了文本各个位置的对...

2018-08-02 10:17:38 3142 1

原创 CoordinatorLayout及Behavior实现源码阅读

前言MD设计风格引入了CoordinatorLayout布局,它能够协调子控件之间的操作,使得子控件相互能够做一些复杂的交互操作,这些交互主要通过Behavior对象来实现,这里就来查看一下Behavior和CoordinatorLayout布局实现源代码。代码分析首先查看Behavior的源码,它是CoordinatorLayout的一个内部抽象类,主要的接口可以大致上分成三组:...

2018-08-01 19:48:10 275

原创 Gitlab项目配置

前言Gitlab可以用来搭建Git仓库服务器端,具有很好的项目管理和用户管理功能,目前Gitlab服务端主要部署在Linux相关平台,Window平台还没有对应的部署包。笔者通过在VMWare Redhat Linux上安装Gitlab服务器来实现代码的版本控制功能,RedHat默认源由于GFW的问题都无法正常请求到Gitlab包,可以在百度上搜索清华Redhat源,很快就能够下载好需要的软件...

2018-07-13 20:04:01 6068

原创 手动生成APK文件

前言学习Android很长一段时间,一直都是使用开发工具生成APK文件,所有的Android打包过程基本上都是透明的,开发人员很难搞清楚底层的编译打包过程究竟是如何进行的。这里使用简单的只包含一个Activity和一个Service的手动打包来深入了解APK打包的每个过程。aapt资源打包打包最开始是处理资源和AndroidManifest文件,处理之后的各种资源会编译出一个R.j...

2018-07-05 21:09:11 4164

原创 Javassist分析类依赖和动态代理实现

前言Javassist作为一款强大的class编辑器,它能够读取class文件内容,class文件的常量池中包含了当前类所有需要交互的其他类。要获取当前类所有依赖的类,只需要先获取当前类直接依赖的类,再继续广度优先遍历直接依赖类依赖的类,最终遍历了整棵依赖树之后就能获取当前类依赖。对于动态代理其实也是通过在运行过程中动态新的代理类,代理类不但会增加额外的用户逻辑,还会调用被代理对象的对应方法,...

2018-07-05 19:18:44 1765

原创 Javassist基础使用

前言Javassist是日本人开发的一款编辑class字节码框架,可以用来检查、动态修改及创建Java类。与JDK自带的反射功能相比Javassist功能更加强大,熟练使用Javassist工具对提高Java动态编程有着重要意义。常用类ClassPool:javassist的类池,使用ClassPool 类可以跟踪和控制所操作的类,它的工作方式与 JVM 类装载器非常相似。 Ct...

2018-07-05 18:02:28 1060

原创 Java Class文件格式简析

前言Java开发只需要编写Java代码之后通过javac命令将其编译成.class文件,.class文件可以被JVM虚拟机加载并执行。如果需要Java能够像动态语言那样编码,通常需要修改.class文件的内容,这种情况下了解.class文件的内部结构就很有必要。类文件查看Java的class文件内容大致上包含如下的各种结构,如果某个节点有多个会被表示成数组结构,数组的长度通常都在实...

2018-07-04 20:40:33 3248 1

原创 Smali简介和实现类外调用父类方法

前言通常基于Java语言开发程序都是通过调用javac编译器将源代码编译成.class文件,这种文件能够被JVM识别,加载并执行的文件格式(除了常见的java源代码生成的class文件,其他的Scalar、Python和Groovy等语言都可以生成class文件,每个类和接口都单独占据一个class文件)。不过class文件内存占用量大,不适合移动端,采用堆栈的加载模式,文件IO操作多,cla...

2018-07-04 17:30:36 1504

原创 Java内存模型简析

CPU多级缓存CPU的存储速度远远高于内存的访问速度,为了匹配CPU的高速度加入了一级缓存,但是由于高速缓存很贵容量比较小,后来又增加了容量稍大的二级缓存。缓存的存在理论主要依靠程序的时间和空间局部性原理提供支持:时间局部性:如果某个数据被访问,那么在不久的将来它很可能再次被访问。空间局部性:如果某个数据被访问,那么与它相邻的数据很快也会被访问。CPU多级缓存的缓存一致性:MES...

2018-06-07 09:58:59 183

原创 Java NIO基础使用

前言Java中的输入输出操作主要针对数据文件和Socket对象,传统的Java IO操作都是阻塞进行的,比如在读取网络数据的时候如果数据还没有返回那么read方法就会被阻塞一直等到网络数据返回或者发生错误,再读取的时候也采用流式读取数据。在Java1.4中引入了NIO处理输入输出,NIO采用内存映射文件的方式将文件或文件的一段映射到内存中,同时它使用块IO来处理数据效率更高。缓冲区...

2018-06-06 18:59:07 2328 2

原创 JVM简单总结

前言Java虚拟机使用软件模拟Java字节码的指令集,它只是一个可以运行Java代码的假想计算机,JVM实际上运行在操作系统之上,它与硬件没有直接的交互。用户编写的Java代码通过编译器生成class文件,之后通过JVM的类加载组件加载到内存中并且存放在方法区中,用户需要创建类的实例需要根据方法区里的数据创建Class对象,生成对应的类对象,执行的代码由JVM的执行引擎转换成本地代码执行。...

2018-06-05 20:31:13 235

原创 Java垃圾回收机制

前言Java语言比C/C++语言更加用于友好重要的一点就是垃圾回收机制,C/C++语言在堆内存分配的资源必须开发这手动删除,如果开发者忽略了这一点就会导致内存泄漏,程序可用的内存空间越来越少,最后没有内存资源可用导致应用失败。Java的自动垃圾回收功能会始终在后台有一个垃圾回收线程,过一段时间检查内存中不再使用的垃圾内存将它们释放返回到堆内存中,这一特性将程序开发者从内存管理中解脱出来,可以将...

2018-06-04 10:55:33 194

原创 Java synchronized简析

前言在Java并发编程里synchronized关键字一直都有着重要的地位,在Java中任何对象都可以作为锁对象,对于普通的方法锁定的是当前实例对象,对于静态方法锁定的是当前的类对象,对于同步代码块锁定的是括号里的对象。最开始synchronized的实现是采用底层操作系统的互斥锁实现,这种锁需要在内核和用户态之间切换效率非常的低,不过在1.6版本引入了大量的优化,使得synchronized...

2018-06-03 19:35:42 133

原创 FutureTask源码阅读

前言在学习ThreadPoolExecutor我们提到过submit提交的任务会被封装成FutureTask类型之后再放到线程池中执行,FutureTask类代表了异步执行的结果对象,用户可以使用它来获取、查看和取消异步请求。public interface Future<V> { boolean cancel(boolean mayInterruptIfRunni...

2018-06-03 02:16:18 1850

原创 ThreadPoolExecutor基础使用

前言Android开发中由于禁止在主线程中做网络请求,通常都需要使用线程对象来做异步请求操作,但是直接使用new Thread();创建新线程需要不停的申请系统资源,这些野生的线程缺乏统一管理,相互竞争占用过多系统资源;直接使用普通的线程做定期执行和线程中断等功能特别容易出错,为此 J.U.C类库里添加了功能强大的Executor框架,它能够为用户程序提供强大的线程池实现。使用JDK自带的线程...

2018-06-02 23:26:37 430

原创 Java死锁问题简析

前言在多线程编程中死锁是一个常见的问题,我们都知道死锁的出现有四个必要条件:资源互斥使用,也就是说每个资源一次只能有一个线程使用;占有并请求,所有的线程都持有它们目前请求到的资源并且申请还未得到的资源;不可剥夺,也就是说所有线程请求到的资源都无法被其他线程抢占;循环等待,也就是线程之间互相等待对方释放己方需要的资源。这里先通过Java代码实现简单的死锁问题,然后通过一个银行转账的示例学习如何预...

2018-05-31 20:44:11 283 1

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除