Android Weekly Notes

Android Weekly Notes #463

2021-06-20  本文已影响0人  圣骑士wind

Android Weekly Issue #463

Room auto-migrations

Room 2.4.0-alpha01推出了Auto migration, 让数据库迁移更加容易.

@Database(
   version = 2,
   entities = [ GoodDoggos.class ],
   autoMigrations = [
        AutoMigration (
            from = 1, 
            to = 2,
            spec = DoggosDatabase.DoggosAutoMigration::class
       )
    ]
)
abstract class DoggosDatabase : RoomDatabase {   
  @RenameTable(fromTableName = "Doggos", toTableName = "GoodDoggos")
    class DoggosAutoMigration: AutoMigrationSpec {   }
}

自动迁移可以和手动迁移结合, 满足开发者的需求.

对于自动迁移还有测试的支持.

A Compose & Viewmodel integration test with Hilt

一个简单的小例子, UI是用Compose, 注入用Hilt.

ViewModel中的state类型:

sealed class UiState {
    object Loading : UiState()
    object Empty : UiState()
    data class Content(val items: List<Item> = listOf()) : UiState()
}

Repository返回flow, flow转UiState的方法:

private suspend fun Flow<List<Item>>.toUiState(): Flow<UiState> = map {
    if (it.isEmpty()) {
        UiState.Empty
    } else {
        UiState.Content(items = it)
    }
}.onStart {
    emit(UiState.Loading)
}

测试的时候, 需要假数据, 所以替换掉了Repository:

@TestInstallIn(components = [SingletonComponent::class],
    replaces = [InventoryRepositoryModule::class])
@Module
object FakeInventoryRepositoryModule {
    @Singleton
    @Provides
    fun provideFakeInventoryRepository() = object : InventoryRepository {
        @ExperimentalCoroutinesApi
        override suspend fun items(): Flow<List<Item>> {
            return flowOf(dummyItems)
        }
    }
}

需要test runner:

class HiltTestRunner : AndroidJUnitRunner() {
    override fun newApplication(
        cl: ClassLoader?,
        className: String?,
        context: Context?,
    ): Application {
        return super.newApplication(cl, HiltTestApplication::class.java.name, context)
    }
}

最后测试写成这样:

@ExperimentalCoroutinesApi
@HiltAndroidTest
class ItemListTest {

    @get:Rule(order = 1)
    var hiltTestRule = HiltAndroidRule(this)

    @get:Rule(order = 2)
    var composeTestRule = createAndroidComposeRule<MainActivity>()

    @Before
    fun setup() {
        hiltTestRule.inject()
        composeTestRule.setContent {
            TallyApp(composeTestRule.activity.viewModels<ListViewModel>().value)
        }
    }

    @Test
    fun app_displays_list_of_items() {
        //assert the list is displayed
        composeTestRule.onNodeWithTag(InventoryListTag).assertIsDisplayed()

        //assert all items exist within the tree
        dummyItems.forEach { item -> 
            composeTestRule.onNodeWithText(item.name).assertExists()
        }
    }
}

Tap Response Time: Jetpack Navigation

关于点击响应时间的进一步探索.

Navigation Drawer using Jetpack Compose

Navigation Drawer的Compose实现.

代码见:
https://github.com/walnashgit/ComposeNavigationDrawer/tree/feature/ComposeNavDrawerUsingModalDrawer

Unit testing on Android

单元测试:

测试LiveData还有一个工具类.

Lessons learned when migrating my app to Jetpack Compose

一些经验和资源介绍.

Getting ready for Declarative UIs — Part 3 — Why Declarative UIs on Android?

为什么要用声明式UI.

CoroutineScope and coroutineContexts

关于测试中CoroutineContext的探讨.

always keep currentCoroutineContext() and coroutineContext pointing to the same value.

Pi Practice App in Compose

一个小应用, 之前使用Anko做的, 现在改用Compose做了.

Code

上一篇下一篇

猜你喜欢

热点阅读