简体   繁体   English

如果缓存为空NPE,则进行改造

[英]Retrofit if cache empty NPE

I add the possibility of caching and the following script happens: Everything works if the pages have been previously uploaded, but if I go without the Internet for the first time then the application crashes and throws an error 我添加了缓存的可能性,并且发生以下脚本:如果页面先前已上传,那么一切正常,但是如果我第一次没有互联网,则应用程序崩溃并引发错误

NullPointerException: Attempt to invoke interface method 'java.lang.Object[] java.util.Collection.toArray()' on a null object reference
    at java.util.ArrayList.<init>(ArrayList.java:171)
    at n.MainDetailTrainFragment$3.onResponse(MainDetailTrainFragment.java:171)

I understand the error, but how can I fix it? 我了解此错误,但如何解决?

do not judge strictly, I'm just learning this. 不要严格判断,我只是在学习这一点。 here is my code^ 这是我的代码^

progressBarTrain.setVisibility(View.VISIBLE);
    Log.d(TAG, "getProducts");

   final OkHttpClient client = new OkHttpClient
           .Builder()
           .cache(new Cache(getActivity().getCacheDir(), 10 * 1024 * 1024)) // 10 MB
           .addInterceptor(new Interceptor() {
               @Override public okhttp3.Response intercept(@NonNull Chain chain) throws IOException {
                   Request request = chain.request();
                   if (NetworkUtils.isNetworkAvailable(getActivity())) {
                       request = request.newBuilder().header("Cache-Control", "public, max-age=" + 60).build();
                   } else {
                       request = request.newBuilder().header("Cache-Control", "public, only-if-cached, max-stale=" + 60 * 60 * 24 * 7).build();
                   }
                   return chain.proceed(request);
               }
           })
           .build();

    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(MY_URL)
            .client(client)
            .addConverterFactory(SimpleXmlConverterFactory.create())
            .build();

    retrofit.create(myTrainInterface.class)
            .getProducts(APP_ID, FROM_CITY, position_0, "everyday")
            .enqueue(new Callback<Responce>() {
                @SuppressLint("SetTextI18n")
                @Override
                public void onResponse(@NonNull Call<Responce> call, @NonNull Response<Responce> response) {
                    progressBarTrain.setVisibility(View.INVISIBLE);
                    if (response.body() != null) {
                        kk = response.body().products;
                    }
                    ArrayList<Responce.Item> p = new ArrayList<>(kk);
                    String s = String.valueOf(response.body());




                    adapter = new DetailTrainAdapter(p);
                    recyclerView.setAdapter(adapter);
                    Log.d(TAG, s);

                    textError.setVisibility(TextView.INVISIBLE);
                    textErrorRestart.setVisibility(TextView.INVISIBLE);
                }

                @Override
                public void onFailure(@NonNull Call<Responce> call, @NonNull Throwable throwable) {
                    Log.d(TAG, "onFailure" + throwable.getLocalizedMessage());
                    textError();
                }
            });

The NPE is thrown when variable kk is null . 当变量kknull时,将引发NPE。 Looking at your code, you're creating a list out of your response (if not null ) and then using it to populate your UI. 查看您的代码,您将从响应中创建一个列表(如果不是null ),然后使用它来填充您的UI。 However, if the response is null you're not doing assigning anything to kk , so it stays with its previous values (most probably null , given the NPE). 但是,如果响应为null ,则您不打算为kk分配任何内容,因此它保持其先前的值(考虑到NPE,很可能为null )。

A possible solution to avoid that is to execute all the logic of creating the adapter and setting it to your UI component only if response.body() != null , otherwise you might want to do something else (eg, display an error). 避免这种情况的可能解决方案是仅在response.body() != null执行创建适配器并将其设置为UI组件的所有逻辑 ,否则您可能想要做其他事情(例如,显示错误)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM