retrofit+livedata+viewModel+moshi处理数据

news2024/9/22 1:37:35

1.从源码角度看,只需要定义一个CallAdapterFactory 处理结果livedata接受默认的CallAdapterFactory 是DefaultCallAdapterFactory

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package retrofit2;

import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Objects;
import java.util.concurrent.Executor;
import javax.annotation.Nullable;
import okhttp3.Request;
import okio.Timeout;

final class DefaultCallAdapterFactory extends CallAdapter.Factory {
    @Nullable
    private final Executor callbackExecutor;

    DefaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
        this.callbackExecutor = callbackExecutor;
    }

    @Nullable
    public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
        if (getRawType(returnType) != Call.class) {
            return null;
        } else if (!(returnType instanceof ParameterizedType)) {
            throw new IllegalArgumentException("Call return type must be parameterized as Call<Foo> or Call<? extends Foo>");
        } else {
            final Type responseType = Utils.getParameterUpperBound(0, (ParameterizedType)returnType);
            final Executor executor = Utils.isAnnotationPresent(annotations, SkipCallbackExecutor.class) ? null : this.callbackExecutor;
            return new CallAdapter<Object, Call<?>>() {
                public Type responseType() {
                    return responseType;
                }

                public Call<Object> adapt(Call<Object> call) {
                    return (Call)(executor == null ? call : new ExecutorCallbackCall(executor, call));
                }
            };
        }
    }

    static final class ExecutorCallbackCall<T> implements Call<T> {
        final Executor callbackExecutor;
        final Call<T> delegate;

        ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
            this.callbackExecutor = callbackExecutor;
            this.delegate = delegate;
        }

        public void enqueue(final Callback<T> callback) {
            Objects.requireNonNull(callback, "callback == null");
            this.delegate.enqueue(new Callback<T>() {
                public void onResponse(Call<T> call, Response<T> response) {
                    ExecutorCallbackCall.this.callbackExecutor.execute(() -> {
                        if (ExecutorCallbackCall.this.delegate.isCanceled()) {
                            callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled"));
                        } else {
                            callback.onResponse(ExecutorCallbackCall.this, response);
                        }

                    });
                }

                public void onFailure(Call<T> call, Throwable t) {
                    ExecutorCallbackCall.this.callbackExecutor.execute(() -> {
                        callback.onFailure(ExecutorCallbackCall.this, t);
                    });
                }
            });
        }

        public boolean isExecuted() {
            return this.delegate.isExecuted();
        }

        public Response<T> execute() throws IOException {
            return this.delegate.execute();
        }

        public void cancel() {
            this.delegate.cancel();
        }

        public boolean isCanceled() {
            return this.delegate.isCanceled();
        }

        public Call<T> clone() {
            return new ExecutorCallbackCall(this.callbackExecutor, this.delegate.clone());
        }

        public Request request() {
            return this.delegate.request();
        }

        public Timeout timeout() {
            return this.delegate.timeout();
        }
    }
}

综上需要重写这块get 方法以及CallAdapter

在这里插入图片描述

 class  BaseRes<T> (
    var `data`: T?,
    var errorCode: Int,
    var errorMsg: String

)
package com.example.myapplication

import androidx.lifecycle.LiveData
import retrofit2.CallAdapter
import retrofit2.CallAdapter.Factory
import retrofit2.Retrofit
import java.lang.reflect.ParameterizedType
import java.lang.reflect.Type

class LiveDataConverterFactory : Factory() {
    override fun get(
        returnType: Type,
        annotations: Array<out Annotation>,
        retrofit: Retrofit
    ): CallAdapter<*, *>? {
        if (getRawType(returnType) != LiveData::class.java) return null
        val observableType = getParameterUpperBound(0, returnType as ParameterizedType)
        val rawType = getRawType(observableType)
        if (rawType != BaseRes::class.java) {
            throw IllegalArgumentException("type must be BaseRes")
        }
        if (observableType !is ParameterizedType) {
            throw IllegalArgumentException("resource must be parameterized")
        }
        return LiveDataCallAdapter<Any>(observableType)


    }

}
package com.example.myapplication

import androidx.lifecycle.LiveData
import retrofit2.Call
import retrofit2.CallAdapter
import retrofit2.Callback
import retrofit2.Response
import java.lang.reflect.Type
import java.util.concurrent.atomic.AtomicBoolean

class LiveDataCallAdapter<T>(private val responseType: Type) : CallAdapter<T, LiveData<T>> {
    override fun adapt(call: Call<T>): LiveData<T> {
        return object : LiveData<T>() {
            private val started = AtomicBoolean(false)
            override fun onActive() {
                super.onActive()
                if (started.compareAndSet(false, true)) {
                    call.enqueue(object : Callback<T> {
                        override fun onFailure(call: Call<T>, t: Throwable) {
                            val value = BaseRes<T>(null, -1, t.message ?: "") as T
                            postValue(value)
                        }

                        override fun onResponse(call: Call<T>, response: Response<T>) {
                            postValue(response.body())
                        }
                    })
                }
            }
        }
    }

