零蚀
[? Jetpack教程基础篇]
目录
? 大纲
? Android 知识栈
? Android Jetpack 系列
? NO.1 Jetpeck 基础<ViewModel & Room>
? NO.2 Jetpeck 基础<Fra导航 & ListAdapter>
Retrofit
-
数据的加载
- 官网上推荐了一个Moshi解析json的库,它是一个 Android JSON 解析器,可将 JSON 字符串转换为 Kotlin 对象。Retrofit 有一个可与 Moshi 配合使用的转换器,所以这里使用了moshi。
//retrofit implementation "com.squareup.retrofit2:retrofit:$version_retrofit" implementation "com.squareup.retrofit2:converter-moshi:$version_retrofit" //implementation "com.squareup.retrofit2:converter-scalars:$version_retrofit"//Moshi implementation "com.squareup.moshi:moshi-kotlin:$version_moshi"
- Moshi官方除了介绍它是专门针对kotlin解析json的库外,它的使用方法,和常用的gson或JSONObject类似,它默认根据json的参数名称来匹配bean中的属性名,你也可以指定
/*** @author ben* @description * @time 2021/7/14*/ data class MarData (val id: String,@Json(name = "img_src") val img_src: String,val type: String,val price: Double)
- 构建我们的数据地址
const val BASE_URL = "https://android-kotlin-fun-mars-server.appspot.com" ... interface ApiServer { /*** 添加路径*/@GET("realestate")fun getProperties(): Call<List<MarData>> }
- 构建Retrofit对象,和接收到数据后,通知viewModel进行更新,这里用的Adapter还是官网推荐的ListAdapter。
open class BaseNetUtil { private var moshi:Moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()private var retrofit:Retrofitinit { retrofit = Retrofit.Builder().addConverterFactory(MoshiConverterFactory.create(moshi)).baseUrl(Parameter.BASE_URL).build()}/*** 直到调用时候开始进行耗损资源的操作,所以只在第一次调用的时候初始化。*/private val retrofitService: ApiServer by lazy { retrofit.create(ApiServer::class.java)}/***当数据成功收到时候通知ViewModel*/fun getMarData(data : MutableLiveData<List<MarData>>){ retrofitService.getProperties().enqueue(object : Callback<List<MarData>> { override fun onResponse(call: Call<List<MarData>>, response: Response<List<MarData>>) { data.postValue(response.body())}override fun onFailure(call: Call<List<MarData>>, c: Throwable) { }})} }// ViewModel部分的代码更新 private fun addData(owner:LifecycleOwner) { viewModelScope.launch(Dispatchers.IO){ BaseNetUtil().getMarData(data)}data.observe(owner, Observer { adapter.submitList(it as MutableList<MarData>)})}
- 有一点需要注意的是,retrofit安装之后是需要分包,所以添加了依赖和初始化,并且还需要指定是java8
//applicationMultiDex.install(this); //defaultConfig multiDexEnabled true //androidcompileOptions { sourceCompatibility JavaVersion.VERSION_1_8targetCompatibility JavaVersion.VERSION_1_8 } //dependenciesimplementation 'com.android.support:multidex:1.0.3'
- 最后强调一点,这个数据看域名就知道是US的,所以正常情况下国内是访问不到的。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9uLEqD4j-1626337077376)(media/16260614201077/16263148673142.jpg)]
- 官网加载图片给出了,加载成功,失败,加载中的样式
Glide.with(imgView.context).load(imgUri).apply(RequestOptions().placeholder(R.drawable.loading_animation).error(R.drawable.ic_broken_image)).into(imgView)
WorkManager
-
介绍
-
WorkManager是一个可以优化并高效的管理后台事件处理的工具,像我们经常会在后台处理一些长时间运行的后台任务,例如一些数据的上传下载,这让人很容易想到了service。
-
WorkManager工作于有延迟性,具有保障的后台任务,延迟性表示不是立即响应,保障性表示即使应用退出,或者重启,任务也会运行。
-
在WorkManager运行后台工作时,它会处理兼容性问题以及电池和系统运行状况的最佳实践。WorkManager兼容到API 14。WorkManager根据设备 API 级别选择合适的方式来安排后台任务。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-but0xcKw-1626337077377)(media/16260614201077/16263284244219.jpg)]
- 除此之外,workManager还可以自己定义任务执行标准,比如电池状态,或者是网络状态。但是WorkManger也有其不适用的场景,比如说,它不能在已经被kill掉的app进程的进程后台进行工作,也不适合那些需要立即执行的任务。
implementation "android.arch.work:work-runtime-ktx:$work_version"
- 服务的启动地点,官网推荐是在application中,因为这里有acitivty和sevice的基类
open class RefreshData(context: Context, params: WorkerParameters):CoroutineWorker(context,params){ companion object { const val WORK_NAME = "zero_refresh_data_1"}/*** 这里使用挂起,主要是为了其不会阻塞主线程,可以执行长时间的任务,也可以对任务进行恢复和暂停*/override suspend fun doWork(): Result { //Result.retry() 工作遇到暂时性故障,应重试Log.e("zero", "main thread doWork: ")return Result.success()}} // Application /*** 设置工作的类型 WorkRequest* OneTimeWorkRequest 一次性的任务* PeriodicWorkRequest 周期性任务,如下,设置周期为5s每次*/ open fun setupRecurringWork(){ // 添加限制条件val constraints = Constraints.Builder().setRequiredNetworkType(NetworkType.NOT_REQUIRED) // 不考虑网络是否连接.setRequiresBatteryNotLow(false) //是否在低电量的时候运行.setRequiresCharging(false) //更新工作请求,使其仅在设备充电时运行.build()val repeatingRequest = PeriodicWorkRequestBuilder<RefreshData>(15, TimeUnit.MINUTES).setConstraints(constraints).build()WorkManager.getInstance().enqueueUniquePeriodicWork(RefreshData.WORK_NAME, // 任务的唯一名称ExistingPeriodicWorkPolicy.KEEP,// keep表示如果同名任务有新任务,保留原先任务,丢弃新任务请求 、REPLACE反之repeatingRequest)}
- 这里最小的时间间隔是15分钟。
07-15 15:46:29.222 E/zero: main thread doWork: 07-15 16:01:29.233 E/zero: main thread doWork:
-