Android Weekly Issue #428
Kotlin Flow Retry Operator with Exponential Backoff Delay
这是讲协程Flow系列文章中的一篇.
对于重试的两个操作符:
- retryWhen
- retry
retryWhen的使用:
.retryWhen { cause, attempt -> if (cause is IOException && attempt < 3) { delay(2000) return@retryWhen true } else { return@retryWhen false }}
retry:
.retry(retries = 3) { cause -> if (cause is IOException) { delay(2000) return@retry true } else { return@retry false }}
可以把时间指数延长:
viewModelScope.launch { var currentDelay = 1000L val delayFactor = 2 doLongRunningTask() .flowOn(Dispatchers.Default) .retry(retries = 3) { cause -> if (cause is IOException) { delay(currentDelay) currentDelay = (currentDelay * delayFactor) return@retry true } else { return@retry false } } .catch { // error } .collect { // success }}
Fragments: Rebuilding the Internals
Fragment在Android 10已经废弃, 现在不在framework中了, 只在AndroidX中有.
这个Fragment 1.3.0-alpha08版本的发布, 有一些关于FragmentManager内部状态的重要更新.
解决了很多issue, 简化了fragment的生命周期, 还提供了一个FragmentManager多个back stacks的支持.
核心就是这个FragmentStateManager类.
这个FragmentStateManager负责:
- 转换Fragment的生命周期状态.
- 跑动画和转场.
- 处理延迟转换.
Postponed fragments
关于状态的确定, 有一个case是一个难点: postponed fragments.
这是一个以前就有的东西, 通常跟shared element transition动画有关系.
postponed fragment有两个特点:
- view创建了, 但是不可见.
- lifecycle顶多到
STARTED
.
只有调用这个方法: startPostponedEnterTransition()
之后, fragment的transition才会跑, view会变成可见, fragment会移动到RESUMED
.
所以有这个bug: Postponed Fragments leave the Fragments and FragmentManager in an inconsistent state bug.
这个issue相关联的还有好几个issues.
在容器层面解决问题
用一个SpecialEffectsController(以后名字可能会改)来处理所有动画转场相关的东西.
这样FragmentManager就被解放出来, 不需要处理postponed的逻辑, 而是交给了container, 这样就避免了FragmentManager中状态不一致的问题.
新的StateManager构架
原先: 一个FragmentManager
总管所有.
现在: FragmentManager
和各个FragmentStateManager
的实例交流.
- The
FragmentManager
only has state that applies to all fragments. - The
FragmentStateManager
manages the state at the fragment level. - The
SpecialEffectsController
manages the state at the container level.
总体
这个改动新发布, 实验阶段, 总体来说是应该没有行为改变的.
如果有行为改变, 对你的程序造成了影响, 也可以暂时关闭(FragmentManager.enableNewStateManager(false)
), 并且报告个issue.
A Framework For Speedy and Scalable Development Of Android UI Tests
讲了一整套的测试实践.
没有用Appium, 用的UI Automator和Espresso.
Basic Coroutine Level 1
Kotlin协程的概念.
Android Lint Framework — An Introduction
Android Lint的介绍.
创建一个Lint规则, 保证每个人都用项目自定义的ImageView, 而不是原生的ImageView.
具体做法:
- 首先从创建一个叫做
custom-lint
的module. 需要依赖lint-api
和lint-checks
:
compileOnly "com.android.tools.lint:lint-api:$androidToolsVersion"compileOnly "com.android.tools.lint:lint-checks:$androidToolsVersion"
这里用了compileOnly
是因为不想lint API在runtime available.
- 之后创建自定义规则. 每个lint check的实现都叫一个detector. 需要继承
Detector
, 并且利用Scanners
来做扫描. 报告错误需要定义Issue. 还可以创建LintFx
, 作为quick fix.
class ImageViewUsageDetector : LayoutDetector() { // Applicable elements override fun visitElement(context:
然后把定义好的自定义规则注册.
class Registry: IssueRegistry() { override val issues: List<Issue> get() = listOf(ImageViewUsageDetector.ISSUE) override val api: Int = CURRENT_API}
创建入口, 在
build.gradle
文件中:
// Configure jar to register our lint registryjar { manifest { attributes("Lint-Registry-v2": "com.tintedimagelint.lint.Registry") }}
加上依赖和一些配置.
android { // Configurations above lintOptions { lintConfig file('../analysis/lint/lint.
Codelabs for new Android game technologies
Codelabs for new Android game technologies
关于Android Game新技术的Codelabs:
资源打包: Play Asset Delivery -> https://codelabs.developers.google.com/codelabs/unity-gamepad/#0
帧率和图像: Android Performance Tuner -> https://codelabs.developers.google.com/codelabs/android-performance-tuner-unity/#0
都是Unity的game.
Android Vitals - When did my app start?
Android Vitals - When did my app start?
系列文章之六, 我的app啥时候启动的?
看个结论吧:
Here's how we can most accurately measure the app start time when monitoring cold start:
Up to API 24: Use the class load time of a content provider.
API 24 - API 28: Use
Process.getStartUptimeMillis()
.API 28 and beyond: Use
Process.getStartUptimeMillis()
but filter out weird values (e.g. more than 1 min to get toApplication.onCreate()
) and fallback to the timeContentProvider.onCreate()
is called.
Comparing Three Dependency Injection Solutions
Comparing Three Dependency Injection Solutions
比较三种依赖注入的解决方案.
手写方式.
Koin.
Dagger Hilt.
Avoiding memory leaks when using Data Binding and View Binding
Avoiding memory leaks when using Data Binding and View Binding
使用Data Binding和View Binding的时候, 注意内存泄漏问题.
Google建议在Fragment中使用binding时, 要在onDestroyView中置为null:
private var _binding: ResultProfileBinding? = null// This property is only valid between onCreateView and// onDestroyView.private val binding get() = _binding!!override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { _binding = ResultProfileBinding.inflate(inflater, container, false) val view = binding.root return view}override fun onDestroyView() { super.onDestroyView() _binding = null}
有个博客中介绍的方法, 可以简化成这样:
private val binding: FragmentFirstBinding by viewBinding()
Fragment还有一个参数的构造, 可以传入布局id:
class FirstFragment : Fragment(R.layout.fragment_first) { private val binding: FragmentFirstBinding by viewBinding() override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) // Any code we used to do in onCreateView can go here instead }}
冷知识: DataBinding实现了ViewBinding.
public abstract class ViewDataBinding extends BaseObservable implements ViewBinding
所以ViewBinding和DataBinding方法通用.
Anti-patterns of automated software testing
Anti-patterns of automated software testing
关于测试的一些anti-patterns.
推荐阅读.
Using bytecode analysis to find unused dependencies
Using bytecode analysis to find unused dependencies
关于这个库: https://github.com/autonomousapps/dependency-analysis-android-gradle-plugin的说明.
Code
Code
https://github.com/jmfayard/refreshVersions: 一个依赖版本管理的gradle插件.
后记
后记
好久没在博客园发过这个系列.
其实一直还有在更, 只不过写得比较散乱随意, 所以丢在了简书:
https://www.jianshu.com/c/e51d4d597637
最近有点忙, 不太有时间写博客, 积攒了好多话题都是没有完成的.
看博客两个月没更了, 拿这篇刷一下存在感.
是想多写点真正厉害有价值的原创的.
先韬光养晦, 积累一下.
Android Weekly Notes Issue #428蜜芽、 邮政电话、 亚马逊平台入门ABC、 FBA买家信息被进一步隐藏?又一条找差评的路子被封死!、 关于亚马逊美日欧鞋码新规,这份指南一定要看!、 亚马逊卖家账号危在旦夕,被无良供应商趁火打劫、 马来西亚电商市场份额抢夺战:Lazada 和 Shopee 谁更胜一筹?、 跨境电商备货业务,在西安国际港务区正式开启!、
No comments:
Post a Comment