改造2 OkHttpClient缓存无法正常工作

时间:2017-08-27 10:40:13

标签: android caching retrofit2 okhttp3 okhttp

所以这就是问题所在,我正在尝试为我的应用程序实现缓存,并按照本教程Android: Cache network requests for offline access with Retrofit2 and 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();

Farmaan Elahis的回答适用于loadHomeNotLoggedPosts,但不适用于loadHomeLoggedPosts。任何帮助都非常感谢。谢谢!

Okhttp日志:由于日志太大而无法完全发布,我已经删除了部分内容。

拳头启动:

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!

2 个答案:

答案 0 :(得分:2)

您可以使用以下代码构建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 );
                } 
            }; 
        }

答案 1 :(得分:0)

POST调用不会在Retrofit中缓存。它在文档中