문제

I'm developing an android tablet application and i need to implement screen orientation (landscape and portrait). when screen orientation changes the fragment asyntactask restarting again. (sometimes application crashing) I need to stop restarting the asynctask and request data again. want to load the existing json data in to the new screen. any help appreciate.

approch: android:configChanges="keyboardHidden|orientation|screenSize" is not working because of im using a fragment class.

도움이 되었습니까?

해결책

You may find some hack (including muting the configuration changes or retaining the instance) to somehow get it work, but really AsyncTasks are evil and you should stay as far as you can from it most of the time.

If your current AsyncTask's job is to load some data from the network before showing it inside your Fragment, I'd recommend to use an AsyncTaskLoader. The examples in the javadoc should give you a good idea of how to implement it.

This will allow the network request to keep going while you rotate, to notify the UI (i.e. the LoaderManager.LoaderCallbacks) with the result only when it is ready to process it (so not while rotating for example), and will also cache the result so that you don't re-issue the network request each time you need the data.

There are a bunch of 3rd-party libraries trying to address this very common problem too, and Loaders also have their intricacies, but if I understand your use case correctly it should be just what you need.

Don't forget that whatever solution you choose it will have to account for the rotation (activity destroy / recreate) happening before, during and after the load of the data.

다른 팁

It seems that this approach is the less recommended. If you're initializing and executing your AsyncTask within your onCreate() method, I'd suggest using this approach. Basically it consists on saving the data you don't need to restart on a runtime configuration change, so you can handle them afterwards in the onCreate() method and decide which information you want to keep from the previous landscape and which should be restarted.

You can easily avoid the "re-creation" of a fragment, just using the setRetainInstance method on it.

public void setRetainInstance (boolean retain)

Control whether a fragment instance is retained across Activity re-creation (such as from a configuration change). This can only be used with fragments not in the back stack. If set, the fragment lifecycle will be slightly different when an activity is recreated:
• onDestroy() will not be called (but onDetach() still will be, because the fragment is being detached from its current activity).
• onCreate(Bundle) will not be called since the fragment is not being re-created.
• onAttach(Activity) and onActivityCreated(Bundle) will still be called.

Reference link

You can use this for example in you onCreateView method, like this:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
    setRetainInstance(true);
    // ... more of your code
}

While the Activity that contains the fragment still re-creating, the fragment instance will be the same, and will be reattached to the new activity.

Keep in mind that even with setRetainInstance the onCreateView method will be called always (in orientation change) because the fragment need to inflate the view according to the new space/dimensions, so if you are executing your asynctask from that method, you should consider moving it to the onCreate method (which will only be executed once) to avoid the "re-launching" every orientation change.

Hope it helps.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top