自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

张可的博客

公众号:zhangke_blog

  • 博客(64)
  • 问答 (2)
  • 收藏
  • 关注

原创 Clean 架构下的现代 Android 架构指南

用 Clean 架构开发 Android 应用,彻底解决代码混乱问题,应该是 Android 目前最好用的架构了!

2023-12-04 17:58:17 365

原创 用 Compose 做了个开源的轻量级的 Notion 客户端 NotionLight,现已上架 Google Play。

迫于 Notion 的客户端比较慢,而且操作路径有点长,如果想当做快速笔记或者 TODO 来用还是不太够。正好前段时间因为疫情在家待了三个月没出门,打算学学 Compose,所以顺便 😃 用 Notion 的 API 卷了个简单快速的客户端出来。既然是当做快速笔记以及 TODO 来用,那内容的组织形式就是按照列表来的,会把 Notion 中的每个能被识别的内容块映射成列表中一个条目展开显示。每个 Notion 页面对应 NotionLight 中的一个 TAB。授权后自己选择将 Notion 中的对应的页.

2022-06-18 12:41:19 864 1

原创 Android Studio 4.1 更新内容

概览Android Studio 4.1 目前已经发布,该版本共修复了2370 个 bug 以及 275 个 issue,主要包含如下新增功能:设计Material Design 组件库的更新开发Database Inspector 功能直接在 Android Studio 中运行模拟器Dagger 导航支持使用 Apply Changes 模型构建与测试Android 模拟器支持折叠屏Apply Changes 更新从 AAR 中导出 C/C++ 中的依赖native

2020-10-13 10:13:13 3165 6

原创 HashMap

本篇文章是【Java集合系列】文章 Map 篇的第二篇,本系列将会逐个分析 Java 中的常用集合的特性及实现,然后对比不同场景下应该选择哪种集合使用。List 系列ArrayListLinkedListCopyOnWriteArrayListQueue系列ArrayDequeConcurrentLinkedDequeLinkedBlockingDequeMap 系列HashtableHashMapHashMapHashMap 实现了 Map 接口,用于存储键值对,与

2020-10-12 11:28:48 198

原创 Hashtable

本篇文章是【Java集合系列】文章 Map 篇的第一篇,本系列将会逐个分析 Java 中的常用集合的特性及实现,然后对比不同场景下应该选择哪种集合使用。List 系列ArrayListLinkedListCopyOnWriteArrayListQueue系列ArrayDequeConcurrentLinkedDequeLinkedBlockingDequeMap 系列HashtableHashMapHashtableHashtable 实现了 Map 接口,用于存储键值

2020-10-12 11:21:35 559

原创 LinkedBlockingDeque

本篇文章是【Java集合系列】文章队列篇的第三篇,本系列将会逐个分析 Java 中的常用集合的特性及实现,然后对比不同场景下应该选择哪种集合使用。List 系列ArrayListLinkedListCopyOnWriteArrayListQueue系列ArrayDequeConcurrentLinkedDequeLinkedBlockingDequeLinkedBlockingDequeLinkedBlockingDeque 是基于链表的双端阻塞队列,线程安全,元素不允许为 nu

2020-09-23 21:56:39 2899

原创 ConcurrentLinkedDeque

本篇文章是【Java集合系列】文章队列篇的第二篇,本系列将会逐个分析 Java 中的常用集合的特性及实现,然后对比不同场景下应该选择哪种集合使用。List 系列ArrayListLinkedListCopyOnWriteArrayListQueue系列ArrayDequeConcurrentLinkedDequeLinkedBlockingDequeConcurrentLinkedDequeConcurrentLinkedDeque 是基于链表的无限双端队列,线程安全,不允许 n

2020-09-23 21:38:29 1414

原创 ArrayDeque使用及源码分析

本篇文章是【Java集合系列】文章队列篇的第一篇,本系列将会逐个分析 Java 中的常用集合的特性及实现,然后对比不同场景下应该选择哪种集合使用。List 系列ArrayListLinkedListCopyOnWriteArrayListQueue系列ArrayDequeConcurrentLinkedDequeLinkedBlockingDequeArrayDequeArrayDeque 是 Java 集合中双端队列的数组实现,双端队列的链表实现(LinkedList)我们在前

2020-09-23 14:38:06 393

原创 Java 中的 CopyOnWriteArrayList

