在Android架構組件基礎上,融入Kotlin 協程+retrofit,模擬網絡,全面快速開發。
Navigation
NavController在 NavHost 中管理應用導航的對象,沿導航圖中的特定路徑導航至特定目標,或直接導航至特定目標。
首先,定義 layout/activity_main.xml
<fragment
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:layout_constraintBottom_toTopOf="@id/nav_view"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/mobile_navigation" />
其次,定義 navigation/mobile_navigation.xml
Activity的添加,需要先在Project創建對應的Activity,即可在佈局設計器處理。
<navigation
<fragment
android:id="@+id/navigation_home"
android:name="com.android.myapplication.ui.home.HomeFragment"
android:label="@string/title_home"
tools:layout="@layout/fragment_home">
<action
android:id="@+id/action_navigation_home_to_detail_activity"
app:destination="@id/detail_activity" />
</fragment>
...
<activity
android:id="@+id/detail_activity"
android:name="com.android.myapplication.ui.detail.DetailActivity"
android:label="DetailActivity">
<argument
android:name="detailId"
app:argType="string" />
</activity>
</navigation>
最後,頁面跳轉,參數傳遞
val direction = HomeFragmentDirections.actionNavigationHomeToDetailActivity(plantId)
view.findNavController().navigate(direction)
參數接收:
private val args: DetailActivityArgs by navArgs()
Databinding
在onCreateView()中直接使用控件,會報空指針異常,這個姿勢 binding.tvNavigation 是可以的。
val binding = FragmentHomeBinding.inflate(inflater, container, false)
binding.tvNavigation.setOnClickListener {
navigateToDetailPage("1", it)
}
佈局文件中,字符串拼接,如跟ViewModel一起使用:
android:text='@{"Data From Network-> "+viewModel.response}'
ViewModel
以生命週期的方式存儲和管理界面相關的數據。
Kotlin協程 viewModelScope, 如果 ViewModel 已清除,則在此範圍內啓動的協程都會自動取消。
private val homeViewModel: HomeViewModel by viewModels {
InjectorUtils.provideHomeViewModelFactory(requireContext())
}
viewModelScope.launch {
...
}
LiveData
一種可觀察的數據存儲器類,具有生命週期感知能力,意指它遵循其他應用組件(如 Activity、Fragment 或 Service)的生命週期。
var plantName = gardenPlantings.map {
...
}
map 實現LiveData的轉換
Room
創建應用數據的緩存, SQLite 的基礎上提供了一個抽象層,充分利用 SQLite 的強大功能,更強健的數據庫訪問機制。
使用 Room 引用複雜數據,Room 提供了在基本類型和包裝類型之間進行轉換的功能,但不允許實體之間進行對象引用。
要爲自定義類型添加此類支持,您需要提供一個 TypeConverter,它可以在自定義類與 Room 可以保留的已知類型之間來回轉換。
class Converters {//TypeConverters ...}
將 @TypeConverters 註釋添加到 AppDatabase 類中,以便 Room 可以使用您爲該 AppDatabase 中的每個實體和 DAO 定義的轉換器:
@Database(entities = table, version = 1, exportSchema = false)
@TypeConverters(Converters::class)
abstract class AppDatabase : RoomDatabase() {
...
}
@Insert
suspend fun insertPlant(plant: Plant): Long
認爲是協程suspend
WorkManager
使用 WorkManager API 可以輕鬆地調度即使在應用退出或設備重啓時仍應運行的可延遲異步任務。
val workManagerConfiguration = Configuration.Builder()
.setWorkerFactory(RefreshDataWork.Factory())
.build()
WorkManager.initialize(appContext, workManagerConfiguration)
val constraints = Constraints.Builder()
.setRequiresCharging(true)
.setRequiredNetworkType(NetworkType.CONNECTED)
.build()
val work = PeriodicWorkRequestBuilder<RefreshDataWork>(2, TimeUnit.HOURS)
.setConstraints(constraints)
.build()
WorkManager.getInstance(appContext)
.enqueueUniquePeriodicWork(RefreshDataWork::class.java.name, KEEP, work)
PeriodicWorkRequest 用於重複或重複工作,最小間隔應爲15分鐘。
OneTimeWorkRequest 一次性申請,不重複工作。
WorkManager按順序執行,單例模式,app啓動時執行一次。
代碼Github的下載地址:
https://github.com/AlbertShen0211/Android-architecture-components
爲了更好的理解代碼,附圖如下