自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

赵彦军

做一只快乐的程序猿!

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

原创 Git 可视化工具 Fork 使用指南

最近遇到一个新项目,经过数年的积累,大概有 30000 个分支,用可视化工具打开直接卡死。由于分支实在是太多了,一般的可视化工具,直接卡死,比如 就直接卡死,测试了很多软件,最终 Fork 脱颖而出,可以完全胜任几万分支的情况。fork: 一款 git 可视化工具官网:https://git-fork.com/下载:https://cdn.fork.dev/mac/Fork-2.18.dmg把文件从 移动到 注意:被选中的 commit 都会被合并到前一个 。所以 合并到 合并结果:Dro

2022-06-05 19:41:28 14024 5

原创 Android中使用 Protobuf

Protobuf,类似于json和xml,是一种序列化结构数据机制,可以用于数据通讯等场景,相对于xml而言更小,相对于json而言解析更快,支持多语言。Protobuf使用 文件来定义数据格式,所以我们首先新建立一个文件,并在文件中填下如下内容:这样我们就定义好了一个基本的Person对象,下面我们对文件中的关键字进行一一说明:syntax:指定proto的版本,protobuf目前有proto2和proto3两个常用版本,如果没有声明,则默认是proto2.package:指定包名。import:导

2022-06-03 22:30:38 4288

原创 Android自定义View Paint

转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/123524086本文出自【赵彦军的博客】文章目录画笔模式画线条画圆画矩形画弧形其他清空画笔样式画笔模式mPaint.setStyle(Paint.Style.FILL); //设置画笔模式为填充STROKE //描边FILL //填充FILL_AND_STROKE //描边加填充实验代码Paint paint = new Paint();paint.setCol.

2022-03-16 15:35:25 4092

原创 Android硬件加速

Android 硬件加速原理Android 硬件加速原理理解Android硬件加速原理的小白文硬件加速控制(Controlling Hardware Acceleration)android提供了以下四个级别的硬件加速控制:ApplicationActivityWindowViewApplication级别在应用的Android清单文件中,把下列属性添加到元素中,能够开启整个应用程序的硬件加速:<application android:hardwareAccelerated=

2022-03-08 11:40:05 6078

原创 Android骨架屏实现方案

Skeletonhttps://github.com/ethanhua/Skeleton依赖引入buildscript { repositories { jcenter() }}allprojects { repositories { jcenter() }}dependencies { implementation 'com.ethanhua:skeleton:1.1.2' implement

2022-03-07 11:30:58 3666

原创 Android通过Scheme协议打开APP界面

转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/123238777本文出自。

2022-03-03 14:21:48 10605 1

原创 Android Bitmap 研究与思考(中篇)

