美文网首页
Android Weekly Notes #466

Android Weekly Notes #466

作者: 圣骑士wind | 来源:发表于2021-07-11 01:42 被阅读0次

    Android Weekly Issue #466

    Static analysis tools for Android

    Android的静态分析工具.

    • Android lint
    • ktlint
    • detekt

    各自举了一个例子来说如何自定义规则.

    Navigation: Nested graphs and include tag

    Navigation graph支持嵌套.

    <navigation>标签.
    可以放在一个新的文件中, 再include进来.

    这样就可以跨module组织代码了.

    Avoid CI/CD Lock-in — Make Your Builds More Portable

    让CI更具可移植性.

    • 把脚本放在代码库里.
    • 把gradle任务放在shell脚本里.
    • 尽量使用gradle插件而不是ci插件.
    • 使用容器化技术.
    • 最小化在ci上的配置.

    Assisted Injection With Dagger and Hilt

    对于构造一个对象, 有些参数需要DI容器帮忙, 有些参数你想自己提供的情况.

    • 解决方案1: 添加AutoFactory依赖, 和daggeer结合使用, 会生成一个工厂.
    • 解决方案2: dagger2.31+之后, 使用@AssistedInject注解, 标记在构造函数上, 想要手动提供的参数, 标记@Assisted. 使用@AssistedFactory创建一个工厂.

    对ViewModel来说, 还需要提供一个ViewModelProvider.Factory的实现.

    Dagger 2 and Jetpack Compose Integration

    Dagger2和Jetpack Compose的集成.

    首先, 开篇定义navigation, 假定每个屏幕需要一个ViewModel:

    setContent {
       val navController = rememberNavController()
    
       NavHost(navController, startDestination = NavigationDestination.Screen1.destination) {
           composable(NavigationDestination.Screen1.destination) {
               val viewModel: Screen1ViewModel = viewModel()
               Screen1(viewModel = viewModel)
           }
           composable(NavigationDestination.Screen2.destination) {
               val viewModel: Screen2ViewModel = viewModel()
               Screen2(viewModel = viewModel)
           }
       }
    }
    

    后来, 换成这种:

    composable(NavigationDestination.Screen1.destination) {
       val viewModel: Screen1ViewModel = hiltNavGraphViewModel()
       Screen1(viewModel = viewModel)
    }
    

    hiltNavGraphViewModel()做了什么呢?

    • 找ViewModel的owner: Hilt用了LocalViewModelStoreOwner, 可以是Activity, Fragment, 在composable中, 是NavBackStackEntry.

    了解Hilt怎么做之后, 看看Dagger 2.

    setContent {
       val navController = rememberNavController()
    
       NavHost(navController, startDestination = NavigationDestination.Screen1.destination) {
           composable(NavigationDestination.Screen1.destination) {
               // option #1 create a component inside NavBackStackEntry,
               // which can be helpful if we need to provide more than one object from DI here
               val component = DaggerScreen1Component.builder().build()
    
               val viewModel: Screen1ViewModel = daggerViewModel {
                   component.getViewModel()
               }
    
               Screen1(viewModel = viewModel)
           }
           composable(NavigationDestination.Screen2.destination) {
               val viewModel: Screen2ViewModel = daggerViewModel {
                   // option #2 create DI component and instantly get ViewModel instance
                   DaggerScreen2Component.builder().build().getViewModel()
               }
    
               Screen2(viewModel = viewModel)
           }
       }
    }
    

    Infinite auto-scrolling lists with RecyclerView & LazyLists in Compose

    无限自动滚动的list, 有点像走马灯的效果.

    Kotlin SharedFlow or: How I learned to stop using RxJava and love the Flow

    • RxJava后台任务分步骤进行UI显示 -> Flow.
    • 处理热流:
    • PublishSubject -> SharedFlow.
    • BehaviorSubject -> StateFlow.

    一些特点:

    • StateFlow是conflated: 如果新的值和旧的值一样, 不会传播.
    • SharedFlow需要合理设置buffer和replay策略.
    • StateFlowSharedFlow永远都不会停止. 不能指望它们的onCompletionCallback.

    还有文中提到了一个观点, 为什么不继续用LiveData呢? 因为LiveData感觉是跟Android相关的一个类, 而SharedFlow和StateFlow是Kotlin的, 这样感觉domain层脱离了对Android的依赖, 更解耦一些.

    From Junior to Master in Kotlin — 1 (Basic Syntax)

    一些Kotlin的用法.

    Code

    News

    Videos

    相关文章

      网友评论

          本文标题:Android Weekly Notes #466

          本文链接:https://www.haomeiwen.com/subject/djohpltx.html