在我尝试显示结果后启动改造 API 调用

Posted

技术标签:

【中文标题】在我尝试显示结果后启动改造 API 调用【英文标题】:The retrofit API call is initiated after i try to display the results 【发布时间】:2019-11-21 14:05:15 【问题描述】:

我正在使用 MVVM 架构,我有我的模型类“Category”和我的 ViewModel 类以及 Recyclerview 的 MainActivity 和 Adapter, 如果我在活动中设置适配器(在改造调用的 onResponse 方法中),一切都可以正常工作,但如果我这样做,我不尊重 MVVM 架构的分离, 这是用于执行调用的方法:

 public List<Category> getcategories() 

    RestInterface restInterface = rest.getInterfaceService();
    Call<List<Category>> productService = restInterface.getCategories();
    productService.enqueue(new Callback<List<Category>>() 
        @Override
        public void onResponse(Call<List<Category>> call, Response<List<Category>> response) 
            if (response.body() == null)
                Log.e(TAG, "responce Call response is null ");
            else
                Log.e(TAG, "repo : "+response.body().toString());
                categories = (ArrayList<Category>) response.body();

            
        

        @Override
        public void onFailure(Call<List<Category>> call, Throwable t) 
            Log.e(TAG, "Call Fail  : " + t.getMessage());
        
    );
    Log.e(TAG, "repo 2: "+categories.toString());
    return categories;

这里是 logcat 结果:

07-11 20:18:34.325 24369-24369/com.instadom E/DataRepository: repo 2: []

07-11 20:18:35.399 24369-24369/com.instadom E/DataRepository: repo : [exemple.com.models.Category@1df175e, exemple.com.models.Category@5cfc73f, exemple.com.models .Category@1e7380c, exemple.com.models.Category@7ceb555, exemple.com.models.Category@3014b6a, exemple.com.models.Category@a83985b, exemple.com.models.Category@3d5c8f8, exemple.com.models .Category@d1251d1]

我无法理解的是为什么我在“Log.e(TAG,”repo 2:“+categories.toString());”中没有得到任何结果即使“类别”也是一个类对象

我会感谢任何帮助, 提前致谢,


代码如下:

公共列表获取类别(最终回调> 打回来) RestInterface restInterface = rest.getInterfaceService(); 调用> productService = restInterface.getCategories(); productService.enqueue(new retrofit2.Callback>() @覆盖 公共无效onResponse(呼叫>呼叫,响应>响应) if (response.body() == null) Log.e(TAG, "responce 调用响应为空"); 别的 Log.e(TAG, "repo : "+response.body().toString()); 类别 = (ArrayList) response.body(); 回调.onSuccess(类别);

        @Override
        public void onFailure(Call<List<Category>> call, Throwable t) 
            Log.e(TAG, "Call Fail  : " + t.getMessage());
            callback.onFailure(t.getMessage());
        
    );
    Log.e(TAG, "result : "+categories.toString());
    return categories;

public interface Callback<T> 
    void onSuccess(ArrayList<Category> data);
    void onFailure(String reason);

这是错误:

java.lang.NullPointerException:尝试在空对象引用上调用接口方法“void instadom.com.repositories.DataRepository$Callback.onSuccess(java.util.ArrayList)”

【问题讨论】:

这不是一个asyc调用,而后者Log是在onResponse之前被调用的吗?我认为您可以与听众一起解决这个问题 您应该使用 LiveData 或 RxJava 在从 Web API 收到数据时在 Activity 中获得通知 【参考方案1】:

那是因为productService.enqueue是一个异步调用,语句Log.e(TAG, "repo 2: "+categories.toString());将在调用入队后立即执行,onResponseonFailure将在网络调用后执行。将回调传递给getCategories() 以获取这样的类别列表

public interface Callback<List<Categories>> callback
   void onSuccess(List<Categories> data);
   void onFailure(String reason);

或者您可以使用通用回调接口在您的所有网络请求中使用这样的

public interface Callback<T> callback
   void onSuccess(List<T> data);
   void onFailure(String reason);

然后实现回调功能

public List<Category> getcategories(Callback<List<Category>> callback) 

    RestInterface restInterface = rest.getInterfaceService();
    Call<List<Category>> productService = restInterface.getCategories();
    productService.enqueue(new Callback<List<Category>>() 
        @Override
        public void onResponse(Call<List<Category>> call, Response<List<Category>> response) 
            if (response.body() == null)
                Log.e(TAG, "responce Call response is null ");
            else
                Log.e(TAG, "repo : "+response.body().toString());
                categories = (ArrayList<Category>) response.body();
                callback.onSuccess(categories);

            
        

        @Override
        public void onFailure(Call<List<Category>> call, Throwable t) 
            Log.e(TAG, "Call Fail  : " + t.getMessage());
            callback.onError(t.getMessage());
        
    );

【讨论】:

非常感谢您的回答,但这似乎并不正确,

以上是关于在我尝试显示结果后启动改造 API 调用的主要内容,如果未能解决你的问题,请参考以下文章

改造 API 调用返回 null

如何使用 ViewModel 和 LiveData 进行改造 API 调用

使用 MockWebServer 模拟嵌套的改造 api 调用

使用 MockWebServer 模拟嵌套的改造 api 调用

如何使用改造 Android 调用具有动态参数的 api?

如何从响应改造中检索 cookie,okhttp?