Fragment crashes after being in background - android

I have this problem. I have an activity and a fragment inside it. I am downloading some data using async task in activity's onCreate and then using it in the fragment's onCreate (something like getActivity().getData()). I am putting the fragment into a view after the data is loaded so it runs without trouble. The problem is that when I'm relaunching the activity from background and this fragment is active it loads immediately and throws an NullPointerException because the data isnt loaded yet. My idea was to check for this in the fragment's onCreate and if I get null data I'll just destroy it and call some activity's method for reloading data and then lauch the fragment again - is it even possible?
Do you have any solution for this or maybe a better approach?

If it's possible to cache the data on the phone, I would consider it.
If you have to reload the data on every (re-)start (more like: every resume) of the app, take a look at the activity lifecycle in the android documentation:
http://developer.android.com/reference/android/app/Activity.html
Your problem should be solved, if you #Overwrite onResume() of your activity and load your data there, instead of onCreate()

Related

How avoid refresh MainActivity after returning from a second one?

When the app is started,in onCreate of MainActivity, some loading data from sharedpreferences and some numerical computations are done. But it is not necessary doing this every time it's coming back from others activities in the app. How can I avoid this?
onCreate is called when a new activity is created for the first time. If you navigate to another activity and come back to previous one then onCreate will NOT be called instead onResume will be called. Have a look at the documentation explaining the lifecycle of an activity
https://developer.android.com/reference/android/app/Activity

Fragments, dealing with async configuration for onCreateView

I have a Fragment in an Activity. When the Activity gets created, it triggers an asynchroneous load of the application state from a file. When this finishes, the Activity starts creating some paged Fragments, depending on the configuration state.
The problem is that when the OS kills the app, so that onCreate(bundle) has a stored state in the bundle because the OS took care of storing it prior to killing the app, the Fragments are also recreated immediately, but the application state is still getting read from the file, so they don't have access to the data they should be showing, which they need in their onCreateView(). This is because this time the Fragments are created by the OS, and not by the callback of the AsyncTask in the Activity's callback.
I'm hesitant towards making onCreateView() block/wait for the async result (even if it is avaliable in a fraction of second), so I'm thinking about moving the code which depends on the application state out of the Fragment's onCreateView(), and have some callback create it when the data is avaliable.
Ideally I'd work with deferreds/promises/futures, where I can "subscribe" to the async load result in the onCreateView() , but i'm too new to Java in order to know how to do this. I don't know which libraries exists or are suited for this.
Which suggestions do you have for me so I can deal in the best possible way with this issue?
Kind regards.

Wrong Fragment is loaded when resuming after my app was killed

In my App I have:
DataManager class - a singleton which holds data
Activity which shows a 'loading' fragment until the data is ready, and then once it is ready, it replaces it with a 'content' fragment. (I do this with the replace() method, since I no longer have use for the 'loading' fragment)
The following flow causes (sometimes) a null pointer exception:
Open app and wait for the data to be loaded (meaning, until we get to the 'content' fragment)
leave the app using the home button
open the app after a while (after Android kills the app)
What happens is that the app resumes to the 'content' fragment, but the data from the DataManager is null.
This happens because Android kills my app, but when I resume, it saves the state, meaning it shows the 'content' fragment automatically.
Is there a way for me to tell the app not to create the 'content' fragment in this scenario? The solution I currently have in mind is to create a 'loading' Activity instead of a fragment, but i'd like to avoid that.
What I would suggest is either:
Persist your data to disk (e.g. SQLite DB), rather than retaining it as static data.
In your Activity onCreate(), check if you have data. If you do, continue on. If not, remove the content fragment and add back the loading fragment.
I would suggest that in the content fragment before loading other views and all, check if your data is ready. if not then start the loading fragment and resume content fragment when it's ready.
e.g in OnCreate
if(!dataLoaded){
replaceFragment(LoadingFragment)
}

Lifecycle of a fragment when startActivityForResult() is called

I have a snippet of code that calls startActivityForResult() to pick an image from the Android gallery. I have trouble understanding the lifecycle of the fragment from when startActivityForResult() is called and onActivityResult() is activated.
My activity retrieves and loads information onto a listview. It then allows user to insert pictures into the listview by sending an intent to the camera/gallery app using startActivityForResult(). This part works perfectly. The problem is that the list loses its data when the app returns from the intent and has to retrieve the information again. I have setRetainFragment(true) already.
My question is, is there any way to retain this data from when the intent is started and when it is returned? My guess would be to save an instance of it in onPause() and onResumse() but I don't quite understand how its lifecycle goes during this event.
Thank you in advance!
I have found a solution to my problem. To answer my question about the lifecycles, the fragment does go through the onDetach(), onAttach(), onCreateView() process. However, because i set onRetainInstance(true), it skips onDestroy() and onCreate(). The reason why my data is loss, is because I retrieve the data during onCreateView() and since onCreateView() is called everytime, so is retrieving data. From this, all I had to do was check if the list is empty before retrieving my data.
Another side problem, however, is that my variables are not retained. Although the list is retained and therefore my listview remains the same, boolean and int variables are reset and I don't know have a solution for this yet. If anyone can help, that would be great!

How to put the proper code for each android's life cycle?

What is differences between onCreate and onStart cycle ?
I got confuse to put the proper code for these cycles.
for example in my case, I have main activity listview to display data from database and other activity to create data to database.
Activity to create data is called by listactivity. After creating data is succeeded, it would be back to listactivity. And the data in listview should be updated.
When I put initialization database, cursor and adapter on onCreate method, the listActivity wouldn't update the latest data after creation the data.
But if I put it on onStart method, it's updated.
my question: Is it correct in this case to put all initialization on OnStart method ?
Because I'm thinking it would be expensive to reinitialize for each database record to listview if there is one updated data.
What is differences between onCreate and onStart cycle ?
onCreate() is called when the activity is first created. onStart() is called whenever the activity becomes visible, which includes when it is first created (after onCreate()) and after it is coming back to the screen from being stopped (e.g., another activity took over the screen).
I have main activity listview to display data from database and other activity to create data to database. Activity to create data is called by listactivity. After creating data is succeeded, it would be back to listactivity. And the data in listview should be updated.
Use a managed Cursor, and that will happen automatically. See startManagingCursor() on Activity.
It depends. Do you want the data to be reloaded everytime the user comes back to the visible activity? If yes, you should add these methods in onStart(). If you are looking to load the values at the very beginning (more like a once off job) and do not want to be reloaded, then onCreate is the right place.
See doco for explanation of onCreate and onStart. This diagram in the link is useful
http://developer.android.com/guide/topics/fundamentals.html#actlife

Categories

Resources