Android LiveData + Retrofit 取消请求

Android OkHttp + Retrofit 取消请求的方法 在某一个界面,用戶發起了一個網絡請求,由於某種緣由用戶在網絡請求完成前離開了當前界面,比較好的作法是取消這個網絡請求。對於OkHttp來講,具體是調用Call的cancel方法。如何找到這一個網絡請求並取消掉它呢?操做大體分爲3步。第一步,在創建請求時,給請求(request)添加標記;第二步,根據標記,找到請求;最後,取消這個請求。要取消一個請求,OkHttp中能夠使用cancel方法OkHttp的request對象有tag。能夠根據tag來標示請求。 Retrofit中並無顯示地提供取消請求的接口。 阅读详情

Android LiveData + Retrofit 取消请求(一)


我们先看看OkHttp是怎么取消请求的

OkHttp 中取消请求
OkHttp 创建、发送请求
        //创建OkHttpClient
         OkHttpClient   mOkHttpClient = new OkHttpClient().newBuilder().build();
         //创建Request,添加tag标记,tag 类型为Object,用tag来取消请求
         Request.Builder builder = new Request.Builder();
         Request request =  builder.url("requestUrl").tag("request").build();
         //创建准备要执行请求的Call
        final Call call = mOkHttpClient.newCall(request);
         //调度发起异步请求
         call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {

            }
        });
取消请求
      /**
         * 根据tag取消请求
         * @param tag
         */
   public void cancelTag(Object tag) {
         if (mOkHttpClient == null)
            return;
        for (Call call : mOkHttpClient.dispatcher().queuedCalls()) {
            if (tag.equals(call.request().tag())) {
                call.cancel();
            }
        }
        for (Call call : mOkHttpClient.dispatcher().runningCalls()) {
            if (tag.equals(call.request().tag())) {
                call.cancel();
            }
        }
    }

调用cancelTag(“request”)取消上面创建的请求

看一下cancel的方法

  /** Cancels the request, if possible. Requests that are already complete cannot be canceled. */
  void cancel();

如果可能的话,取消请求。已完成的请求无法取消

我们都知道Retrofit是基于OkHttp的再次封装,Retrofit 怎么取消请求呢?

Retrofit中取消请求

Retrofit并没有显示地提供能访问OkHttp的tag方法,2018年时Retrofit仍未提供直接访问call对象的方法

JakeWharton 提供了一些提示

You might be able to add dummy headers and loop through OkHttp's in-flight Calls and match on them that way though.
您可以添加虚拟的头文件,并循环使用OkHttp的动态调用,然后通过这种方式对它们进行匹配

what mean?

联网查询了下,原来是先在请求interface Service中提供的Call方法添加注解Header,然后在拦截器进行匹配取消

举个栗子

当Activity,Fragment 将要销毁时,取消未完成的请求,就要对页面添加标记,代表着页面生存状态,那就需要一个集合来管理这个标记

创建存放Tag的集合
public class NetTagManager {
    private static ConcurrentHashMap<String, Boolean> actLiveMap = new ConcurrentHashMap<>(); // 标记Activity是否存活

    public static void markPageAlive(String actName) {
        actLiveMap.put(actName, true);
    }

    public static void markPageDestroy(String actName) {
        actLiveMap.put(actName, false);
    }

    public static ConcurrentHashMap<String, Boolean> getActLiveMap() {
        return actLiveMap;
    }
}
在Activity中管理页面状态
private  final String MY_ACT_NAME = getClass().getSimpleName();
 @Override
 protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    NetTagManager.markPageAlive(MY_ACT_NAME);
     //发起请求
     RequestCreator.getRequestService().post(MY_ACT_NAME,...,...).enqueue(...);
  }
  
     @Override
  protected void onDestroy() {
     NetTagManager.markPageDestroy(TAG);
   }

下面就是Retrofit的处理

创建请求Service Interface,添加Head注解
public class Base {
 //定义注解Head的key
 public static final String HEAD_TAG = "TAG_NAME";
}
public interface RequestService {
 
