Retrofit 2 OkHttpClient кэширование не работает

Итак, вот в чем проблема, я пытаюсь реализовать кэширование для своего приложения, и я следовал этому руководству по Android: кешировать сетевые запросы на автономный доступ с помощью Retrofit2 и OkHTTP3, чтобы сделать это. К сожалению, кэшированные ответы не отображаются, когда нет подключения к Интернету, вместо этого

Toast.makeText(getContext(), getContext(). GetResources(). GetString(R.string.error_failed_to_load_posts), Toast.LENGTH_SHORT).show();

исполняется. Так может кто-нибудь сказать мне, что я делаю не так? Или направить меня, чтобы получить ответ на эту проблему? Я опубликую дополнительную информацию, если потребуется, если вы спросите меня. Ниже приведен весь код конкретной функции.

private void loadHomeLoggedPosts(String uid) {
    progressBar.setVisibility(View.VISIBLE);

    OkHttpClient client = new OkHttpClient
            .Builder()
            .cache(new Cache(getContext().getCacheDir(), 10 * 1024 * 1024)) // 10 MB
            .addInterceptor(new Interceptor() {
                @Override public okhttp3.Response intercept(Chain chain) throws IOException {
                    Request request = chain.request();
                    if (Utils.isNetworkAvailable(getContext())) {
                        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();

    Gson gson = new GsonBuilder()
            .setLenient()
            .create();

    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(getResources().getString(R.string.app_base_url))
            .client(client)
            .addConverterFactory(GsonConverterFactory.create(gson))
            .build();

    RequestInterface request = retrofit.create(RequestInterface.class);
    Call<Classes> call = request.homeLoggedPosts(uid);
    call.enqueue(new Callback<Classes>() {
        @Override
        public void onResponse(Call<Classes> call, Response<Classes> response) {
            Classes jsonResponse = response.body();
            if (jsonResponse!=null) {
                homePosts = jsonResponse.getHomePosts();
                homeLoggedInAdapter = new HomeLoggedInAdapter(homePosts);
                recyclerView.setAdapter(homeLoggedInAdapter);
                homeLoggedInAdapter.notifyDataSetChanged();
            }
            else {
                Toast.makeText(getContext(), getContext().getResources().getString(R.string.error_failed_to_load_posts), Toast.LENGTH_SHORT).show();
            }
            progressBar.setVisibility(View.INVISIBLE);
        }

        @Override
        public void onFailure(Call<Classes> call, Throwable t) {
            progressBar.setVisibility(View.INVISIBLE);
            Toast.makeText(getContext(), getContext().getResources().getString(R.string.error_failed_to_load_posts), Toast.LENGTH_SHORT).show();
            Log.d("ERROR", t.getMessage());
        }
    });
}

РЕДАКТИРОВАТЬ: У меня есть две функции в одном фрагменте, вызывающий следующим образом:

if (FirebaseAuth.getInstance().getCurrentUser()!=null) {
        loadHomeLoggedPosts(FirebaseAuth.getInstance().getCurrentUser().getUid());
    }
    else {
        loadHomeNotLoggedPosts();
    }

Я разместил код для loadHomeLoggedPosts выше. loadHomeNotLoggedPosts - то же самое с разницей, являющейся только этим разделом:

RequestInterface request = retrofit.create(RequestInterface.class);
Call<Classes> call = request.homeNotLoggedPosts();

Ответ Фармаана Элахиса работает для loadHomeNotLoggedPosts, но не для loadHomeLoggedPosts. Любая помощь высоко ценится. Спасибо!

Журнал Okhttp: я отредактировал некоторые части, поскольку журнал был слишком большим, чтобы публиковать здесь полностью.

Fist Startup:

08-27 18:35:29.426 32673-32673/com.appsoflife.microstories I/System.out: Cache CREATED!
08-27 18:35:29.452 32673-2498/com.appsoflife.microstories D/OkHttp: --> POST http://my_web_site.com/jacob/micro_stories/queries/home_logged.php http/1.1
08-27 18:35:29.452 32673-2498/com.appsoflife.microstories D/OkHttp: Content-Type: application/x-www-form-urlencoded
08-27 18:35:29.452 32673-2498/com.appsoflife.microstories D/OkHttp: Content-Length: 32
08-27 18:35:29.452 32673-2498/com.appsoflife.microstories D/OkHttp: uid=MY_USER_ID
08-27 18:35:29.452 32673-2498/com.appsoflife.microstories D/OkHttp: --> END POST (32-byte body)
08-27 18:35:29.460 32673-2363/com.appsoflife.microstories D/AppTracker: App Event: start
08-27 18:35:29.502 32673-32673/com.appsoflife.microstories E/RecyclerView: No adapter attached; skipping layout
08-27 18:35:29.592 32673-32679/com.appsoflife.microstories I/art: Do partial code cache collection, code=27KB, data=30KB
08-27 18:35:29.593 32673-32679/com.appsoflife.microstories I/art: After code cache collection, code=26KB, data=29KB
08-27 18:35:29.593 32673-32679/com.appsoflife.microstories I/art: Increasing code cache capacity to 128KB
08-27 18:35:29.614 32673-32673/com.appsoflife.microstories W/PropertyValuesHolder: Method set() with type float not found on target class class me.zhanghai.android.materialprogressbar.IndeterminateHorizontalProgressDrawable$RectTransformX
08-27 18:35:33.088 32673-2498/com.appsoflife.microstories D/OkHttp: <-- 200 OK http://my_web_site.com/jacob/micro_stories/queries/home_logged.php (3634ms)
08-27 18:35:33.088 32673-2498/com.appsoflife.microstories D/OkHttp: Date: Sun, 27 Aug 2017 13:05:29 GMT
08-27 18:35:33.088 32673-2498/com.appsoflife.microstories D/OkHttp: Server: Apache/2.4.25
08-27 18:35:33.088 32673-2498/com.appsoflife.microstories D/OkHttp: X-Powered-By: PHP/5.6.30
08-27 18:35:33.088 32673-2498/com.appsoflife.microstories D/OkHttp: Vary: Accept-Encoding,User-Agent
08-27 18:35:33.088 32673-2498/com.appsoflife.microstories D/OkHttp: Keep-Alive: timeout=5
08-27 18:35:33.088 32673-2498/com.appsoflife.microstories D/OkHttp: Connection: Keep-Alive
08-27 18:35:33.088 32673-2498/com.appsoflife.microstories D/OkHttp: Transfer-Encoding: chunked
08-27 18:35:33.088 32673-2498/com.appsoflife.microstories D/OkHttp: Content-Type: text/html; charset=UTF-8
08-27 18:35:33.088 32673-2498/com.appsoflife.microstories D/OkHttp: Cache-Control: max-age=120
08-27 18:35:37.890 32673-2653/com.appsoflife.microstories I/FirebaseCrash: Sending crashes
08-27 18:35:41.664 32673-32695/com.appsoflife.microstories W/art: Suspending all threads took: 9.530ms
08-27 18:35:41.681 32673-2498/com.appsoflife.microstories D/OkHttp: 

MY_JSON_OUTPUT_TOO_LONG_TO_POST

08-27 18:35:41.721 32673-2498/com.appsoflife.microstories D/OkHttp: <-- END HTTP (3297402-byte body)

ВТОРОЙ РАЗ:

08-27 18:37:35.904 5089-5089/com.appsoflife.microstories I/System.out: Cache CREATED!
08-27 18:37:35.922 5089-5190/com.appsoflife.microstories D/OkHttp: --> POST http://my_web_site.com/jacob/micro_stories/queries/home_logged.php http/1.1
08-27 18:37:35.922 5089-5190/com.appsoflife.microstories D/OkHttp: Content-Type: application/x-www-form-urlencoded
08-27 18:37:35.922 5089-5190/com.appsoflife.microstories D/OkHttp: Content-Length: 32
08-27 18:37:35.922 5089-5190/com.appsoflife.microstories D/OkHttp: uid=MY_USER_ID
08-27 18:37:35.922 5089-5190/com.appsoflife.microstories D/OkHttp: --> END POST (32-byte body)
08-27 18:37:35.934 5089-5135/com.appsoflife.microstories D/AppTracker: App Event: start
08-27 18:37:35.979 5089-5089/com.appsoflife.microstories E/RecyclerView: No adapter attached; skipping layout
08-27 18:37:36.058 5089-5094/com.appsoflife.microstories I/art: Do partial code cache collection, code=26KB, data=30KB
08-27 18:37:36.058 5089-5094/com.appsoflife.microstories I/art: After code cache collection, code=25KB, data=29KB
08-27 18:37:36.058 5089-5094/com.appsoflife.microstories I/art: Increasing code cache capacity to 128KB
08-27 18:37:36.083 5089-5089/com.appsoflife.microstories W/PropertyValuesHolder: Method set() with type float not found on target class class me.zhanghai.android.materialprogressbar.IndeterminateHorizontalProgressDrawable$RectTransformX
08-27 18:37:39.860 5089-5190/com.appsoflife.microstories D/OkHttp: <-- 200 OK http://my_web_site.com/jacob/micro_stories/queries/home_logged.php (3937ms)
08-27 18:37:39.860 5089-5190/com.appsoflife.microstories D/OkHttp: Date: Sun, 27 Aug 2017 13:07:36 GMT
08-27 18:37:39.860 5089-5190/com.appsoflife.microstories D/OkHttp: Server: Apache/2.4.25
08-27 18:37:39.860 5089-5190/com.appsoflife.microstories D/OkHttp: X-Powered-By: PHP/5.6.30
08-27 18:37:39.860 5089-5190/com.appsoflife.microstories D/OkHttp: Vary: Accept-Encoding,User-Agent
08-27 18:37:39.860 5089-5190/com.appsoflife.microstories D/OkHttp: Keep-Alive: timeout=5
08-27 18:37:39.860 5089-5190/com.appsoflife.microstories D/OkHttp: Connection: Keep-Alive
08-27 18:37:39.860 5089-5190/com.appsoflife.microstories D/OkHttp: Transfer-Encoding: chunked
08-27 18:37:39.860 5089-5190/com.appsoflife.microstories D/OkHttp: Content-Type: text/html; charset=UTF-8
08-27 18:37:39.860 5089-5190/com.appsoflife.microstories D/OkHttp: Cache-Control: max-age=120
08-27 18:37:49.883 5089-5426/com.appsoflife.microstories I/FirebaseCrash: Sending crashes
08-27 18:37:51.044 5089-5190/com.appsoflife.microstories D/OkHttp: 

JSON_OUTPUT_TOO_LONG_TO_POST

read: unexpected EOF!

1 ответ

Вы можете использовать приведенный ниже код для создания своего okhttp-клиента, который может иметь как онлайн-кеш, который действителен в течение 2 минут, так и автономный кеш, который действителен в течение 7 дней.

PS: Вам нужно подумать об открытии приложения в первый раз с подключенным к Интернету шоу, которое не вызывает исключений

  private static OkHttpClient provideOkHttpClient () 
        { 
            return new OkHttpClient.Builder() 
                    .addInterceptor( provideOfflineCacheInterceptor() ) 
                    .addNetworkInterceptor( provideCacheInterceptor() ) 
                    .cache( provideCache() ) 
                    .build(); 
        } 

        private static Cache provideCache ()
        { 
            Cache cache = null;
            try 
            { 
                cache = new Cache( new File( getApplicationContext().getInstance().getCacheDir(), "http-cache" ),
                        10 * 1024 * 1024 ); // 10 MB 
            } 
            catch (Exception e)
            { 
                Timber.e( e, "Could not create Cache!" );
            } 
            return cache;
        } 

        public static Interceptor provideCacheInterceptor () 
        { 
            return new Interceptor() 
            { 
                @Override 
                public Response intercept (Chain chain) throws IOException
                { 
                    Response response = chain.proceed( chain.request() );

                    // re-write response header to force use of cache 
                    CacheControl cacheControl = new CacheControl.Builder()
                            .maxAge( 2, TimeUnit.MINUTES )
                            .build(); 

                    return response.newBuilder()
                            .header( CACHE_CONTROL, cacheControl.toString() )
                            .build(); 
                } 
            }; 
        } 

        public static Interceptor provideOfflineCacheInterceptor () 
        { 
            return new Interceptor() 
            { 
                @Override 
                public Response intercept (Chain chain) throws IOException
                { 
                    Request request = chain.request();

                    if ( !AndroidUtils.isNetworkAvailable() ) 
                    { 
                        CacheControl cacheControl = new CacheControl.Builder()
                                .maxStale( 7, TimeUnit.DAYS )
                                .build(); 

                        request = request.newBuilder() 
                                .cacheControl( cacheControl )
                                .build(); 
                    } 

                    return chain.proceed( request );
                } 
            }; 
        }

Вызовы POST не кэшируются в Retrofit. Это в документации

Другие вопросы по тегам