自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

FritzXu的博客

要把事情做得更好,你要先把自己变得更好

  • 博客(53)
  • 资源 (2)
  • 收藏
  • 关注

原创 带着问题去看下 Lifecycle 源码

在写完上篇 带着问题去看下ViewModel源码 之后,虽然将 ViewModel 都交代清楚了,不过最基础核心的 Lifecycle 组件 部分并没有进行说明,因此这篇就专门说一下 Lifecycle 组件,下面开始正文Lifecycle组件 的使用使用 Lifecycle 组件的话,我们可以相对轻松去响应指定组件( 通常都是 Activity )的生命周期变化,因此利用 Lifecycle 组件,我们可以避免在 Activity 等组件 的生命周期回调中写大量管理组件的代码,进一步精简了我们的项目代

2021-04-22 20:19:16 261

原创 带着问题去看下ViewModel源码

ViewModel 可以监听到当前 Activity 的 onDestory 方法来自动切断与 Activity 的联系,并且回调 ViewModel 里面的 onClear 方法,方便 使用者 去进一步去释放数据,不得不说这是一个很实用的利器那么问题来了:ViewModel 是怎么去监控 Activity 的生命周期的?这个是一个面试题目,Activity 屏幕旋转后,Activity 经历了销毁和重新创建后,为什么 ViewModel 没有销毁,而是沿用之前的 ViewModel 对象呢?.

2021-03-26 00:44:26 322

原创 关于 Gson 容错的思考

最近项目中遇到了两个 Json 解析的坑,一个是后端没有按照约定返回对应类型的字段,文档说明写了 int ,但是它直接返回了 String 类型;另外一个数据请求成功后, data 是一个 Object 类型,但是如果数据请求失败,后端直接返回了 List因为这两个坑,后端周末紧急加班去发版本, 不过就勾起了我对 Gson 容错的方案思考Gson 源码的分析要解决业务方的需求,客户端这边想法子做一定的 Json 容错,那么就必须去了解一下 Gson 的源码了先看下 Gson 的日常用法:Gso.

2021-01-31 23:57:04 361

原创 记一个使用系统相机拍照后照片被旋转的问题

