How do I handle AsyncTask incompletion in fragments due to screen rotation
android
Solution
There are several solutions you could go with, but they all have one common theme...you shouldn't have long-running operations like that so tightly bound directly to your user interface classes.
If I were to make a suggestion, there are two possibilites that often work well:
- Implement your `AsyncTask` inside of a custom `AsyncTaskLoader` that you can connect to each time your `Fragment` is started up again to retrieve the data or wait for it to come back. There are a number of callback methods you need to implement, so you'll want to reference the documentation (link). You may also want to look at the source for `CursorLoader` to get another example of an `AsyncTaskLoader` implementation.
- Create a "data" `Fragment` in your application whose sole purpose is to manage your background tasks and provide the information when available. This fragment will have no UI component (i.e. don't override `onCreateView()`) and you will call `setRetainInstance()` so the `FragmentManager` keeps only one around. When you add the fragment with a constant tag value, all other components in your UI can easily find it via the `FragmentManager` to retrieve the data. For more information about this, see the docs section Adding a fragment without a UI.
Problem
I have an App which opens few fragments (actually 3) through a Fragment container (on Tab) and the first fragment uses AsyncTask to download feeds into the app. The problem occurs when there is screen rotation - the application crashes. I temporarily handle this problem by loading the data from PostExecute into private static variable but this problem can still occur when the user first enters the app. This seems a very common or rampant problem but I've not been able to find outright solution here. I do understand that this is because of configuration changes due to the screen rotation as the AsyncTask is running on a parallel thread to the UI thread. I do refrain from using the Java threads/executor/executor service at this stage since there seem a ready-made tool in AsyncTask I have been unable to interrupt the process in order to restart the activity or the fragment successfully and discard the initial subsequent AsyncTask calls.. In other words, how do I destroy the AsyncTask within a Fragment when there has been continuous configuration changes like Screen Rotation. Your help would be greatly appreciated. ``` public class MolyListFragment extends Fragment { public final static String MOLY_ARTICLE_DATA = "No Details"; private static final String TAG = "MOLY"; private static ArrayList<MolyPg> mMolyPgs = null; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); if (mMolyPgs == null) { new MolyLoadTask().execute(getResources().getString(R.string.mly_feed)); } else displayMlicles (mMolyPgs); //this displays the arrayList out of static mMolyPgs } private class MolyLoadTask extends AsyncTask<String, Void, ArrayList<MolyPg>> { @Override protected ArrayList<MolyPg> doInBackground(String... urls) { String myUrl = urls[0]; ArrayList<MolyPg> myMlPgs = null; try { myMlPgs = loadXmlFromNetwork(myUrl); } catch (MalformedURLException e) { Log.d(TAG, "MalformedURLException", e); } catch (IOException e) { getResources().getString(R.string.connection_error); } catch (XmlPullParserException e) { getResources().getString(R.string.xml_error); } return myMlPgs; } @Override protected void onPostExecute(ArrayList<MolyPg> result) { super.onPostExecute(result); Do some acrobatics here } ........ } } ```