Issue
I'm trying to cache my data from API using oKhttp and save this data into FILE. The problem is when I'm trying to use applicationContext.cacheDir
, in my NetworkLayer class but it gives me an error.
I have tried to make my NetworkLayer extends from Application() but the problem is still.
I also tried to make some search about this problem but I didn't find anything that related. Thanks In advance.
Here's my code
NetworkLayer
class NetworkLayer : Application() {
private val BASE_URL = ""
private val moshi: Moshi = Moshi.Builder().addLast(KotlinJsonAdapterFactory()).build()
private fun myHttpClient(): OkHttpClient {
val interceptor = HttpLoggingInterceptor()
interceptor.level = HttpLoggingInterceptor.Level.BODY
val httpCacheDirectory = File(applicationContext.cacheDir, "http-cache")
val cacheSize = 10 * 1024 * 1024 // 10 MiB
val cache = Cache(httpCacheDirectory, cacheSize.toLong())
val builder = OkHttpClient()
.newBuilder()
.addNetworkInterceptor(CacheInterceptor())
.cache(cache)
.addInterceptor(interceptor)
.callTimeout(3, TimeUnit.SECONDS)
.connectTimeout(3, TimeUnit.SECONDS)
return builder.build()
}
private val retrofit: Retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.client(myHttpClient())
.addConverterFactory(MoshiConverterFactory.create(moshi))
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build()
val apiService: APIService by lazy {
retrofit.create(APIService::class.java)
}
}
The problem is here, at this code line
val httpCacheDirectory = File(applicationContext.cacheDir, "http-cache")
My CacheInterceptor Class
class CacheInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val response: Response = chain.proceed(chain.request())
val cacheControl = CacheControl.Builder()
.maxAge(1, TimeUnit.DAYS)
.build()
return response.newBuilder()
.removeHeader("Pragma")
.removeHeader("Cache-Control")
.header("Cache-Control", cacheControl.toString())
.build()
}
}
The Error message
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.moataz.afternoonhadeeth/com.moataz.afternoonhadeeth.ui.view.activity.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.content.Context.getApplicationContext()' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3430)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3614)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:86)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2199)
at android.os.Handler.dispatchMessage(Handler.java:112)
at android.os.Looper.loop(Looper.java:216)
at android.app.ActivityThread.main(ActivityThread.java:7625)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.content.Context.getApplicationContext()' on a null object reference
at android.content.ContextWrapper.getApplicationContext(ContextWrapper.java:116)
at com.moataz.afternoonhadeeth.data.request.NetworkLayer.myHttpClient(NetworkLayer.kt:26)
at com.moataz.afternoonhadeeth.data.request.NetworkLayer.<init>(NetworkLayer.kt:42)
at com.moataz.afternoonhadeeth.data.repository.ApiClient.<init>(ApiClient.kt:12)
at com.moataz.afternoonhadeeth.ui.viewmodel.HomeViewModel.<init>(HomeViewModel.kt:16)
at com.moataz.afternoonhadeeth.ui.view.fragment.HomeFragment.<init>(HomeFragment.kt:25)
at com.moataz.afternoonhadeeth.ui.view.activity.MainActivity.initializeBottomNavigation(MainActivity.kt:71)
at com.moataz.afternoonhadeeth.ui.view.activity.MainActivity.onCreate(MainActivity.kt:46)
at android.app.Activity.performCreate(Activity.java:7458)
at android.app.Activity.performCreate(Activity.java:7448)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1286)
Edit: Here's the final code
class NetworkLayer : AppCompatActivity() {
private val BASE_URL = ""
private val moshi: Moshi = Moshi.Builder().addLast(KotlinJsonAdapterFactory()).build()
private val myHttpClient = OkHttpClient()
override fun onCreate(savedInstanceState: Bundle?, persistentState: PersistableBundle?) {
super.onCreate(savedInstanceState, persistentState)
val interceptor = HttpLoggingInterceptor()
interceptor.level = HttpLoggingInterceptor.Level.BODY
val httpCacheDirectory = File(applicationContext.cacheDir, "http-cache")
val cacheSize = 10 * 1024 * 1024 // 10 MiB
val cache = Cache(httpCacheDirectory, cacheSize.toLong())
myHttpClient
.newBuilder()
.addNetworkInterceptor(CacheInterceptor())
.addInterceptor(ForceCacheInterceptor())
.cache(cache)
.callTimeout(3, TimeUnit.SECONDS)
.connectTimeout(3, TimeUnit.SECONDS)
.build()
}
private val retrofit: Retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.client(myHttpClient)
.addConverterFactory(MoshiConverterFactory.create(moshi))
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build()
val apiService: APIService by lazy {
retrofit.create(APIService::class.java)
}
}
Solution
applicationContext.cacheDir
must call after onCreate()
in Application
class.
In your code myHttpClient()
is calling before onCreate()
so applicationContext
is null
.
To solve this problem you can create retrofit
in Application onCreate()
Answered By - A Sarshar
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.