     @FormUrlEncoded
     @POST
    Call<String> post(@Header(Base.HEAD_TAG) String actName, @Url String url, @FieldMap           Map<String, Object> params);  
}  
创建Retrofit对象,并在OkHttpClient中添加Cancel 拦截器
public class RequestCreator {
private static final String BASE_URL = "http://...";  
private static final Retrofit RETROFIT_CLIENT =
              new Retrofit.Builder().baseUrl(BASE_URL).
                      ... 
                      .client(OkHttpHolder.OK_HTTP_CLIENT).build();
 private static  final  class  OkHttpHolder{
    
        private static final int TIME_OUT = 60;
        private static final OkHttpClient OK_HTTP_CLIENT = new OkHttpClient.Builder().
                 connectTimeout(TIME_OUT, TimeUnit.SECONDS)
                .addInterceptor(new CancelInterceptor())
                .build();
  
     }
private static final RequestService REQUEST_SERVICE = RETROFIT_CLIENT.create(RequestService.class);
 public static  RequestService getRequestService(){
        return  REQUEST_SERVICE;
    }    
}

//在拦截器中检查页面的存活情况。检查后,把这个自定义header移除掉
//Cancel interceptor
public class CancelInterceptor implements Interceptor{
    private static final String TAG = CancelInterceptor.class.getSimpleName();
    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        String actName = request.header(Base.HEAD_TAG);
        Log.d(TAG,"actName==="+actName);
        if (!TextUtils.isEmpty(actName)){
            Log.d(TAG,"HeadName==="+actName);
            boolean actLive = NetTagManager.getActLiveMap().get(actName);
            if(!actLive){
               chain.call().cancel();
                Log.d(TAG, "取消请求, actName: " + actName);
            }else{
                Log.d(TAG, "发起请求, actName: " + actName);
            }
        }
         Request newRequest = request.newBuilder().removeHeader(Base.HEAD_TAG).build();
        return chain.proceed(newRequest);

    }
}
在Activity中发起请求
 RequestCreator.getRequestService().post(MY_ACT_NAME,...,...).enqueue(...);

还有一种 实现CallAdapter.Factory方法:

来源于retrofit-helper 简洁的封装retrofit

Retrofit 可以添加CallAdapter,根据Retrofit默认的DefaultCallAdapterFactory

,通过添加修改CallAdapter.Factory的实现类,也就是用addCallAdapterFactory()添加一个适配器,如:

private static final Retrofit RETROFIT_CLIENT = 
new Retrofit.Builder().baseUrl(BASE_URL)
.addCallAdapterFactory(ExecutorCallAdapterFactory().create())...;

需要自己实现一个CallAdapterrFactory,在enqueue(Object tag, final Callback callback)中关联tag和Call,

其中Call2实现了retrofit中的Call 并且添加enqueue(Object tag, final Callback callback)方法

public interface Call2<T> extends Call<T> {
    void enqueue(Object tag,Callback<T> callback);
     Call2<T> clone();
}
public class ExecutorCallAdapterFactory extends CallAdapter.Factory {
    @Override
    public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
         //Call2实现了retrofit中的Call  
        if (getRawType(returnType) != Call2.class) {
            return null;
        }
        if (!(returnType instanceof ParameterizedType)) {
            throw new IllegalArgumentException(
                    "Call return type must be parameterized as Call<Foo> or Call<? extends Foo>");
        }
        final Type responseType = getParameterUpperBound(0, (ParameterizedType) returnType);

