You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Retrofit中SingleObserver的onSubscribe方法始终返回null求助

Retrofit + RxJava: SingleObserver's onSubscribe Receives Null Disposable

Let's break down your issue and figure out why you're seeing a null value related to onSubscribe with your SingleObserver. First, let's recap your code context to make sure we're on the same page:

Your Code Snippets

Interface definition:

@GET(ApiAddress.LANGUAGE_ALL)
Single<Response<Language>> languageAll();

Subscription implementation:

apiRepository.languageAll()
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(new SubscribeWithView<Response<Language>>(view) {
        @Override
        public void onSuccess(Response<Language> response) {
            if (response.isSuccess()) {
                view.setLanguage(response.getData().getResults());
            }
        }
        // Code incomplete (missing onError implementation)
    });

Key Observations & Troubleshooting Steps

First, a quick clarification: onSubscribe is a void method—it doesn't return anything. I suspect you're actually seeing that the Disposable parameter passed to onSubscribe is null, or your custom SubscribeWithView class is mishandling this parameter. Here are the most likely fixes:


1. Fix Your Custom SubscribeWithView Implementation

The problem almost certainly lies in how your SubscribeWithView abstract class is implemented. Since it's a custom wrapper around SingleObserver, you need to ensure it properly forwards the Disposable parameter from onSubscribe.

Here's a correct implementation template for your SubscribeWithView:

public abstract class SubscribeWithView<T> implements SingleObserver<T> {
    protected final View view;
    private Disposable disposable;

    public SubscribeWithView(View view) {
        this.view = view;
    }

    @Override
    public void onSubscribe(Disposable d) {
        // Save the disposable so you can cancel requests later (e.g., on view destroy)
        this.disposable = d;
        
        // Optional: Bind disposable to view lifecycle to prevent memory leaks
        if (view instanceof LifecycleOwner) {
            ((LifecycleOwner) view).getLifecycle().addObserver((LifecycleOwner source, Lifecycle.Event event) -> {
                if (event == Lifecycle.Event.ON_DESTROY && disposable != null && !disposable.isDisposed()) {
                    disposable.dispose();
                }
            });
        }
    }

    @Override
    public void onError(Throwable e) {
        // Add generic error handling here (e.g., show toast, log error)
        Log.e("SubscribeWithView", "Request failed", e);
        // You can also add an abstract method to let subclasses handle errors if needed
    }

    // Let subclasses implement success handling
    protected abstract void onSuccess(T response);

    @Override
    public void onSuccess(T t) {
        // Forward the success callback to your subclass implementation
        onSuccess(t);
    }
}

If your existing SubscribeWithView wasn't properly storing or forwarding the Disposable, that's why you're seeing null.


2. Verify Dependency Version Compatibility

Mismatched versions of Retrofit, RxJava, and RxAndroid can cause unexpected behavior like null disposables. Ensure your build.gradle (Module level) has compatible versions:

// RxJava 2.x (match versions as closely as possible)
implementation 'io.reactivex.rxjava2:rxjava:2.2.21'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
// Retrofit with RxJava 2 adapter
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.9.0'

Avoid mixing RxJava 1.x and 2.x dependencies—this is a common source of bugs.


3. Test with a Default SingleObserver

To isolate the issue, temporarily replace your custom SubscribeWithView with a vanilla SingleObserver and log the disposable:

apiRepository.languageAll()
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(new SingleObserver<Response<Language>>() {
        @Override
        public void onSubscribe(Disposable d) {
            Log.d("TEST", "Disposable received: " + d);
            // If this logs a non-null value, the problem is definitely in your SubscribeWithView
        }

        @Override
        public void onSuccess(Response<Language> response) {
            if (response.isSuccess()) {
                view.setLanguage(response.getData().getResults());
            }
        }

        @Override
        public void onError(Throwable e) {
            Log.e("TEST", "Request error", e);
        }
    });

If this test shows a valid Disposable, go back to fixing your SubscribeWithView implementation. If it still shows null, check if your apiRepository.languageAll() is returning a properly initialized Single (e.g., no errors in Retrofit setup).


Final Notes

Don't forget to implement the onError method in your subscriber—unhandled errors can crash your app or lead to silent failures.

内容的提问来源于stack exchange,提问作者tohidmahmoudvand

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 03:54:10