1

I want to use cache in retrofit, but I get an error because of getCacheDir();

This is my code:

public class ServiceGenerator extends AppCompatActivity {

    public static final String API_BASE_URL = "https://myapiurl.com/";

    private static HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
    private static Interceptor logging = interceptor.setLevel(HttpLoggingInterceptor.Level.BASIC);

    static File dir = getCacheDir();
    static Cache cache = new Cache(dir,10*1024*1024);
    private static OkHttpClient httpClient = new OkHttpClient.Builder()
            .cache(cache)
            .addInterceptor(logging)
            .build();

    private static Gson gson = new GsonBuilder()
            .setLenient()
            .create();
    private static Retrofit.Builder builder =
            new Retrofit.Builder()
                    .baseUrl(API_BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create(gson));

    public static <S> S createService(Class<S> serviceClass) {
        Retrofit retrofit = builder.client(httpClient).build();
        return retrofit.create(serviceClass);
    }


}

The error is "Non-static method 'getCacheDir()' cannot be referenced from a static context"

So I deleted all static variables and I get another error about createService() that it couldn't be non-static.

How can I fix this problem?

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Daniel
  • 108
  • 17
  • Why is everything static? – Sandrogo Feb 10 '19 at 12:03
  • @Sandrogo I don't know. i just copied it from a tutorial! – Daniel Feb 10 '19 at 12:04
  • Static variables should be avoided as much as possible since they can cause memory leaks. Please provide a link to the tutorial you followed, so we have a chance of understanding what you tried to do. – Sandrogo Feb 10 '19 at 12:09
  • @Sandrogo this is the retrofit tutorial :https://github.com/danbuckland/android-retrofit-example and caching tutorial : https://futurestud.io/tutorials/retrofit-2-activate-response-caching-etag-last-modified – Daniel Feb 10 '19 at 12:13
  • That is a very old tutorial and looks like not a popular one. Please check this: https://medium.com/mindorks/caching-with-retrofit-store-responses-offline-71439ed32fda – Housefly Feb 10 '19 at 12:16
  • @Housefly i checked that too. it was in kotlin and it wasn't a complete guide of retrofit. – Daniel Feb 10 '19 at 12:22
  • Possible duplicate of ["Non-static method cannot be referenced from a static context" error](https://stackoverflow.com/questions/4922145/non-static-method-cannot-be-referenced-from-a-static-context-error) – MML Feb 12 '19 at 14:55

2 Answers2

0

getCacheDir() isn't a static method, so it can't be called by static field/method. First you must create ServiceGenerator instance. I recommend you to make all fields and methods as regular (non-static) and call them/assign them in ServiceGenerator onCreate callback.

public class ServiceGenerator extends AppCompatActivity {

    private static final String API_BASE_URL = "https://myapiurl.com/";

    private Retrofit retrofit;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BASIC);
        Cache cache = new Cache(getCacheDir(), 10 * 1024 * 1024);
        Gson gson = new GsonBuilder()
                .setLenient()
                .create();
        OkHttpClient httpClient = new OkHttpClient.Builder()
                .cache(cache)
                .addInterceptor(loggingInterceptor)
                .build();
        retrofit = new Retrofit.Builder()
                .baseUrl(API_BASE_URL)
                .client(httpClient)
                .addConverterFactory(GsonConverterFactory.create(gson))
                .build();
    }

    protected <S> S createService(Class<S> serviceClass) {
        return retrofit.create(serviceClass);
    }
}

Every activity which gonna extend ServiceGenerator would create a service.

jczerski
  • 265
  • 2
  • 13
  • could you explain more please? i'm new to android :/ – Daniel Feb 10 '19 at 12:22
  • Thancks for your help but i got this error when i used your code : error: non-static method createService(Class) cannot be referenced from a static context where S is a type-variable: S extends Object declared in method createService(Class) – Daniel Feb 10 '19 at 16:00
  • Where do you want use your service? In activity? Fragment? Service? – jczerski Feb 10 '19 at 21:22
  • I use it in several activities – Daniel Feb 11 '19 at 05:51
  • public class TestActivity extends ServiceGenerator { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); final SomeService service = createService(SomeService.class); } } – jczerski Feb 11 '19 at 09:52
0

After a lot of search i found out the answer is in Context

 public static <S> S createService(Class<S> serviceClass,Context mContext) {
     File dir = new File(mContext.getCacheDir(),"http-cache");
     ...
 }
Daniel
  • 108
  • 17