        final Executor executor = retrofit.callbackExecutor();
        if (executor == null) {
            throw new NullPointerException("executor is null");
//            executor = new MainThreadExecutor();
        }
        return new CallAdapter<Object, Object>() {
            @Override
            public Type responseType() {
                return responseType;
            }

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

    static class MainThreadExecutor implements Executor {
        private final Handler handler = new Handler(Looper.getMainLooper());

        @Override
        public void execute(Runnable r) {
            handler.post(r);
        }
    }

    public static Type getParameterUpperBound(int index, ParameterizedType type) {
        Type[] types = type.getActualTypeArguments();
        if (index < 0 || index >= types.length) {
            throw new IllegalArgumentException(
                    "Index " + index + " not in range [0," + types.length + ") for " + type);
        }
        Type paramType = types[index];
        if (paramType instanceof WildcardType) {
            return ((WildcardType) paramType).getUpperBounds()[0];
        }
        return paramType;
    }

    static <T> T checkNotNull(T object, String message) {
        if (object == null) {
            throw new NullPointerException(message);
        }
        return object;
    }

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

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

        @Override
        public void enqueue(final Callback<T> callback) {
            throw new UnsupportedOperationException("please call enqueue(Object tag, Callback callback)");
//            checkNotNull(callback, "callback == null");
        }

        @Override
        public boolean isExecuted() {
            return delegate.isExecuted();
        }

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

        @Override
        public void cancel() {
            delegate.cancel();
        }

        @Override
        public boolean isCanceled() {
            return delegate.isCanceled();
        }

        @Override
        public void enqueue(Object tag, final Callback<T> callback) {
            CallManager.getInstance().add(tag != null ? tag : "NO_TAG", this);
            delegate.enqueue(new Callback<T>() {
                @Override
                public void onResponse(Call<T> call, final Response<T> response) {
                    callbackExecutor.execute(new Runnable() {
                        @Override
                        public void run() {
                            if (delegate.isCanceled()) {
                                // Emulate OkHttp's behavior of throwing/delivering an IOException on cancellation.
                                callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled"));
                            } else {
                                callback.onResponse(ExecutorCallbackCall.this, response);
                            }
                        }
                    });
                }

                @Override
                public void onFailure(Call<T> call, final Throwable t) {
                    callbackExecutor.execute(new Runnable() {
                        @Override
                        public void run() {
                            callback.onFailure(ExecutorCallbackCall.this, t);
                        }
                    });
                }
            });

        }

        @SuppressWarnings("CloneDoesntCallSuperClone") // Performing deep clone.
        @Override
        public Call2<T> clone() {
            return new ExecutorCallbackCall<>(callbackExecutor, delegate.clone());
        }

        @Override
        public Request request() {
            return delegate.request();
        }
    }

}

CallManage 管理tag和Call

public interface ActionManager<T> {
    void add(T tag, Call call);
    void remove(T tag);
    void removeAll();
    void cancel(T tag);
    void cancelAll();
}
public class CallManager implements ActionManager<Object> {

    private static final String TAG = CallManager.class.getSimpleName();
    private static CallManager sInstance = null;
        private ArrayMap<Object, Call> maps;
        public static CallManager getInstance() {
            if (sInstance == null) {
                synchronized (CallManager.class) {
                    if (sInstance == null) {
                        sInstance = new CallManager();
                    }
                }
            }
            return sInstance;
        }

        private CallManager() {
            maps = new ArrayMap<>();
        }

    @Override
    public void add(Object tag, Call call) {
        Log.d(TAG,"Add Call=="+tag);
        maps.put(tag, call);
    }

    @Override
    public void remove(Object tag) {
        if (!maps.isEmpty()) {
            maps.remove(tag);
        }
    }

    public void removeAll() {
            if (!maps.isEmpty()) {
                maps.clear();
            }
        }

    @Override
    public void cancel(Object tag) {
        if (maps.isEmpty()) {
            return;
        }
        Log.d(TAG,"cancel Call=="+tag);
        Call call =  maps.get(tag);
        if (call != null) {
            call.cancel();
            remove(tag);
        }
    }
        @Override
        public void cancelAll() {
            if (maps.isEmpty()) {
                return;
            }
            Set<Object> keys = maps.keySet();
            for (Object key : keys) {
                    cancel(key);
            }
         }
}

用法如下:

Retrofit RETROFIT_CLIENT =
        new Retrofit.Builder().baseUrl(BASE_URL).
                .addCallAdapterFactory(ExecutorCallAdapterFactory.create())
               .client(OkHttpHolder.OK_HTTP_CLIENT).build();
@FormUrlEncoded
@POST
Call2<String> postCancel(@Url String url, @FieldMap Map<String, Object> params);
RequestCreator.getRequestService().postCancel().enqueue("request", new Callback<String>() {
    @Override
    public void onResponse(Call<String> call, Response<String> response) {
        
    }

    @Override
    public void onFailure(Call<String> call, Throwable t) {

    }
});

参考:Android OkHttp + Retrofit 取消请求的方法

​ retrofit-helper 简洁的封装retrofit

