Johnny Shieh

人如果没有梦想,跟咸鱼有什么分别


  • 首页

  • 分类

  • 归档

  • 标签

  • 读书

  • 小伙伴

  • 关于

  • 搜索

Android targetSdkVersion 版本适配指北(持续更新)

发表于 2019-05-17 | 分类于 Android | | 阅读次数

Google Play 要求新应用(自 2019 年 8 月 1 日起)和应用更新(自 2019 年 11 月 1 日起)将目标 API 级别至少设为 28(至少为 Android 9.0)。在这两个日期之前,新应用和应用更新的目标 API 级别必须至少为 26(至少为 Android 8.0)。

同时,国内的华为、360、应用宝等也开始要求开发者适配 Android 9.0,所以必须面对版本适配这个难题,下面记录了从 Android 5.0 开始版本适配的注意事项。

Android 5.0(API 21)

Android 5.0 行为变更

在 Android 5.0 中,ART 运行时取代 Dalvik 成为平台默认设置。

Context.bindService不再支持隐式的 Intent

1
2
3
4
5
6
7
8
9
10
11
12
private void validateServiceIntent(Intent service) {
if (service.getComponent() == null && service.getPackage() == null) {
if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP) {
IllegalArgumentException ex = new IllegalArgumentException(
"Service Intent must be explicit: " + service);
throw ex;
} else {
Log.w(TAG, "Implicit intents with startService are not safe: " + service
+ " " + Debug.getCallers(2, 3));
}
}
}

Context.bindService方法需要显式 Intent,需要调用Intent.setComponent()或Intent.setPackage()即可。

阅读全文 »

Android 7.0 以上 Charles 和 Fiddler 无法抓取 HTTPS 包的解决方式

发表于 2019-05-06 | 分类于 Android | | 阅读次数

最近升级了 targetSdkVersion 到 28 后发现在 Android 7.0 以上机型 Charles 抓取 https 包时显示找不到证书,但是 Android 6.0 机型还是可以正常抓包。原因是因为从 Android 7.0 开始,默认的网络安全性配置修改了,具体请阅读官方文档网络安全性配置。

阅读全文 »

Kotlin Coroutines(协程) 完全解析(五),协程的并发

发表于 2019-01-07 | 分类于 Kotlin | | 阅读次数

Kotlin Coroutines(协程) 完全解析系列:

Kotlin Coroutines(协程) 完全解析(一),协程简介

Kotlin Coroutines(协程) 完全解析(二),深入理解协程的挂起、恢复与调度

Kotlin Coroutines(协程) 完全解析(三),封装异步回调、协程间关系及协程的取消

Kotlin Coroutines(协程) 完全解析(四),协程的异常处理

Kotlin Coroutines(协程) 完全解析(五),协程的并发

本文基于 Kotlin v1.3.0-rc-146,Kotlin-Coroutines v1.0.0-RC1

通过前面几篇文章可以明白协程就是可以挂起和恢复执行的运算逻辑,挂起函数用状态机的方式用挂起点将协程的运算逻辑拆分为不同的片段,每次运行协程执行的不同的逻辑片段。所以协程在运行时只是线程中的一块代码,线程的并发处理方式都可以用在协程上。不过协程还提供两种特有的方式,一是不阻塞线程的互斥锁Mutex,一是通过 ThreadLocal 实现的协程局部数据。

1. Mutex

线程中锁都是阻塞式,在没有获取锁时无法执行其他逻辑,而协程可以通过挂起函数解决这个,没有获取锁就挂起协程,获取后再恢复协程,协程挂起时线程并没有阻塞可以执行其他逻辑。这种互斥锁就是Mutex,它与synchronized关键字有些类似,还提供了withLock扩展函数,替代常用的mutex.lock; try {...} finally { mutex.unlock() }:

1
2
3
4
5
6
7
8
9
10
11
12
fun main(args: Array<String>) = runBlocking<Unit> {
val mutex = Mutex()
var counter = 0
repeat(10000) {
GlobalScope.launch {
mutex.withLock {
counter ++
}
}
}
println("The final count is $counter")
}

Mutex的使用比较简单,不过需要注意的是多个协程竞争的应该是同一个Mutex互斥锁。

阅读全文 »

Kotlin Coroutines(协程) 完全解析(四),协程的异常处理

发表于 2019-01-07 | 分类于 Kotlin | | 阅读次数

Kotlin Coroutines(协程) 完全解析系列:

Kotlin Coroutines(协程) 完全解析(一),协程简介

Kotlin Coroutines(协程) 完全解析(二),深入理解协程的挂起、恢复与调度

Kotlin Coroutines(协程) 完全解析(三),封装异步回调、协程间关系及协程的取消

Kotlin Coroutines(协程) 完全解析(四),协程的异常处理

Kotlin Coroutines(协程) 完全解析(五),协程的并发

本文基于 Kotlin v1.3.0-rc-146,Kotlin-Coroutines v1.0.0-RC1

在上一篇文章中提到子协程抛出未捕获的异常时默认会取消其父协程,而抛出CancellationException却会当作正常的协程结束不会取消其父协程。本文来详细解析协程中的异常处理,抛出未捕获异常后协程结束后运行会不会崩溃,可以拦截协程的未捕获异常吗,如何让子协程的异常不影响父协程。

Kotlin 官网文档中有关于协程异常处理的文章,里面的内容本文就不再重复,所以读者们先阅读官方文档:

Coroutine Exception handling

协程的异常处理(官方文档中文版)

看完官方文档后,可能还是会有一些疑问:

  • launch式协程的未捕获异常为什么会自动传播到父协程,为什么对异常只是在控制台打印而已?

  • async式协程的未捕获异常为什么需要依赖用户来最终消耗异常?

  • 自定义的CoroutineExceptionHandler的是如何生效的?

  • 异常的聚合是怎么处理的?

  • SupervisorJob和supervisorScope实现异常单向传播的原理是什么?

这些疑问在本文逐步解析协程中异常处理的流程时,会一一解答。

阅读全文 »

2018 年终总结

发表于 2018-12-31 | 分类于 随笔 | | 阅读次数

今年的年终总结迟到了,下不为例。

最重要的事情是新房装修完入住了,满足。

至于去年底设定了一些目标,大部分没完成,所以缺乏计划的目标,只是许愿而已。

12…16
Johnny Shieh

Johnny Shieh

我本微末,心向天空

76 日志
13 分类
43 标签
GitHub Weibo Gmail 简书
  • 热门系列
  • Dagger 完全解析(6)
  • AspectJ in Android(3)
  • Kotlin 写 Android 单元测试(4)
  • Kotlin 协程完全解析(5)
© 2015 - 2019 Johnny Shieh
访客数 访问量