OkHttp 请求流程简析
从 Android 4.4 开始,HttpURLConnection 底层使用 OkHttp 实现,所以阅读并学习它的源码就显得更加地理所应当。 为了简洁起见,我们去除源码中一些健壮性代码。 本文基于 OkHttp 3.8.1 分析案例这里我们选用最简单的 GET 请求来分析 OKHttp 的内部工作大体流程。 一般情况下的同步 GET 请求我们是以下面的方式发起的: 123456789Request request = new Request.Builder() .url(url) .build();OkHttpClient client = new OkHttpClient.Builder() .build();Call call = client.newCall(request);Response response = call.execute();String content = response.body().string();response.close(); **异步 GET **请求又是下面这样子的: 123456789101112call ...
Picasso 加载流程
自己第一次写比较完整 app 还是去年暑假,当时参加现在的团队夏令营,组长要求我们不能使用第三方库(亏得自己还苦哈哈地看了几天各种第三方库),所以就得自己手写图片加载逻辑,所以也就遇到很多问题,比如错位、加载慢等。不过使用第三方库的话,一行代码就能解决这些问题。 不废话了,从我的角度来看,网上目前流行的图片加载库也就三款,Picasso、Glide 和 Fresco,而它们的功能也是依次递增。Glide 是 Google 员工基于 Picasso 进行的二次开发,Google 在自己的应用里面也大量使用;Fresco 则出自 Facebook 之手,由于使用 Native/C 来缓存图片,所以一定程度上减少了 OOM 的可能。 现在大概清楚了三款库的定位,前两者专业性显然不如 Fresco,但是使用上简单,如果是应用内有大量的图片加载场景,如图库类应用,使用 Fresco 应该是个不错的选择。所以这次我们就选最简单的 Picasso 来分析,认怂。。。 图片加载库最经典的场景就是 从网络加载一张图片到 ImageView , Picasso 对此给出了最简单的解决方案: ...
Butterknife 剖析
在初学 Android 的时候,写一个 Activity,就要写好几句 findViewById (现在 support 包使用泛型避免强转),慢地就变得厌倦这些模板代码,但是又不能不写。ButterKnife 使用注解的方式来避免这一类模板代码,比如事件监听器等。代码变得好看了,也就开始思考它内部的工作原理。 学习源码最重要的是学习它的设计思想,然后帮助我们在以后学习中打开思路,多一种解决问题的可能。我觉得 ButterKnife 告诉我们要学会偷懒,能少写的代码绝不多写一句。 另外,Kotlin 可以直接使用 xml 里面的 id 来操作控件。 平台和工具 OS:Ubuntu 17.04Android Studio:Android Studio 2.4 Preview7ButterKnife:8.5.1 ButterKnife 做了啥这里我们创建一个简单的工程,布局文件里面就放一个 id 为 button 的按钮。MainActivity 里面的代码如下。 12345678910public class MainActivity extends AppCompatActi ...
Shell 学习 curl
最近有个作业需要自己写个服务器,接口写完了还得测试,虽然使用 postman 等工具很便捷,但是感觉不够装逼(嗯,就是不够装逼),所以 curl 成了不二之选。 当信用一个命令行工具的时候,习惯性动作都是在 Terminal 里面键入 ‘ –help’ 来看看都有哪些功能和参数,基本上能大概知道学习成本了。不过本人比较怂,如果一下子输出了好几页的帮助文档,基本上就转投 Google ,毕竟可能就用这么一次(以后得改改)。 使用1curl [options...] <url> 它的学问全部在 [options…] 里,鉴于帮助文档实在太多了,这里就只挑选进行 Http 请求时用的比较多的参数项。 保存输出到文件直接执行 curl http://www.baidu.com 会默认输出到标准输出,如果要保存至本地文件,有三种方式: 重定向1curl https://www.baidu.com > ./index.html 这样就能够输出到 index.html 了 使用 -o1curl -o ./index.html https://www.baidu.com ind ...
Android 磁盘目录
每次遇到存储这一块的时候,都要去看 官方文档 ;但是这里有一个蛋疼的问题就是,官方文档中没有对特定方法返回的路径进行说明。所以每次都会在这个问题上耗费十多分钟来 看文档 和 写 Demo 来找到符合要求的方法,这次就做个笔记,以防不时之需。 内部存储官方术语:Internal Storage我的理解就是 系统存储空间 ,也就是一般情况下,用户无法通过文件管理器查看。应用安装的时候会分配这样的一个空间,当用户卸载的时候系统会清理掉这部分存储空间。获取方式: 12345// /data/user/0/your.package.name/cacheContext.getCacheDir().absolutePath()// /data/user/0/your.package.name/filesContext.getFilesDir().absolutePath() 这两种也能够满足大部分的需求了。 外部存储官方术语: External Storage理解成 用户存储空间 可能比较恰当,因为用户通过一个文件管理器就可以把这部分存储空间看个遍(除非有这么闲)。这部分空间又要分成两部分:p ...
缓存之 MemoryLruCache
在开发图片加载功能时,既要保证加载速度,又要避免 OOM,特别是在类似于图库这样的场景中,如何处理好这两者关系显得尤为重要。所以最简单的想法就是一共缓存,将那些暂时 “食之无味,弃之可惜” 的对象暂时缓存起来,以备不适之需。 LruCache 简单使用这里我们以缓存 Bitmap 为例: 123456789101112131415val cacheSize = (Runtime.getRuntime().maxMemory() / 1024 / 8).toInt()val cache = object : LruCache<String, Bitmap>(cacheSize) { override fun sizeOf(key: String?, value: Bitmap?): Int { return value?.byteCount ?: 0 / 1024 } override fun create(key: String?): Bitmap { return super.cr ...
缓存之 DiskLruCache
DiskLruCache 在 Glide 、 OkHttp 中都有使用,不过这些第三方库有可能根据自己的需求进行了一定的修改,不过总体上的还是一样的。下载地址 特点 当缓存损坏的时候,它能够高效地进行处理。最明显的方法就是删除缓存,其他大多数缓存是没有这种机制的。不过一般来说,缓存损坏的情况还是比较少见的。 维护了一个缓存条目的内存LRU缓存,避免在每次访问缓存条目都需要查询数据库和磁盘,提高数据加载效率。 能够自己判断缓存是不是最新的,也就是说,每次使用 Editor 进行操作的时候都会做一个版本控制。 写入缓存发生错误时,可以调用 Editor#abort() 来放弃本次操作,并且产生的临时文件也将被删除。即使 app 在操作的时候意外停止运行,我们可以通过调用 DiskLruCache#close() 来删除所有的临时文件来保证缓存的状态连续性。 对同一份缓存的读写是线程安全的。 简单使用1234567891011121314151617// 初始化并获取实例DiskLruCache cache = DiskLruCache.open(directory, appVersi ...
React Native 之环境搭建
来自 GitBook,完成第一篇迁移 最近 React Native、weex 等跨平台框架都好火的样子,要是再不看看,可能就要听不懂他们前端的话了。万事开头难,搭环境、跑 Demo 啥的基本上没有不遇坑,当然解决之后也是蛮开心的。 平台OS:Ubuntu 17.04IDE:Android Studio 本来呢,不想在主力机上装各种环境,便想在只有 Windows 小破旧电脑上装,结果还是受不了 Windows ,于是也给 旧电脑装了 Ubuntu。 配置过程我是按照ReactNative中文社区的 教程 来配置的,一套流程走下来基本上也没什么问题。 node 安装打开 Terminal 执行下面几条命令就完成了 node 的安装: 1234$ sudo apt-get install -y build-essential # -y 表示不留缓存$ curl -sL https://deb.nodesource.com/setup_5.x | sudo -E bash -$ sudo apt-get install -y nodejs$ sudo ln -s /usr ...
AndroidArchitectureComponent 之 ViewModel
在学习 Android 稍微深入一点,就知道 Activity/Fragment 是受 Android 框架层控制的,具体表现在生命周期上面。系统会根据用户的操作或者设备状态来创建或销毁 Activity/Fragment,这个时候会带来数据的 保存和恢复(包括视图状态) 问题。一个典型场景就是表单页面,当用户旋转屏幕之后,系统会重建Activity/Fragment,如果什么数据的保存恢复工作都没有做,那么系统重建的 Activity/Fragment 将失去用户已经输入的数据,丢失数据越多,用户体验越差。 上面的还只是最简单的场景,当存在异步操作,Activity/Fragment 有可能恰好在请求返回时恰好被系统回收了,如果重建的 Activity/Fagment 又重新请求一次,就会造成资源浪费,最理想的情况就是能够直接利用之前请求到的数据同时又不会有内存泄露的隐患。 虽然系统提供了 onSaveInstanceState() 来保存数据,但是这只适用于 少量的 、支持 序列化 和 反序列化 的数据,局限性很明显。 所以我们需要自行提供一套数据保存与恢复的机制 ...
Android Architecture Components 之 Lifecycle
现在都流行 MVP + RxJava2 开发,然后 RxJava 带来的一个问题就是需要在适当的时候取消订阅关系以避免 内存泄露 ,最常见的做法就是在 Activity/Fragment#onDestroy() 方法中调用 disposable.dispose() 来解决。然后,官方文档中是用 LocationManager 来举例,这种情况就比较典型,需要重写 Activity/Fragment 的每个生命周期方法来处理它的状态。官方文档中又单独封装了一个类来处理,保持生命周期方法中的代码不会太臃肿。但是这还是没有彻底解决问题,毕竟还是要重写方法,难免不会有一次忘记重写某个生命周期函数。最理想的情况就是,我们封装的类能够 自动察觉 到生命周期的变化。 Lifecycle正式开始前,先了解几个概念。Lifecycle 这个类封装了组件的生命周期信息,并且使得这些信息可以被其他人监视。 Lifecycle 使用两个 枚举类 来追踪和它关联的组件生命周期: Event:这个枚举类代表了生命周期 变化,并且与 Activity/Fragment 中的生命周期回调方法 ...