告别Callback Hell!用Kotlin协程重构你的Android网络请求层(附完整代码) 本文详细介绍了如何使用Kotlin协程重构Android网络请求层,解决传统回调地狱(Callback Hell)问题。通过协程的挂起函数和结构化并发特性,开发者可以编写线性同步风格的代码,提升可读性和维护性。文章包含完整代码示例,涵盖Retrofit协程化配置、并发请求优化、错误处理策略等实用技巧,帮助Android开发者高效实现网络请求层的现代化改造。 阅读详情

相关推荐

LiveData+Retrofit网络请求实战

RxJava与Retrofit 在出现LiveData之前,Android上实现网络请求最常用的方式是使用Retrofit+Rxjava。通常是RxJavaCallAdapterFactory将请求转成Observable(或者Flowable等)被观察者对象,调用时通过subscribe方式实现最终的请求。为了实现线程切换,需要将订阅时的线程切换成io线程,请求完成通知被观察者时切换成ui线程...

weixin_45365889的博客 5460

Android网络请求生命周期管理:LiveData与Retrofit请求取消的三种方案

在Android应用开发中,内存泄漏和资源管理是影响应用稳定性的核心问题。当使用MVVM架构配合LiveData和Retrofit进行网络请求时,若缺乏对请求生命周期的有效管理,未完成的网络请求可能持续占用资源,导致内存泄漏、数据错乱甚至应用崩溃。其技术原理在于LiveData仅管理数据观察者的生命周期,而Retrofit的请求默认独立执行,两者生命周期错配。通过手动管理Call引用、利用协程的协作式取消或集成RxJava的Disposable,可以将UI组件的生命周期事件传递至网络层,实现请求的及时取消。

weixin_34302798的博客 417

Retrofit实战指南:Android网络请求从入门到生产级落地

Retrofit是Android开发中主流的类型安全HTTP客户端,其本质是构建在OkHttp之上的声明式网络抽象层,通过注解将Java接口映射为HTTP请求,并借助Gson等Converter完成JSON与对象的自动序列化。它解决了传统AsyncTask+HttpURLConnection模式下手动拼URL、解析JSON、线程切换易错等工程痛点,显著提升网络层可维护性与稳定性。在电商、金融、IoT等真实业务场景中,Retrofit需配合OkHttp连接池、超时控制、拦截器链及生命周期管理才能发挥最大价值。

快马扬鞭须努力! 755

retrofit http取消请求