    override fun responseType() = responseType
}


interface BannerService {

    @GET("/banner/json")
    fun listRepos(): LiveData<BaseRes<List<Data>>>
}
package com.example.myapplication

import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.converter.moshi.MoshiConverterFactory

class RetrofitUtils {
    companion object {
        private var BaseURL = "https://www.wanandroid.com/"
        fun getHttp(): Retrofit {
            return Retrofit.Builder().baseUrl(BaseURL).client(initClient())
                .addConverterFactory(MoshiConverterFactory.create())
                .addCallAdapterFactory(LiveDataConverterFactory())
                .build()
        }

        private fun initClient(): OkHttpClient {
            val newBuilder = OkHttpClient().newBuilder()
            return newBuilder.build()
        }

    }


}
 val bannerModel = ViewModelProvider(this)[NetModel::class.java]
            bannerModel.loadData().observe(this) {
                println("获取的数据${it.data}")

                Picasso.get().load(it.data?.get(0)!!.imagePath).into(inflate.iv)
            }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2048684.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

那不勒斯足球俱乐部在 The Sandbox 中启动

访问 The Sandbox 中的那不勒斯足球俱乐部快闪商店&#xff0c;赢取比赛门票和签名商品。 我们很高兴地宣布&#xff0c;我们将与意大利著名职业足球俱乐部那不勒斯足球俱乐部展开合作&#xff0c;在 4 个 UGC 体验中开设 “快闪商店”。在这个以传奇球队为灵感来源的独特数字…

[Meachines] [Medium] poison LFI+日志投毒+VNC权限提升

信息收集 IP AddressOpening Ports10.10.10.84TCP:22,80 $ nmap -p- 10.10.10.84 --min-rate 1000 -sC -sV 22/tcp open ssh OpenSSH 7.2 (FreeBSD 20161230; protocol 2.0) | ssh-hostkey: | 2048 e3:3b:7d:3c:8f:4b:8c:f9:cd:7f:d2:3a:ce:2d:ff:bb (RSA) | 256 …

Linux - 基础工具使用

文章目录 一、yum1、介绍2、功能3、语法4、使用 二、rzsz1、安装rzsz的指令2、介绍3、使用 三、vim基础使用1、介绍2、基础使用 四、gcc/g使用1、生成可执行文件过程2、语法3、常用选项4、编译过程5、动静态库6、链接外部库 一、yum 1、介绍 Linux中的yum是一个强大的软件包管…

部署 K8s 图形化管理工具 Dashboard

文章目录 一、Dashboard 概述二、GitHub 地址三、Dashboard 部署安装1、选择兼容版本2、下载配置文件3、添加 Dashboard 的Service类型4、应用部署5、查看 kubernetes-dashboard 命名空间下资源状态6、创建访问账户7、授权8、获取账号token9、1.24 版本以后的需要创建一个Pod 四…

STM32入门开发操作记录(九)——外部时钟定时器

目录 一、项目准备1. 工程模板2. 器件接线 二、外部时钟1. 端口复用2. 流程示意 三、定时器模块Timer.cTimer.h 四、遮光计数 一、项目准备 1. 工程模板 本篇项目所用模板包含以下模块&#xff0c;声明函数见头文件&#xff0c;模块添加和函数功能详见往期记录。   2. 器件…

alibabacloud学习笔记13

微服务Docker镜像打包讲解 父项目怎么springboot版本依赖 每个子模块项目添加依赖 添加构建文件&#xff1a; 微服务Docker镜像打包整合JDK11 服务根目录创建dockerFile文件. dockerFile的内容。 构建镜像( 去到子模块pom文件下)&#xff1a; 要下载这个才能使用本地docker.…

linux常用网络工具汇总三

linux常用网络工具汇总 6. 抓包工具6.1 wireshark安装界面介绍使用过滤器TCP协议示例关于wireshark的缺点 6.2 tcpdump命令格式关键字使用关于tcpdump的缺点 6.3 fiddler6.4 burpsuite 6. 抓包工具 6.1 wireshark Wireshark&#xff08;前称Ethereal&#xff09;是一个网络封…

谷歌账号异常后,恢复账号的时候验证手机号出现这样的界面就悬了

朋友们在使用谷歌账号玩游戏&#xff0c;或者浏览一些内容的时候&#xff0c;甚至啥也不干&#xff0c;过一阵仅仅来登录谷歌的时候可能会发现账号无法顺利登录。 往往是输入了谷歌账号&#xff08;邮箱地址&#xff09;后&#xff0c;经历过了纠结的人机验证后&#xff0c;输…

leetcode热题系列14