本篇文章是【Java集合系列】文章的第三篇,本系列将会逐个分析 Java 中的常用集合的特性及实现,然后对比不同场景下应该选择哪种集合使用。List 系列Java 中的 ArrayListJava 中的 LinkedListJava 中的 CopyOnWriteArrayListCopyOnWriteArrayList先看看百科上关于 COW 的介绍:写入时复制(英语:Copy-on-write,简称COW)是一种计算机程序设计领域的优化策略。其核心思想是,如果有多个调用者(caller

2020-08-14 10:11:00 338

原创 Java 中的 LinkedList

本篇文章是【Java集合系列】文章的第二篇,从系列将会逐个分析 Java 中的常用集合的特性及实现,然后对比不同场景下应该选择哪种集合使用。Java 中的 ArrayListJava 中的 LinkedListLinkedList实现了 List 以及 Deque 的双向链表,元素允许为 null,所以 LinkedList 同时具备 List 以及 Deque 的特性。跟 ArrayList 一样,LinkedList 也是非线程安全的,可以使用包装方法获取同步对象:List list =

2020-08-13 09:55:15 318

原创 Java 中的 ArrayList

本篇文章是【Java集合系列】文章的第一篇,从本篇文章开始将会逐个分析 Java 中的常用集合的特性及实现,然后对比不同场景下应该选择哪种集合使用。List先看下 ArrayList 实现的接口 List 的相关概念。List 可以称为有序集合或者序列,通过整数索引访问元素允许插入相同元素一般来说也允许插入 null 值List 接口中还提供了一个特殊的迭代器:ListIteratorListIteratorListIterator 专门为了 List 打造,在 Iterator 基础上

2020-08-12 12:06:51 220

原创 什么是信息熵?

1948 年,伟大的信息论之父**香农(Shannon)**将热力学中熵的概念引入到了信息论中,提出了“信息熵”这一概念。信息熵用于解决信息的量化问题,将原本模糊的信息概念进行计算得出精确的信息熵值,信息熵是描述消息中,不确定性的值。理解起来需要一点耐心,可以先这么说,信息熵就是用来描述信息中不确定性的值,熵越低,不确定性越低,我们也就更容易得到确定的信息。举个栗子,张三的女朋友小红又要过生日了,他现在挑选礼物有三个选择:口红、包、机械键盘。张三并不知道小红到底喜欢那种礼物,因此对于张三来说,小红喜欢

2020-07-27 11:25:58 4896

原创 WMS-Window的添加流程

总览我在上一篇文章介绍了 Activity 的启动流程,一直讲到到 WMS 这里结束,这篇文章讲沿着上篇文章的脉络继续分析下去。这篇文章不仅仅是 Window 的添加过程,也会涉及到一些 WMS 相关的原理。我希望能通过了解 Window 添加流程来掌握整个 WMS 的架构,从而对其产生一个完整的印象,至于旁枝末节也不着急深入的理解,有空就看看,这样后面遇到相关的问题也能知道个大概。先看一下 Window 的添加过程:上一篇文章讲了 AMS 将会调用 WMS 中的几个方法,也就是上图中从 AMS

2020-07-10 15:24:59 587 2

原创 Activity 启动流程分析(Android10)

概览Activity 启动流程比较复杂,分析起来很容易陷入复杂的代码中去,所以我这篇分析文章不会深入的分析代码细节,尽量抛开不重要的东西把启动流程按照重点分成几个部分来分析。下图是 Activity 启动流程的总览。(上图红色方块是与 WMS 关联的部分,后面会从这里开始介绍 WMS)后面我们将以 Android 29 为例,按照上图步骤逐步分析。Intent 解析到 Activity调用 startActivity 之后,经过几步辗转最终会调用到 AMS 中,而 AMS 又会调用 Activ

2020-06-23 14:53:42 4380 3

原创 回溯法:N皇后与解数独

好久没写博客了,最近比较忙,在系统学习一些知识,没学完之前不太容易输出高质量文章,等过段时间学完了再整理一下写几篇文章出来。但中间也在用零碎的时间学学别的,今天写总结一下回溯法。概念回溯法作为一种搜索算法,可以找出所有或一部分解的一般性算法,尤其适用于约束满足问题,例如今天要讲的N皇后、解数独等等。回溯法采用试错的思想,它尝试分步的去解决一个问题。在分步解决问题的过程中,当它通过尝试发现现有的分步答案不能得到有效的正确的解答的时候,它将取消上一步甚至是上几步的计算,再通过其它的可能的分步解答再次尝试

2020-05-22 15:02:02 535

原创 Android Service 基础与使用

Service 作为 Android 四大组件之一,有着非常重要的作用,Service 被设计为在后台长时间执行而不需要提供页面的任务。Service 基础知识Service 的生命周期如下图所示:启动/关闭 Service通过如下代码既可启动 Service。val intent = Intent(this, SampleService::class.java)startServi...

2020-04-15 22:21:03 441

原创 注解处理器(APT)技术使用

基本概念APT 全称为 Annotation Processing Tool,可翻译为注解处理器,APT 工具是用于注解处理的命令行程序,它可以找到源码中对应注解的对象并使用注解处理器对其进行处理。一般来说,我们会使用 APT 生成一些源码,然后加入编译目录进行编译,从而简化开发周期。注解注解处理器是基于注解(Annotation)的,实际开发中自定义注解用的比较少,这里先简单的复习下相关...

2020-03-30 09:57:52 1596

原创 Gradle 依赖与 Plugin

关于 Gradle 中的基础、Task 等知识,可以看我的上一篇文章。Gradle 中的依赖Gradle 中的依赖可以分为脚本文件依赖、插件依赖以及包依赖。脚本文件依赖随着项目结构的复杂,一个 build.gradle 已经无法满足我们的需求了,尤其是对依赖库版本的配置,如果多个 project 都需要用到某个依赖库,稍有不慎版本就会错乱,从而引发一些问题。此时我们期望可以把所有用到的依...

2020-03-08 18:49:32 2646

原创 Gradle 扫盲与 Task 基础

Gradle 是用于构建项目的工具,除了管理依赖库之外,Gradle 还支持我们自己添加编译脚本、添加编译配置等控制项目的构建,通过提供 API 我们可以控制编译的每一步操作。Gradle 目前使用最广泛的是 Android 项目的构建,几年前 Google 推出 Android Studio 的同时也把它也推选为默认的构建工具,因此我们也经历了从 Maven 到 Gradle 这一痛苦的转变过...

2020-03-08 18:22:44 314

原创 OkHttp 源码分析

流程分析我们从一个简单的 HTTP 请求开始:client = new OkHttpClient();Request request = new Request.Builder().url("your url").build();//同步发起请求Response syncResponse = client.newCall(request).execute();//异步发起请求clie...

2020-02-03 10:55:39 517

原创 Flutter Widget 最全使用介绍

Flutter widget 的设计思想跟 Android 略有不同,Flutter 中的 widget 可以用两条规则来约束:一切都是 widget每个 widget 只负责自己关注的部分第一条意味着你所看到的东西都是由于 widget 构成,跟安卓不同的是,原本在安卓中一些参数相关的东西到了 Futter 中都被 widget 化,例如大小、背景、margin、padding 等等原...

2019-12-02 15:14:10 1279 1

原创 Hello Flutter

Flutter 是 Google 在 2015 年发布的一款跨平台 UI 开发工具包,支持 Android 及 iOS 平台,同样也是 Google Fuchsia 的主力开发工具。作为 Android 开发有学习 Flutter 的必要吗?个人觉得很有必要,首先这是 Google 在主推的一个项目,并且国内阿里腾讯等等大厂都已经有使用 Flutter 开发的项目了,有他们背书,不用怕有什么填不...

2019-11-11 20:00:53 405

原创 Java 内存模型与线程

这篇文章是我之前看书时做的笔记,内容都是基于【深入理解 JVM 虚拟机】(周志明)这本书中介绍的东西,觉得有一定的价值所以拿出来分享。并且个人时间总是有限的,无法保证大量的产出,因此拿点之前的东西来充个数。硬件的效率与一致性由于计算的存储设备与处理器的运算速度有几个数量级的差距,所以现代计算机系统都不得不加入一层读写速度尽可能接近处理器运算速度的高速缓存(Cache)来作为内存与处理器之间...

2019-10-20 23:04:43 138

原创 ConstraintLayout 使用介绍

ConstraintLayout 是个功能超级强大的布局,很多复杂的布局之前需要很多层嵌套现在都可以使用一个 ConstraintLayout 来解决,很大程度上解决了布局嵌套层级过多问题,不仅如此,还提供了很多其他高级功能,对习惯用拖拽布局的同学也很友好。其中主要包含了如下几个功能点:相对定位(Relative positioning)居中定位(Centering position)及偏...

2019-10-15 18:20:51 310

原创 DataBinding 使用介绍

DataBinding 是 Google 在 Jetpack 中推出的一款数据绑定的支持库,利用该库可以实现在页面组件中直接绑定应用程序的数据源。使其维护起来更加方便,架构更明确简介。简介那么 DataBinding 本质上到底是个什么呢?它在开发正扮演着什么样的角色?我们应该如何使用?DataBinding 名为数据绑定,他的功能很简单,就是将数据绑定在 UI 页面上(这不是废话吗),明白...

2019-09-18 11:49:04 618

原创 Kotlin 中的泛型介绍

泛型类型参数泛型允许你定义带类型形参的类型。当这种类型的实例被创建出来的时候,类型形参被替换成称为类型实参的具体类型。使用方式和 Java 一样:List,Map<K, V>。同样,Kotlin 也可以自动推导类型:val authors = listOf("Dmitry", "Svetlana")和 Java 不同的是,Kotlin 始终要求类型实参要么被显示的说明,要么...

2019-08-18 21:25:14 788

原创 Kotlin 中的 lambda,这一篇就够了

lambda 本质上是可以传递给函数的一小段代码,Kotlin 与 Java 中的 Lambda 有一定的区别,除了对 lambda 的全面支持外,还有内联函数等简洁高效的特性。下面我们来仔细看一下。高阶函数我们知道,lambda 的应用场景就是高阶函数,我们可以把一个 lambda 当做参数传递到高阶函数中,获取返回一个 lambda。准确的来说,高阶函数就是以另一个函数作为参数或者返回值...

2019-08-16 23:15:27 1204

原创 Kotlin 从零到一

2017 年 Google 宣布 Android 为 Kotlin 提供最佳支持并且取代了 Java 的位置,Kotlin 逐渐步入大众的视野。Kotlin 项目最早可以追溯到 2010 年,JetBrains 团队准备开发一款现代化、更强大、更易用的语言,经过五年多的开发,JetBrains 终于在 2016 年年初发布了 Kotlin v1.0 版本。至今已经过了三年多,Android 最新...

2019-08-04 22:37:12 133

原创 Android Matrix详解

我们在自定义 View 控件时随处可见 Matrix 的身影,主要用于坐标转换映射,我们可以通过 Matrix 矩阵来控制视图的变换。Matrix 本质上是一个如下图所示的矩阵:上面每个值都有其对应的操作。Matrix 提供了如下几个操作:缩放(Scale)对应 MSCALE_X 与 MSCALE_Y位移(Translate)对应 MTRANS_X 与 MTRANS_Y...

2019-06-13 23:04:41 1622

原创 Android 多点触控及应用(画板控件 DrawView)

多指触控是指监听多个手指的触控事件,我们可以重写 View 中的 onTouchEvent 方法,或者使用 setOnTouchListener 方法来处理触摸事件。首先我们来看一下如何判断多指触摸时的事件类型。MotionEvent 中的事件类型一般而言,我们通过判断 MotionEvent 的 action 来判断输入事件类型,从而做出相应的处理。在不考虑多指的情况下,我们一般只关注如...

2019-06-12 23:03:06 1960 4

原创 Android事件分发机制

事件分发机制事件分发机制是 Android 开发者的必备技能,关于这方面的博客也有很多,最近准备夯实一下自己的基础知识,整理一下零散的知识点,为突破做准备,所以再来梳理一下事件分发机制。大多介绍事件分发机制的文章都只叙述了 View 与 ViewGroup 的事件分发机制,我这里将从 Activity 开始介绍。一般来说,事件传递的顺序是:Activity->ViewGroup-Vie...

2019-06-06 21:10:59 1333 1

原创 网络流 InputStream 的读取

InputStream 读取相信大家都不陌生,网上搜一下也有很多种方法,但是关于网络流 InputStream 的读取这两天我倒是发现了一个坑,在这里记录一下。最开始我使用的是 Apache 的 IOUtils#toString 方法直接将 InputStream 转为 String,大多数情况下这样做都没什么问题,毕竟是 Apache 家的东西。但是这两天写接口时遇到了一个问题,当我接收到 ...

2019-05-16 23:58:32 4381 1

原创 WebSocketDemo 安卓客户端实现及代码封装,3.0 版本发布

介绍WebSocket 3.0 版本经过这段时间的开发终于完成并且通过测试,相比较于 2.0 版本有了很大的改动,程序的健壮性与扩展性有了很大的提高。实际上,以前的版本很大程度上都是为了应付公司业务而做的,顺手开源出来,但我发现随着使用者越来越多,问题也逐渐凸显出来,再加上经过前段时间的学习技术上有了长足的进步,就想着把这个给重构一遍。其实做这个技术上并没有什么技术上的难点,但是要做开源,要...

2019-05-05 09:20:40 4166 13

原创 最小生成树-Prim 算法与 Kruskal 算法 Java 实现版

最小生成树一个无向图 G 的最小生成树(minimum spanning tree) 就是由该图的那些连接 G 的所有顶点的边构成的树,且总价值最低。最小生成树存在当且仅当 G 是连通的。Prim 算法Prim 算法是使其连续的一步步长成。在每一步,都要把一个节点当做跟并网上加边,这样也就把相关联的顶点增长到了树上。/** * 类似 {@link Dijkstra} 算法。 ...

2019-04-28 21:35:54 982

原创 图论总结-拓扑排序以及最短路径问题(无权最短路径、Dijkstra算法、具有负边值的图)

图的定义一个图(graph)G = (V,E) 由 顶点(vertex) 集 V 和 边(edge) 集 E 组成。每一条边就是一个点对(v,w),其中 v,w∈ V,有时也被称为弧(arc)。如果点对是有序的,那么图就叫做是有向的(directed),有向的图有时也叫做有向图(digraph)。顶点 v 和 w 邻接(adjacent) 当且仅当(v,w)∈ E。有时边还有第三种成分,...

2019-04-28 21:30:57 1985

原创 插入排序与希尔排序Java版

插入排序时间复杂度:O(n²)插入排序(Insertion Sort)是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,通常采用 in-place 排序(即只需用到 O(1) 的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。——维基百科publ...

2019-04-12 00:00:09 220

原创 快速排序与归并排序Java实现版

快速排序快速排序(Quicksort) 是一种排序算法,平均时间复杂度为:O(n log n),最坏需要 O(n²),但很少见,快速排序之所以叫快速排序,就是因为它比一般的排序算法要快。快速排序使用了分而治之的思想,步骤如下:选择基准值(pivot)将数组分成两个子数组:小于基准值的元素和大于基准值的元素对这两个子数组进行快速排序不同的选取基数值策略对排序性能都有很大的影响。递归...

2019-04-10 23:26:47 963

原创 阅读源码的方法论

随着互联网行业的发展,优秀的开源框架越来越多,我们可以轻易地在 Github 上找到业界顶尖的大佬亲手写的代码,对于这种放在眼前的美食我们怎么能视而不见呢?但实际上,源码一般比较复杂,一个框架动辄上万行、几百个类,互相之间又有着各种各样奇奇怪怪的联系。想要从这一堆复杂冗长的代码中理清楚头绪实在是非常困难。下面这篇文章就总结了我在阅读源码时的一些方法与技巧,希望可以帮到大家。下面的框架我会按照 ...

2019-03-31 14:59:50 275

原创 Glide 源码分析解读-缓存模块-基于最新版Glide 4.9.0

缓存模块缓存模块涉及到的东西比较多,比较重要,所以需要单独用一章节来讲。关于缓存的获取、数据加载相关的逻辑在 Engine#load 方法中。先来看看缓存流程,流程如下图:全部的缓存流程大致如上图所示。Glide 实例化时会实例化三个缓存相关的类以及一个计算缓存大小的类://根据当前机器参数计算需要设置的缓存大小MemorySizeCalculator calculator = n...

2019-03-20 17:21:26 927

原创 Glide 源码分析解读-基于最新版Glide 4.9.0

项目编译项目基于最新版 Glide 4.9.0 源码分析,通过如下方式获取并编译代码:git clone https://github.com/bumptech/glide.gitcd glide./gradlew jar代码量(使用 cloc 统计):这么多的代码,直接看肯定让人头疼,理不清头绪,但好在 Glide 分包结构明确,我们可以先根据不同的模块来逐个击破。总览有一点...

2019-03-20 16:16:12 3750 1

空空如也

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

TA关注的人

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