1.Retrofit取消请求Call<LoginResult> call = apiService.getData("Tamic", "1234"); call.enqueue(new Callback<LoginResult>() { @Override public void onResponse(Call<LoginResult> call, Response<LoginRe

博水之野,人杰地灵 4742

Android项目架构优化与网络请求管理实战

MVVM(Model-View-ViewModel)模式是一种为解决UI交互和业务逻辑分离而设计的软件架构模式。它的一个核心优点是实现了视图(View)和模型(Model)之间的解耦。通过ViewModel来桥接两者,让开发者专注于业务逻辑和UI的实现,而不必担心两者之间的直接关联。利用数据绑定(Data Binding),可以将UI组件和数据源直接绑定,这样当数据源发生变化时,UI组件会自动更新,反之亦然,这极大提高了开发效率并减少了bug的发生。

weixin_35755562的博客 1057

Windows 64 位系统下安装配置 DOSBox 及 debug.exe

该篇博客同样作为类似问题 “如何在 Windows 64 位系统下进入 debug” 的答案。 很多同学初看王爽的《汇编语言》,或者因为其它原因需要进入 debug 调试模式下学习汇编语言的时候,会发现进入不了,出现类似以下的错误提示。 这是因为他们使用的是 64 位的 Windows 系统(Win 7,Win 8 以及 Win 10 等),而 64 位 Windows 系统不再支持在命令提示符窗口下进入 debug 调试模式。那么对于使用 64 位 Windows 系统的用户来说,该怎样才能够顺利进入 d

加号减减号的博客 5万+

retrofit取消上个请求

Retrofit是一个网络请求库,它可以帮助我们简化网络请求的过程。如果要取消上一个请求,可以使用Call.cancel()方法来取消它。例如: Call<ResponseBody> call = service.getData(); call.enqueue(new Callback<ResponseBody>() { @Override public v...

weixin_35754962的博客 619

新手避坑指南:在MacBook上为PyTorch正确配置MPS环境,跑通第一个YOLOv8训练

本文详细指导新手如何在MacBook上为PyTorch正确配置MPS环境,并成功运行YOLOv8训练。从环境准备、PyTorch安装到YOLOv8配置和性能调优,提供全面的避坑指南和实用技巧,帮助开发者充分利用Mac的GPU加速能力。

weixin_29100399的博客 228

retrofit-helper-简洁的封装retrofit,优雅的取消请求,我们究竟还要学习哪些Android知识

文章会持续更新的。绝对干货!!!Android进阶学习全套手册关于实战,我想每一个做开发的都有话要说,对于小白而言,缺乏实战经验是通病,那么除了在实际工作过程当中,我们如何去更了解实战方面的内容呢?实际上,我们很有必要去看一些实战相关的电子书。

2401_83601703的博客 899

CAN总线错误帧全解析:从数据包到硬件层的故障树分析

本文深入解析CAN总线错误帧的故障树分析方法,从数据包到硬件层全面剖析错误机制。通过物理层信号测试、数据链路层错误解码和应用层协议排查,提供系统化的诊断框架。结合CANoe配置和示波器波形分析,帮助工程师快速定位总线故障,提升系统可靠性。

weixin_26742753的博客 488

信贷审批中的那些坑:从零开始搭建风控策略体系的5个关键步骤

本文深入探讨了信贷审批中的风控策略体系搭建,从数据陷阱识别、规则冲突诊断到反欺诈攻防,提供了5个关键步骤的实战指南。重点解析了如何通过特征工程、决策树优化和模型可解释性技术,构建动态平衡的风控体系,有效降低逾期风险并提升审批效率。

weixin_29253711的博客 412

retrofit-helper-简洁的封装retrofit,优雅的取消请求

initCause((Throwable) body); } //FastPrintWriter#print(String str) this.msg = msg != null ? msg : “null”; this.body = body; }/**@Override public String toString() { return “HttpError {msg=”#####2.5 ExecutorCallAdapterFactory返回Call2请求适配器处理请求接口方法返回为Call2的请求

2401_84010165的博客 964

【Bug已解决】[Bug]: ValueError: No user query found in messages QWEN 3.5 27B VLLM 0.16.0 NIGHTLY 解决方案

用 vLLM 0.16.0 nightly 给发聊天请求时,服务端在处理消息时抛ValueError,请求失败。

博客 408

Android LiveData + Retrofit 取消请求(二)

Android LiveData + Retrofit 取消请求(二) 接着继续之前,我们来看 Retrofit + RxJava 取消请求 添加RxJava2的CallAdapter private static final Retrofit RETROFIT_CLIENT = new Retrofit.Builder().baseUrl(BASE_URL). addConverterFactory(ScalarsConverterFactory.create())

K_Hello的博客 1028

RK3588 ENV 环境配置之 fw_printenv

RK3588 ENV环境配置指南 本文详细介绍了在RK3588平台上配置ENV环境变量的完整流程。首先需要在parameter分区表中划分env分区,然后在U-Boot中配置MMC偏移地址。接着编译fw_printenv工具并部署到目标设备,配置fw_env.config文件指定存储位置。重点解决了内核中读写ENV时遇到的CRC校验问题,通过U-Boot的saveenv命令初始化环境变量存储区域。最后展示了如何使用fw_printenv/fw_setenv工具在内核中读写ENV变量,并建议将配置集成到根文件

501846585_QQAndroid_java 1032

Q3D提取PCB走线RLCG参数

介绍一种提取PCB走线寄生电容和寄生电感的方法

sinat_15150363的博客 2917

Android进阶实战:网络请求、协程与Jetpack整合避坑指南

Android开发进入中高级阶段后,网络请求、协程与Jetpack架构组件往往不再是孤立的知识点,而是需要协同工作的整体方案。理解Retrofit与OkHttp的底层原理,能帮助开发者写出更稳健的数据层;协程通过挂起与恢复机制让异步逻辑回归同步思维,配合生命周期Scope可有效避免内存泄漏;ViewModel与StateFlow则解决了界面状态管理的问题。这些技术共同构成了现代Android应用的标准骨架,适用于从简单Demo向完整项目过渡的工程实践。同时,深色主题适配与沉浸式状态栏处理也是提升应用质感的重

weixin_33461476的博客 265

海思3559av100平台lan9500模块调试记录

1. 前言 通过USB2.0接口扩展一路百兆虚拟网口 2. 配置lan9500驱动 make ARCH=arm64 menuconfig 开启LAN95XX驱动,编译进内核 保存内核配置 3. 编译内核 make ARCH=arm64 CROSS_COMPILE=aarch64-himix100-linux- uImage -j 20 cd ../../arm-trusted-firmware/arm-trusted-firmware ./mk.sh cp ...

jzwjzw19900922的博客 908

主线程网络请求为何崩溃?NetworkOnMainThreadException 原理与正确姿势

在 Android 开发中,主线程负责 UI 渲染和事件分发,而网络请求属于耗时操作。当开发者直接在主线程发起网络请求时,系统会抛出 NetworkOnMainThreadException,导致应用崩溃。这一机制源于系统对主线程的严格保护——耗时操作阻塞主线程会引发 ANR(应用无响应),严重影响用户体验。从 Android 4.0 开始,主线程网络请求被硬性禁止。正确的做法是将网络请求放入子线程,通过 Handler、线程池或 Kotlin 协程切换线程,同时注意 OkHttp 异步回调的线程模型,避免

weixin_29173777的博客 222

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

LiveData+Retrofit 网络请求实战

code小生,一个专注 Android 领域的技术平台公众号回复 Android 加入我的安卓技术群作者:星星y星星y授权发表,转发等请联系原作者授权RxJava与Ret...

weixin_38754349的博客 1148

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

LiveData+Retrofit网络请求实战,三面美团Android岗

找工作是个很辛苦的事情,而且一般周期都比较长,有时候既看个人技术,也看运气。第一次找工作,最后的结果虽然不尽如人意,不过收获远比offer大。接下来就是针对自己的不足,好好努力了。最后为了节约大家的时间,我把我学习所用的资料和面试遇到的问题和答案都整理成了PDF文档,都可以分享给有需要的朋友,如有需要私信我【资料】或者**【点这里】免费领取**《Android面试复习资料汇总》,而且一般周期都比较长,有时候既看个人技术,也看运气。第一次找工作,最后的结果虽然不尽如人意,不过收获远比offer大。

2201_75604341的博客 890

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

关于Retrofit+Rxjava3+LiveData网络请求的封装

本文介绍了基于Retrofit的网络请求封装实现,主要支持日志打印、统一配置BaseUrl、请求头管理、错误统一处理等功能。通过Builder模式构建ApiRetrofit类,可配置超时时间、拦截器、请求头等参数,并支持多实例模式。文章展示了如何结合Hilt依赖注入使用该封装,以及在ViewModel中调用API服务的示例代码。该封装简化了网络请求流程,统一处理了错误码解析和权限拦截,提高了开发效率。

青穗的博客 930

retrofit content-length为0_LiveData+Retrofit 网络请求实战

code小生,一个专注 Android 领域的技术平台公众号回复 Android 加入我的安卓技术群作者:星星y链接:https://www.jianshu.com/p/34fb6ffaa684声明:本文已获星星y授权发表,转发等请联系原作者授权RxJava与Retrofit 在出现LiveData之前,Android上实现网络请求最常用的方式是使用Retrofit+Rxjava。通常是...

weixin_39688170的博客 185

初始化请求例子_LiveData+Retrofit网络请求实战

View点击上方蓝字关注?来源:星星yhttps://www.jianshu.com/p/34fb6ffaa684RxJava与Retrofit在出现LiveData之前,Android上实现网络请求最常用的方式是使用Retrofit+Rxjava。通常是RxJavaCallAdapterFactory将请求转成Observable(或者Flowable等)被观察者对象,调用时通过su...

weixin_28883533的博客 299

retrofit content-length为0_LiveData+Retrofit网络请求实战

View点击上方蓝字关注?来源:星星yhttps://www.jianshu.com/p/34fb6ffaa684RxJava与Retrofit在出现LiveData之前,Android上实现网络请求最常用的方式是使用Retrofit+Rxjava。通常是RxJavaCallAdapterFactory将请求转成Observable(或者Flowable等)被观察者对象,调用时通过su...

weixin_39675963的博客 115
上一篇: 软硬件操作示例文案样板
下一篇: Android LiveData + Retrofit 取消请求(二)
K_Hello
博客等级 码龄12年 33粉丝 115原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值