540. 有序数组中的单一元素 给定一个只包含整数的有序数组&#xff0c;每个元素都会出现两次&#xff0c;唯有一个数只会出现一次&#xff0c;找出这个数。 示例 1: 输入: [1,1,2,3,3,4,4,8,8] 输出: 2 示例 2: 输入: [3,3,7,7,10,11,11] 输出: 10 思路&#xff1a; 利用逻…

适合毕业生!分享好用的9款AI论文写作软件

对于即将毕业的大学生来说&#xff0c;撰写论文是一项既重要又具挑战性的任务。为了帮助大家更高效地完成这一过程&#xff0c;我将推荐几款适合毕业生使用的AI论文写作软件&#xff0c;并详细介绍它们的功能和优势。 1. 千笔-AIPassPaper 千笔-AIPassPaper是一款功能全面且用…

【Python学习-UI界面】PyQt5 小部件4-QRadioButton

样式如下&#xff1a; QRadioButton 类对象是一个带有文本标签的可选择按钮。用户可以在表单上选择其中一个选项。该类派生自QAbstractButton类。 单选按钮默认是自动排斥的。因此&#xff0c;在父窗口中只能选择一个单选按钮。 如果选择了其中一个按钮&#xff0c;则之前选择…

微信小程序在不同移动设备上的差异导致原因

在写小程序的时候用了rpx自适应单位&#xff0c;但是还是出现了在不同机型上布局不统一的问题&#xff0c;在此记录一下在首页做一个输入框&#xff0c;在测试的时候&#xff0c;这个输入框在不同的机型上到处跑&#xff0c;后来排查了很久都不知道为什么会这样 解决办法是后 …

红日靶场vulnstack (二)

环境搭建 环境其实和vulnstack (一)差不多滴&#xff0c;只是变成有两台主机是具有两个IP的了。所有账号登录密码为1qazWSX&#xff0c;域管理员账号为administrator&#xff0c;密码和前面的一样。 Web&#xff1a;192.168.145.144(外)&#xff0c;192.168.215.31(内) PC&am…

基因组学系列4:参考转录本数据库MANE

1. 参考转录本数据库MANE简介 为了促进临床参照的一致性&#xff0c;美国国家生物技术信息中心( NCBI)和欧洲分子生物学实验室-欧洲生物信息学研究所(EMBL-EBI)合作发布了参考转录本数据库MANE&#xff08;Matched Annotation from the NCBI and EMBL-EBI&#xff09;&#xf…

Python之格式化输出

格式化输出 方法一&#xff1a;用%方法二&#xff1a;用format()函数设置输出的内容的宽度和小数位数 方法一&#xff1a;用% 直接用print()函数对字符串进行输出&#xff0c;是没有进行格式化控制的。 格式化&#xff0c;是对输出内容的显示方式进行设置。 首先&#xff0c;要…

有名管道和信号

3.无名管道 只能用于 亲缘关系 进程间 A.c B.c | | A B 有名管道 fifo&#xff1a;先入先出 创建有名管道&#xff1a;makepipe 1.是一种特殊文件 a.存在于 内存中 b.在系统中&#xff0c;有一个对应的名称 c.看文件的大小 0bytes pathname…

仓颉编程语言入门 -- I/O 流概述

I/O 流概述 一 . 什么是I/O 在仓颉编程语言的设计理念中&#xff0c;与外部实体&#xff08;如文件系统、网络、用户输入等&#xff09;的数据交换活动被统称为I/O操作&#xff0c;其中“I”代表输入&#xff08;Input&#xff09;&#xff0c;而“O”则代表输出&#xff08;O…

算法打卡 Day22(二叉树)-最大二叉树 + 合并二叉树 + 二叉搜索树中的搜索 + 验证二叉搜索树

文章目录 Leetcode 654-最大二叉树题目描述解题思路 Leetcode 617-合并二叉树**题目描述**解题思路 Leetcode 700-二叉搜索树中的搜索**题目描述**解题思路 Leetcode 98-验证二叉搜索树**题目描述**解题思路 Leetcode 654-最大二叉树 题目描述 https://leetcode.cn/problems/…

Nginx--虚拟机配置

前言&#xff1a;本博客仅作记录学习使用&#xff0c;部分图片出自网络&#xff0c;如有侵犯您的权益&#xff0c;请联系删除 1、什么是虚拟主机 虚拟主机是一种特殊的软硬件技术&#xff0c;它可以将网络上的每一台计算机分成多个虚拟主机&#xff0c;每个虚拟主机可以独立对…

C语言日常练习 Day16

目录 一、求一个3*3的整型矩阵对角线元素之和 二、有一个已经排序好了的数组&#xff0c;要求输入一个数后&#xff0c;按原来排序的规律将它插入数组中 三、输出“魔方阵”&#xff0c;所谓魔方阵是指它的每一行、每一列和对角线之和均相等 一、求一个3*3的整型矩阵对角线元…