最近在做项目的自定义相册时,遇到了这么一个问题:从 小米9 手机上面的拉起系统相机进行拍照,然后上传到服务器上面,发现图片莫名其妙就旋转了 90° ,这个并不符合业务方的需求,在仔细分析后,发现拍照后,系统保存到本地的照片已经给旋转过了因此要解决这个问题,就只有在拍照后,判断图片是否给旋转,如果有,就将它旋转回去要获取图片的旋转信息,其实就是要获取图片的 Exit 信息,它里面存储了图片的全部参数,我们可以通过 ExifInterface 来获取到这个数据:/** * 读取图片的旋转的角度 *.

2020-12-06 22:51:32 2393 5

原创 Android增量更新

现在国内的各大应用市场都有省流量更新的功能,只需要你将最新版本的 apk 上传到它们的应用市场上面进行更新,用户在通过应用市场更新应用时,都可以看到体积较小的升级包,这背后的技术,就是增量更新增量升级的基本流程:用户手机上面已经安装的目标应用,它的版本号为 1,而目前该应用的最新版本的版本号为 2将版本号为 1 和版本号为 2 的两个目标应用的安装包,进行差量对比,得到一个差分包(这个就是增量包)版本号为 1的应用和增量包进行合并得到版本号为 2 的安装包,并进行覆盖安装从上面的流程就可以.

2020-05-17 23:54:46 294

原创 迟来的2019的年终总结

对我来说,2019年是一个充满变化的一年遇到了不少好事,也有一些坏事,也有一堆我不知道它以后是好事还是坏事的事情生活上的最大变化就是,宝宝学会跑了,这是件好事,同时也让我对 [照顾] 二字,有了更深的体会,庆幸老婆能这么容忍笨拙的我也开始明白了一些生活的意义,每天除了工作,你需要多思考其实你还有家人的。虽然因为工作的原因,我平时只有周末在家,但是只要条件允许,我必定是尽量早点回到家,然后尽...

2020-02-05 23:20:46 334

原创 Glide 的 transformation

Glide 里面内置了一套图片改造机制,名叫 Transformation ;利用这套机制,我们可以轻松实现以下的效果:调用的方法也很简单,就拿其中一个来举例:RequestOptions requestOptions = new RequestOptions() .transforms(new CenterCrop(), new CircleCrop());Glide.with(t...

2019-12-15 11:16:49 1324

原创 Fragment 的 getActivity() 为什么会返回null

这个是同事询问我的一个问题:明明 Activity 没有给销毁,为什么 Fragment 的 getActivity() 有时候会返回一个 null 呢?在解答他的疑问之后,也在博客中记录一下Fragment的生命周期我们先通过打印来看下 Fragment 各个生命周期里面, getActivity() 是否会返回了 null :public class TestFragment e...

2019-09-13 16:53:06 696

原创 View绘制的一问一答

最近从网上收集了一些 View 绘制的面试题来做练习,算是温故而知新了1.View 的绘制流程是从哪里开始的?哪个过程结束后,我们才能看到 View 的显示?View 是个抽象类,它在内部封装了测量(measure),布局(layout)和绘制(draw)的方法,但是以上方法的触发都是交给上层 ViewRootImpl 来的,View 整体的绘制流程如下:ViewRootImpl(它处...

2019-08-07 00:08:01 236

原创 在 Dialog 或 Popupwindow 中修改activity的光亮度

我们平时使用的 Dialog 和 Popupwindow 在出现时都会让手机屏幕变暗,但是某些时候我们需要它不要变暗或者变得更加暗应该怎么办呢?这时候就需要修改 Activity 的透明度参数了: /** * 设置Activity的透明度 */ private void setUpWindowAlpha(float alpha) { //获取act...

2019-06-30 00:02:21 226

原创 View与Activity之间不可不知的关系

最近因为工作需求,需要搞明白 Activiy 与 View 之间的一些生命周期关联的情况,于是这里做一个详细的记录View 和 Activity 一样也是有着自己的生命周期方法,熟知这些生命周期方法对我们日常开发绝对会有不少帮助的(比如我最近遇到的一些自定义 View 的需求),下面我们通过自定义一个 View 来打印它的全部生命周期方法吧:public class LifeView ex...

2019-06-16 15:37:43 491

原创 Glide源码分析之如何获取到View的宽高值

我们知道 Glide 默认会依据传入的 View 的宽高来裁剪图片的宽高,那么 Glide 是怎么拿到 View 的宽高值的呢?我们带着疑问,看下源码吧在 Glide.with(FragmentActivity).load(URL).into(imageView); 这个过程中,我们在 into 里面传入了 ImageView ,通过查看源码:public ViewTarget&lt...

2019-06-08 22:44:37 720

原创 Glide源码分析之load方法

这里承接上篇 Glide源码分析之with方法 ,这篇将对Glide.with(FragmentActivity).load(URL).apply(centerCropTransform()) .into(imageViewRes); 中的 load 方法进行分析(PS:本人阅读的源码为 Glide 4.7 版本)先贴出 load 方法的时序图:接着就来依据这个时序图来阅读源码吧S...

2019-05-02 14:00:01 999

原创 SharedPreferences的分析与实践

SharedPreferences 是 Android 里面一个轻量级别的存储方案,不过随着项目的发展,SharedPreferences 使用不当,也很容易引发一些问题,甚至会导致 Crash 的发生因此,我们有必要搞清楚 SharedPreferences 的基本原理SharedPreferencesSharedPreferences 的本质是一个基于xml文件存储的key-valu...

2019-04-28 00:12:07 295

原创 Glide源码分析之with方法

Glide 是一个开源的图片处理库,源代码的学习对于我们的帮助是非常大的,不过要看源码项目总得有个流程,这里我就从 Glide.with(FragmentActivity).load(URL).apply(centerCropTransform()) .into(imageViewRes); 作为阅读流程,首先就从 with(FragmentActivity) 开始开始吧。...

2019-04-16 14:28:40 840

原创 Glide里面的几个线程池

一.概述在日常开中,如果经常使用到线程的话,如何快捷创建和关闭回收线程是一件较为麻烦的事情,因此 阿里巴巴的Java规范插件 一直都是建议使用线程池来管理线程使用线程池有那些好处?复用存在的线程,减少线程的创建,减少线程的开销,进一步提高了效率通过阻塞队列来控制最大的线程并发数,让内存等消耗限制在一个合理的范围内二.线程池的相关参数我们要怎么使用线程池呢?我们先来看下线程池参数最全...

2019-03-31 00:09:43 6063 2

原创 Android中获取TextView一行最多能显示几个字

日常工作中,我们有时候需要知道一个 TextView 一行最多显示几个字符,这里提供两个方法(这两个方法都需要知道 TextView 的宽度)方法一: /** * 获取textview一行最大能显示几个字(需要在TextView测量完成之后) * * @param text 文本内容 * @param paint textview.g...

2019-03-24 16:15:56 7867

原创 对 Drawable 的一些分析

Drawable 在日常开发中经常用到,我们经常用它来给 View 设置背景图片,它到底是怎么做到的呢?这篇就带大家去了解一下先看个例子我写过一篇 Android绘制圆形图片的3个方法 ,这里就用里面的一个demo来用下:public class CircleHeadView extends View { private Paint mPaint; .... { ...

2019-03-16 13:58:09 187

原创 JavaScrip里面的this

JavaScrip 里面的 this 到底指向哪里?它是一个很特别的关键字,被自动定义在所有函数的作用域中,是 JavaScrip 的一种上下文机制通常我们会以为 this 是指向函数或对象自己,但事实并非如此,this 实际上是在函数被调用时发生的一个绑定,它指向什么完全取决于函数在哪里被调用,并非我们一开始所想的那样,我们可以看下下面的例子:指向一个对象:function foo()...

2019-02-23 23:51:51 156

原创 记录React 组件的生命周期

React 严格定义了组件的生命周期,一般来说 React 的生命周期经历如下 3 个 阶段:装载过程(Mount),也就是把组件第一次在 DOM 树中渲染的过程更新过程(Update),组件重新渲染的过程卸载过程(Unmount),组件从 DOM 中删除的过程上面的 3 个阶段,React 库会依次调用组件的一些成员函数,这些成员函数就是 React 的生命周期函数,我们对 Reac...

2019-02-21 00:09:38 188

原创 Android绘制圆形图片的3个方法

在日常开发中,我们经常需要用到圆形图片,最近总结了3个绘制圆形图片的方法,在这里总结一下BitmapShaderBitmapShader 是 Shader 的子类,Shader 是 画笔的着色器,是用于给画布着色,利用 BitmapShader ,我们可以给画布绘制一个圆形图片:public class CircleHeadView extends View { privat...

2019-02-13 22:08:11 3522

原创 React 的 PropTypes

在 React 中,prop 是从外部传递给组件的数据,可以说是组件对外的一个接口属性,它也是应该有对应的规范的,比方说:这个组件支持哪些 prop每个 prop 应该是怎么样的格式而 React 是通过 propTypes 用来规范 prop 必须满足某种规格,如下所示:export default class MyComponent extends Component { //...

2019-02-03 23:20:31 1229

原创 Python 中的字典

Python 中的字典就是一系列的键值对集合,与键相关联的值可以是数字、字符串、列表乃至字典等一切元素,我们可将任何 Python 对象用作字典中的值在 Python 中,用方括号({ })来表示列表,键和值之间用冒号分隔,而键值对之间用逗号分隔,如下所示:python_dist = {"one": 1, "two": 2}(注:你可以理解 Pyhton 中的字典为 Java 的 Map)...

2019-01-22 23:19:24 710

原创 Python 的元组

列表用于存储在程序运行期间可能变化的数据集,然而,有时候你需要创建一系列不可修改的元素,这时候就需要用到元组了Python 将不能修改的值称为不可变的,而不可变的列表被称为 元组1.定义一个元组元组有着列表的基本要素,但是元组里面的元素是不可修改的在Python中,用括号 () 来表示元组,并用逗号来分隔其中的元素,如:python_array = (200, 404, "Python"...

2019-01-14 21:59:08 252

原创 Python 的列表

1.列表是什么Python 里面的列表由一系列按特定顺序排列的元素组成,它可以包含字母表中所有字母、数字0~9或所有家庭成员姓名,我们可以将任何东西加入列表中,列表其中的元素之间可以没有任何关系在 Python 中,用方括号(** [ ] **)来表示列表,并用逗号来分隔其中的元素,如下所示:Python_list = [1,2,3,4,5,6]Python_strings = ["one...

2019-01-13 13:47:22 161

原创 高效易用的okio(四)

超时机制在我们的日常生活中随处可见,最为常见就是火车了,如果你不能按时到达火车站点,那么你就错失坐这一趟火车的机会在前面的文章,就已经提到过 okio 中的有一个超时机制 Timeout, 现在就来说说它的原理okio 中的超时机制只要就两种:同步超时 Timeout异步超时 AsyncTimeout还有一个超时对象 ForwardingTimeout ,不过这个属于一个空盒子,需要...

2019-01-05 14:29:13 800

原创 高效易用的okio(三)

在上篇 高效易用的 okio(二) 的结尾提到了 Segment ,这是一个内存缓冲区, IO 读写操作能如此高效,都是通过这个 SegementSegement 本质是一个字节数组,同时也是一个循环双向链表,同时为了提高效率,okio 还提供了一个 SegmentPool 用于存储空闲状态的 Segment 用于复用,它们构成了 okio 高效的内存使用政策,它们的关系如下图:Segmen...

2019-01-01 21:47:58 286

原创 Gson 处理空字符串的一个小技巧

在项目开发的过程中,经常会遇到空字符串的 json,为了避免遇到空指针的问题,我们往往要进行字符串的判空处理,不过如果是使用 Gson,则可以通过自定义 TypeAdapter 来处理空字符串的问题定义一个处理空字符串的 TypeAdaper: public class StringNullAdapter extends TypeAdapter<String> { ...

2018-12-27 23:10:57 3996

原创 Android Studio 自定义模板

前言在开发 Android 项目的过程中,难免会遇到重复编写同一段逻辑的代码的情况,就拿目前比较流行的 MVP 模式来举例好了,要实现一个页面的 MVP 开发,我们需要编写以下的类:一个 MVP 的契约接口,里面有一个 view 层接口 和 P 层的接口(或抽象类)对应的view 层接口的实现类对应的P 层接口的实现类对应的 model 层如果当前页面需要使用 RecyclerVi...

2018-12-23 21:56:05 402

原创 高效易用的okio(二)

在上篇文章中,我们知道了一些 Java IO 的概念,也了解了 okio 的用法,现在我们来分析一下源码Okio我们回到上篇的代码: Source source = Okio.source(new File(mPath)); String read = Okio.buffer(source).readString(Charset.forName("utf-8"));显而易见 Okio...

2018-12-15 00:55:53 409

原创 高效易用的okio(一)

okio 作为 okhttp 的底层 IO 库,对比 Java 的原生 IO ,提供了更灵活易用的API 来处理数据流的输入和输出,某程度上,我们可以放弃 Java 的原生 IO,转为使用 okio 作为 日常开发的 IO 框架Java 的原生 IO在正式介绍 okio之前,我们有必要先来回顾一下 Java IO 的一些基础知识程序内部和外部进行数据交互的过程,这个输入输出(input/ou...

2018-12-10 22:04:47 804

原创 okhttp的拦截器

okhttp 其实就做了 3 个操作,分别是 请求(call) ,TCP 连接(Connection) ,数据流(okio),这 3 个操作都是通过 okhttp 的拦截器来完成的okhttp 的拦截器到底是有些,我们可以在 opkhttp3/RealCall 里面的一个方法看到:Response getResponseWithInterceptorChain() throws IOExc...

2018-12-03 21:49:50 181

原创 Java 中的代理模式

为其他对象提供一个代理对象,从而让其他对象操作该代理对象来间接完成对某个指定对象的访问,这个就是代理模式。而在 Java 中,针对代理对象的创建方式,又划分了 静态代理 和 动态代理静态代理代理模式的一个特征就是 代理类和指定对象有着同样的方法调用,因此一般都是通过接口来设计代理模式。首先定义个接口:public interface Subject { void req...

2018-11-25 23:14:46 125

原创 动手写一个AspectJ的gradle插件

越是深入学习 Android ,就越发感觉到 Gradle 这个构建工具十分强大, Android 插件化都是依赖于 Gradle ,因此有必要学会怎么用 Gradle 来编写插件,从而进一步去理解 Gradle 的自动化构建过程。 由于我同时对 AspectJ 十分感兴趣 ,这里就总结一下我是如何把 AspectJ 做成一个 Gradle 插件 的过程。Gradle 插...

2018-07-28 18:59:30 765 2

原创 集成 Jenkins 自动化打包 Android Apk

在最近的 Android 开发中,每次发布版本都要手动打包,深感到不便,为了让测试的人员也可以感受到 Android 打包的乐趣,参考了网上很多 Jenkins 进行 Android 自动打包的文章后,花了一些时间把这个环境搭建起来了。Jenkins 安装Jenkins 的可以单独运行也可以在 Tomcat 服务器中运行,不过我这里是单独运行的,首先就要到 https://je...

2018-07-24 22:46:22 1051

原创 Glide之外层生命周期监听的方法

Glide 一个重要的特点就是通过一个透明的 Fragment 来感知外层 Activity 或 Fragment的生命周期,在 onStart 方法里面启动网络请求,onStop 里面暂停请求,onDestroy 里面解除监听并释放内存。 那么,Glide 是怎么做到这个监听事件的?用于监听的接口Glide 里面用于监听生命周期的接口总有两个,它们分别是 Lifec...

2018-07-08 18:45:47 1086

原创 认识Http的缓存策略

这篇以前在简书写的blog,由于已经不会在简书写东西了,就搬过来这边。 我们日常开发经常和网络打交道,从服务器上面获取数据。但是如果我们如果在短时间内多次向服务器请求的数据其实都是一样的,我们是没有必要这么浪费用户的流量的。为了提高用户的体验,我们需要合理使用缓存,要使用缓存就得搞明白缓存的一些相关策略机制,于是就有了这篇文章。Http的缓存机制我们可以先看下面的思维导图...

2018-06-30 18:43:46 1409

原创 说说Handler的一些使用姿势

Handler大家应该都很熟悉了,毕竟只要是涉及到Android里面线程间的通讯,总会看到它的身影。我平时也经常使用Handler,今天整理笔记,就将之前记录下来的Handler的一些使用姿势发到这里来。1.在子线程中创建Handler对象这个可能比较少见,一般都是在主线程创建Handler对象。不过少见不代表我们以后不会遇到。 按照我们平时在主线程创建Handler对象的习惯,代码...

2018-06-30 18:31:06 984 1

原创 DataBinding的双向绑定

这篇之前在简书上面发布的blog,由于不打算在简书上面写东西了,就搬过来这里。之前曾经发布过一篇blog来记录之前使用DataBinding的一些心得体会,当时对于DataBinding的双向绑定简单提了一下。现在对这个双向绑定有了进一步的了解,于是继续分享。回顾我们先来回顾一下之前双向绑定的做法:<EditTextandroid:layout_width="m...

2018-06-30 18:23:18 4864

原创 DataBinding的使用心得

这篇以前在简书写的blog,由于已经不会在简书写东西了,就搬过来这边前言在项目中使用到了DataBinding,深感它的优秀,于是进行分享。什么是DataBindingDataBinding,数据绑定,可以直接在xml中绑定数据并实现一些处理逻辑,实时动态刷新数据。它的功能强大,可以节省很多手写的代码,而且性能也很好。DataBinding的优点和缺点优...

2018-06-30 18:21:18 2494

一个mvp的代码模板

一个mvp的代码模板,模板的内容仅供个人参考,因为每个人的模板都可能是不一样的,适合自己的模板才是最好的

2018-12-23

动手写一个AspectJ的gradle插件

动手写一个AspectJ的gradle插件的demo,详细说明了怎么创建Gradle插件和AspectJ的一些使用方法

2018-07-28

空空如也

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

TA关注的人

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