文章目录质量压缩采样率压缩矩阵缩放RGB_565压缩createScaledBitmap 压缩BitmapFactory.Options 属性介绍bitmap 保存为文件文件转为 bitmap高效加载大位图bitmap 转为 drawabledrawable 转为 bitmap总结质量压缩 private fun compressQuality() { //把 drawable 转成 bitmap val bm = BitmapFactory.decodeResourc

2022-02-25 17:48:09 1217

原创 android gradle自定义钉钉群提醒

今天接到一个需求,写一个 gradle 小插件,在执行完某个 gradle 任务后,向钉钉群聊机器人发送一条消息,并自动 @所有人。首先在钉钉群中创建智能机器人,并获取到 Webhook 链接有了 Webhook 链接就可以给机器人发消息了。下面我们来自定义 gradle 工具。在项目的跟目录创建 dingding.gradledingding.gradle 代码如下:import groovy.json.JsonBuilderimport groovy.json.JsonOutput

2022-02-16 20:10:04 1470

原创 Shell脚本学习笔记

什么是 ShellShell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。Shell 既是一种命令语言,又是一种程序设计语言。Shell 脚本Shell 脚本(shell script),是一种为 shell 编写的脚本程序。Shell 环境Shell 编程跟 JavaScript、php 编程一样,只要有一个能编写代码的文本编辑器和一个能解释执行的脚本解释器就可以了。Shell 语法打开文本编辑器(可以使用 vi/vim 命令来创建文件),新建一个文件 test.sh,扩

2022-02-14 15:55:04 529

原创 Android如何实现全局的护眼模式

最近接到一个做护眼模式的需求,要求是在Android App 全局,在任何一个页面都显示。在做需求之前要先弄清楚几个概念蓝光短波蓝光是波长处于400nm-480nm之间具有相对较高能量的光线。该波长内的蓝光会使眼睛内的黄斑区毒素量增高,严重威胁我们的眼底健康。蓝光诱发致盲眼病,最有效的解决方案是对电视进行贴膜处理。防蓝光贴膜技术已经很成熟,成本很低,可以有效阻止蓝光穿透。在这里,特别提出一点,蓝光并不都是有害蓝光,真正有害的是波长400到450以内的蓝光,而480到500纳米之间的蓝光有一种调整生物

2022-02-11 17:26:33 2692 1

原创 Android使用suspendCancellableCoroutine将回调转换为协程

普通的回调函数:interface Result<T> { fun onSuccess(t: T) fun onFailed(e: Exception)}回调方法,模拟耗时操作 fun longTimeMethod(result: Result<String>) { thread { Thread.sleep(5000) if (System.currentTimeMillis() % 10

2021-12-21 11:27:38 4234

原创 Android 图片加载框架Coil使用总结

文章目录简介简单使用高斯模糊圆角圆形灰色变换 GrayscaleTransformationGif监听下载过程取消下载替换 okhttp 实例自定义Coil 源码分析简介Coil 是一个 Android 图片加载库,通过 Kotlin 协程的方式加载图片。特点如下:更快: Coil 在性能上有很多优化,包括内存缓存和磁盘缓存,把缩略图存保存在内存中,循环利用 bitmap,自动暂停和取消图片网络请求等。更轻量级: Coil 只有2000个方法(前提是你的 APP 里面集成了 OkHttp 和 Co

2021-12-20 16:20:28 7288

原创 Kotlin reduce、fold

reduce从集合左到右,依次计算每个元素累加的结果示例1:val array = intArrayOf(1, 2, 3, 4, 5)val result = array.reduce { acc, i -> acc + i}Log.d("yyy-ppp", "$result") //结果:15示例2:val array = arrayOf("a", "b", "c", "d", "e")val result = array.reduce { acc, i -&g

2021-12-16 15:05:14 1814

原创 Kotlin协程重新认知 CoroutineContext

文章目录前言2. CoroutineContext类图一览3. CoroutineContext接口4. Key接口4. CoroutineContext.get方法5. CoroutineContext.plus方法6. CombinedContext分析7. 五种plus场景8. CoroutineContext的minusKey方法9. 总结前言如果你对CoroutineContext不了解,本文值得你细细品读,如果一遍看不懂,不妨多读几遍。写作该文的过程也是我对CoroutineContext

2021-12-16 14:23:47 636

原创 kotlin 协程异常处理机制颠覆三观

文章目录协程树与结构化并发协程作用域的cancel协程的cancel状态清理协程的返回值协程异常的处理结构化并发的异常处理协程的异常处理CoroutineExceptionHandler协程的异常处理与OKhttp、RxJava这些框架的处理方式都不太一样,因为异步代码的异常处理,往往是比较麻烦的,而到了同步化处理的协程框架下,异常就变得比较容易进行管理了。要完全理解协程的异常,我们需要先理解协程的树形结构和结构化并发,在这基础上,就能很容易的理解协程是如果管理异常的了。协程树与结构化并发在协程作用

2021-12-14 20:23:09 1715

原创 Android StateFlow详解

文章目录一、冷流还是热流StateFlow1. StateFlow使用2. 和LiveData比较3. 如何解决开头的问题简单描述一下:点击图中的皇冠按钮,会弹出 Nike、Adidas 和 其他 品牌的按钮,选中之后,页面中数据源只会包含该品牌的数据。简单看一下,原来的结构,使用的 LiveData:class MainViewModel : ViewModel() { private val selectedBrand = MutableLiveData<String>()

2021-12-13 20:25:59 6297 1

原创 Android SharedFlow详解

文章目录什么是SharedFlow实战默认无粘性什么是SharedFlowSharedFlow 是一个接口,继承 Flow在使用是,一般使用 MutableSharedFlowSharedFlow 有如下特点:1、是热数据流 ,及时没有接收者,也会发射数据2、SharedFlow 是 StateFlow 的可配置性极高的泛化数据流。3、可以有多个接收器,一个数据可以被多个接收实战class MainActivity : AppCompatActivity() { priva

2021-12-13 19:31:46 8083 2

原创 OkHttp ResponseBody没有关闭造成的内存泄漏

在网络请求中,ResponseBody 用完时需要关闭的。日常开发中,我们需要操作的不多,是因为常用的框架已经做好了。response.body().string() 的 string() 方法已经自动关闭资源。类似的方法还有:response.body().bytes() 也会自动关闭再比如常用的 GsonConverter ,会把 ResponseBody 转成 Bean 对象,也会自动关闭 。...

2021-12-13 14:45:09 3243

原创 Android复盘OkHttp HttpLoggingInterceptor造成的OOM

文章目录前言HttpLoggingInterceptor 简介下载文件请求阶段需要等很久以及OOM前言最近项目中发生了很多 oom,通过 oom 日志分析来看,都跟 okhttp 有关。经过艰难的分析定位,终于发现了造成 oom 的凶手HttpLoggingInterceptor 。原因是 HttpLoggingInterceptor 作为 okhttp 请求的过程的日志输出工具, 会把 ResponseBody 里面内容全部读出来,放在内存里。对于普通的网络请求,影响并不大。但是对于下载来说,它会把

2021-12-13 14:13:19 2436 2

原创 Android Kotlin Flow 如何使用callbackflow

首先我们来看一个例子:我们有一个网络接口,在耗时3秒后会回调一个结果,把结果 3 ,回调出去。代码如下: /** * 模拟网络请求 */ fun requestApi(block: (Int) -> Unit) { thread { Thread.sleep(3000) block(3) } }如果我们要把这个用 Flow 的形式把结果发送出去改怎么写:

2021-12-09 19:47:14 5280 1

原创 Android Flow遇见Retrofit网络请求实践

方式一:RetrofitFlowCallAdapter添加 RetrofitFlowCallAdaptergithub地址:https://github.com/zyj1609wz/RetrofitFlowCallAdapter//添加maven地址allprojects { repositories { maven { url 'https://jitpack.io' } }}//添加依赖implementation 'com.github.zyj1609w

2021-12-08 11:52:17 3733 4

原创 Retrofit 注解参数详解

文章目录GET@Path@Query@QueryMapPOST@Bodyform表单1:@FormUrlEncodedform表单2:FormBody@Multipart上传文件对Retrofit已经使用了一点时间了,是时候归纳一下各种网络请求的service了。下面分为GET、POST、DELETE还有PUT的请求,说明@Path、@Query、@QueryMap、@Body、@Field的用法。添加依赖implementation 'com.squareup.retrofit2:retrofit

2021-10-28 15:54:54 1013 2

原创 Android 断点续传实现原理

下载原理在介绍断点续传之前,我们先说说下载的原理。代码示例用 OkHttp 作为示例。下载核心思路是把 responseBody 写入文件,核心代码如下:但是这种做法有个明显的问题,假如手机在下载文件的时候下载了80%,某些原因断网了,如果不支持断点续传,那就只有被迫重头开始下载。但是如果有断点续传的加持,就只需要下载最后 20% 的资源,避免重新下载。断点续传原理1、java.io.RandomAccessFile断点续传/下载需要使用到 java.io.RandomAccessFile 类

2021-10-25 17:36:19 1098

原创 Android Context Hook

Context Hook在 Android 编程中,我们常常会和 Context打交道,而且 Context 遍布各个地方,就算使用 Jetpack Compose 也都离不开它。正因为 Context 被广泛的使用和传播,当我们面对一些特殊问题时,常常能够从 Context对象入手,去解决许多看似不能改变的代码问题。这常常就会用到 Context Hook 这种手法。Context Hook 形式其实特别简单,就是使用 ContextWrapper 对原有的 Context 进行代理,从而实现 Con

2021-10-25 17:04:17 1603

原创 Java字符串、文件MD5工具类

Hex首先定义 Hex 工具类, 来源于 apache 开源工具类 https://commons.apache.org/proper/commons-codec/download_codec.cgi/** * @author : zhaoyanjun * @time : 2021/6/8 * @desc : file md5值 https://commons.apache.org/proper/commons-codec/download_codec.cgi */public class

2021-10-20 20:27:23 392

原创 Java原子操作Atomic

Java的java.util.concurrent包除了提供底层锁、并发集合外,还提供了一组原子操作的封装类,它们位于java.util.concurrent.atomic包。AtomicInteger我们以AtomicInteger为例,它提供的主要操作有:增加值并返回新值:int addAndGet(int delta)加1后返回新值:int incrementAndGet()获取当前值:int get()用CAS方式设置:int compareAndSet(int expect, int

2021-10-19 21:33:04 629

原创 Java线程安全StampedLock

ReadWriteLock前面介绍的ReadWriteLock可以解决多线程同时读,但只有一个线程能写的问题。如果我们深入分析ReadWriteLock,会发现它有个潜在的问题:如果有线程正在读,写线程需要等待读线程释放锁后才能获取写锁,即读的过程中不允许写,这是一种悲观的读锁。要进一步提升并发执行效率,Java 8引入了新的读写锁:StampedLock。StampedLock和ReadWriteLock相比,改进之处在于:读的过程中也允许获取写锁后写入!这样一来,我们读的数据就可能不一致,所以,

2021-10-19 21:02:27 424

原创 Java阻塞队列 LinkedBlockingDeque

LinkedBlockingDequeLinkedBlockingDeque类实现了BlockingDeque接口。阅读BlockingDeque文本以获取有关的更多信息。Deque来自“双端队列” 这个词。Deque是一个队列,你可以在插入和删除队列两端的元素。LinkedBlockingDeque是一个Deque,如果一个线程试图从中获取一个元素,而队列空的,不管线程从哪一端试图获取元素,都会被阻塞。以下是实例化和使用LinkedBlockingDeque的例子:BlockingDeque&l

2021-10-19 10:47:35 990

原创 Java栈 Stack

Stack栈(Stack)是一种后进先出(LIFO:Last In First Out)的数据结构。什么是LIFO呢?我们先回顾一下Queue的特点FIFO:所谓FIFO,是最先进队列的元素一定最早出队列,而LIFO是最后进Stack的元素一定最早出Stack。如何做到这一点呢?只需要把队列的一端封死:因此,Stack是这样一种数据结构:只能不断地往Stack中压入(push)元素,最后进去的必须最早弹出(pop)来:Stack只有入栈和出栈的操作:把元素压栈:push(E);把栈顶的

2021-10-18 19:33:19 431

原创 Java队列 PriorityQueue

PriorityQueue我们知道,Queue是一个先进先出(FIFO)的队列。在银行柜台办业务时,我们假设只有一个柜台在办理业务,但是办理业务的人很多,怎么办?可以每个人先取一个号,例如:A1、A2、A3……然后,按照号码顺序依次办理,实际上这就是一个Queue。如果这时来了一个VIP客户,他的号码是V1,虽然当前排队的是A10、A11、A12……但是柜台下一个呼叫的客户号码却是V1。这个时候,我们发现,要实现“VIP插队”的业务,用Queue就不行了,因为Queue会严格按FIFO的原则取出队

2021-10-18 16:42:42 371

原创 Java队列 Deque

我们知道,Queue 是队列,只能一头进,另一头出。如果把条件放松一下,允许两头都进,两头都出,这种队列叫双端队列(Double Ended Queue),学名Deque。Java集合提供了接口Deque来实现一个双端队列,它的功能是:既可以添加到队尾,也可以添加到队首;既可以从队首获取,又可以从队尾获取。我们来比较一下Queue和Deque出队和入队的方法:QueueDeque添加元素到队尾add(E e) / offer(E e)addLast(E e) / o

2021-10-18 16:32:51 543

原创 Java队列 Queue

Queue队列(Queue)是一种经常使用的集合。Queue实际上是实现了一个先进先出(FIFO:First In First Out)的有序表。它和List的区别在于,List可以在任意位置添加和删除元素,而Queue只有两个操作:把元素添加到队列末尾;从队列头部取出元素。超市的收银台就是一个队列:在Java的标准库中,队列接口Queue定义了以下几个方法:int size():获取队列长度;boolean add(E)/boolean offer(E):添加元素到队尾;E rem

2021-10-18 16:08:52 939

原创 Android View Binding的使用

什么是View BindingView Binding是Android Studio 3.6推出的新特性,目的是为了替代findViewById(内部实现还是使用findViewById)。。在启动视图绑定后,系统会为改模块中的每个xml文件生成一个绑定类,绑定类的实例包含对在相应布局中具有 ID 的所有视图的直接引用。View Binding 的优点Null 安全:由于视图绑定会创建对视图的直接引用,因此不存在因视图 ID 无效而引发 Null 指针异常的风险。此外,如果视图仅出现在布局的某些配置

2021-10-13 21:08:52 1795 2

原创 Java线程安全Lock、ReentrantLock、ReentrantReadWriteLock

文章目录前言LockReentrantLock公平锁/非公平锁超时机制可重入锁读写锁 ReentrantReadWriteLock源码结构总结示例前言java5之后,并发包中新增了Lock接口(以及相关实现类)用来实现锁的功能,它提供了与synchronized关键字类似的同步功能。既然有了synchronized这种内置的锁功能,为何要新增Lock接口?先来想象一个场景:手把手的进行锁获取和释放,先获得锁A,然后再获取锁B,当获取锁B后释放锁A同时获取锁C,当锁C获取后,再释放锁B同时获取锁D,以此

2021-10-13 20:32:26 522

原创 Java线程安全集合总结

从Java5开始,在Java.util.concurrent包下提供了大量支持高效并发访问的集合接口和实现类,如下图:从图中可以看出,这些线程安全的集合主要分为两类,以Concurrent开头的集合类和以CopyOnWrite开头的集合类。1、以Concurrent开头的集合类,可以支持多个线程并发写入访问,写入操作都是线程安全的,读取操作不必锁定,采用更复杂的算法保证永不会锁住整个集合,因此在并发写入时有较好的性能。ConcurrentLinkedQueue实现多线程高效、无须等待的访问,不能使用

2021-10-13 18:08:01 2697

原创 Android ConstraintLayout ConstraintSet动态布局

在传统布局方式中,如果要改变某个控件的位置,需要获取 LayoutParams , 后台修改属性值就行了。但是在约束布局 ConstraintLayout 中,要改变控件的约束条件,需要用到 ConstraintSet 类。主要有 5 个步骤第一步:创建 ConstraintSet() 实例 val set = ConstraintSet()第二步:需要复制一份父布局的约束,方法有三个如下set.clone(constraintLayout: ConstraintLayout);set

2021-10-12 19:58:06 5325 1

原创 Java CountDownLatch的两种常用场景

简介先来看看 CountDownLatch 的源码注释;/** * A synchronization aid that allows one or more threads to wait until * a set of operations being performed in other threads completes. * * @since 1.5 * @author Doug Lea */public class CountDownLatch {}描述如下:它是一个同

2021-09-27 13:46:38 767

原创 Kotlin重载运算符operator

定义运算符重载就是对已有的运算符赋予他们新的含义。重载的修饰符是operator。比如我们的+号,它的含义是两个数值相加:1+1=2。+号对应的函数名是plus比如我们定义一个类,如何才能使用 + 这个符号呢?其实也很简单,使用 operator 重载 plus 函数就能搞定,我们试试吧重载 plus首先我们定义一个类 Point ,然后重载 plus 函数class Point(private val x: Int, private val y: Int) { operator fu

2021-09-26 21:01:51 4999

原创 Kotlin密封类sealed

简介密封类用来表示受限的类继承结构:当一个值为有限几种的类型, 而不能有任何其他类型时。在某种意义上,他们是枚举类的扩展:枚举类型的值集合 也是受限的,但每个枚举常量只存在一个实例,而密封类的一个子类可以有可包含状态的多个实例。声明一个密封类,使用 sealed 修饰类,密封类可以有子类。sealed 不能修饰 interface ,`abstract classe(会报 warning,但是不会出现编译错误)密封类与枚举类对比① 相同点 ( 类型限制 ) : 从类型种类角度对比 , 类与枚举类

2021-09-26 20:32:14 3236

原创 RSA加密 — 详解

文章目录RSA 简介实际运用注意事项实战RSA 简介RSA——非对称加密,会产生公钥和私钥,公钥在客户端,私钥在服务端。公钥用于加密,私钥用于解密。实际运用注意事项1、一般由服务器创建秘钥对,私钥保存在服务器,公钥下发至客户端2、公钥是二进制数据,怎么下发给客户端呢?第一种方式:服务器把二进制数据写入文件,然后把文件传给客户端。由客户端从文件读取二进制数据。第二种方式:服务器把二进制数据转成 base64 字符串,客户端获取到 base64 字符串后,再转码为二进制数据。实战我们封存一

2021-09-15 21:16:21 18356 1

Pepk 签名压缩工具

Android app 签名生成工,执行完命令,会生成 output.zip , 然后把 output.zip 上传即可,非常好用

2020-04-16

XShell+XFtp

灵活、轻便的SFTP/FTP客户端 通过Xftp 5在网络中安全传输文件,实现多窗口 编辑,进行文件同步。

2018-02-26

空空如也

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

TA关注的人

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