Issue
In it's onStart
method the fragment calls the presenter to fetch weather data.
The presenter starts an AsyncTask
which fetches the data, returns it to the presenter and gets displayed in the fragment.
The problem is, if I open the fragment(and fetch data), switch to another activity and then return to the fragment I get the following error:
Caused by: java.lang.IllegalStateException: Cannot execute task: the task has already been executed (a task can be executed only once)
at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:605)
at android.os.AsyncTask.execute(AsyncTask.java:560)
at com.dev.weather.forecast.ForecastPresenter.fetchWeather(ForecastPresenter.kt:20)
at com.dev.weather.forecast.ForecastFragment.refreshWeather(ForecastFragment.kt:83)
at com.dev.weather.forecast.ForecastFragment.onStart(ForecastFragment.kt:105)
at android.support.v4.app.Fragment.performStart(Fragment.java:2287)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1458)
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1750)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1819)
at android.support.v4.app.FragmentManagerImpl.dispatchStateChange(FragmentManager.java:3227)
at android.support.v4.app.FragmentManagerImpl.dispatchStart(FragmentManager.java:3186)
at android.support.v4.app.FragmentController.dispatchStart(FragmentController.java:203)
at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:582)
at android.support.v7.app.AppCompatActivity.onStart(AppCompatActivity.java:177)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1256)
at android.app.Activity.performStart(Activity.java:6959)
at android.app.Activity.performRestart(Activity.java:7075)
at android.app.Activity.performResume(Activity.java:7080)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3768)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3832)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1681)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6682)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)
I didn't have this problem before switching to dagger but now that dagger only creates one instance of the AsyncTask
I don't know how to fix it.
I hope somebody can help me!
Fragment:
@ActivityScoped
class ForecastFragment @Inject constructor(): DaggerFragment(), ForecastContract.View {
@Inject
lateinit var presenter: ForecastContract.Presenter
override fun refreshWeather() {
...
presenter.fetchWeather(location, unitType)
}
override fun onStart() {
super.onStart()
refreshWeather()
}
}
Presenter:
@ActivityScoped
class ForecastPresenter @Inject constructor() : ForecastContract.Presenter, FetchWeatherTask.AsyncResponse {
@Inject
lateinit var fetchWeatherTask: FetchWeatherTask
override fun fetchWeather(location: String, unitType: String) {
fetchWeatherTask.execute(location, unitType)
}
...
}
AsyncTask:
class FetchWeatherTask @Inject constructor(private var client: OkHttpClient): AsyncTask<String, Void, MutableList<String>>() {
...
override fun onPostExecute(result: MutableList<String>) {
returnWeather()
}
}
Solution
Your AsyncTask
is tied to your ForecastFragment
lifecycle. As long as your fragment lives, you will have the same instance of fetchWeatherTask
.
You should not inject your task. Instead, create a new one every time you need it.
Answered By - Benjamin
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.