当前位置: 代码迷 >> 综合 >> NO.3 Jetpeck 基础<Retrofit WorkManager>
  详细解决方案

NO.3 Jetpeck 基础<Retrofit WorkManager>

热度:79   发布时间:2023-12-15 16:08:25.0

零蚀
[? 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: 
    
  相关解决方案