I have an activity that sends a BC and waits 5 seconds for the response using AlarmManager.
Once i get the broadcast i:
1. remove the FragmentDialog using mDialog.dismiss();
2. start a new activity using getActivity().startActivity(myIntent);
I'm inside a Fragment (using TabFragment from the support library and MyTabActivity which i created).
The thing is i constantly getting balck screen and ANR, if i remove the line startActivity()
I'm not getting the ANR, the fragment does gets dismissed, but my activity doesn't show, i get the black screen and if i press it, ANR.
What i thought about is that the fragment manager started out working on the activity and then i started a new one that fucks up android, since i'm basing myself on fragment i really don't know how to get out of this mess, thought of using handler in the activity to post my activity start in 300 millis, this is a very very ugly solution.
Any nice ideas ?
the problem seems to be that i unbding a service twice in onStop of the activity due to the fact that once i call unbind ServiceDisconnected is NOT called and changes the state of my activity to unbonded (state i follow).
since onStop is never eding the original activity gets the UIthrehad and make the whole app stuck...
Related
I'm using an Activity A which starts another Activity B to get a result (the id of a customer), all seems to work perfectly but I have few error reports which tend to indicate that I have a concurrency bug between the UI building process and the onActivityResult method.
The whole hypothesis is based on the fact that the Activity A could have been destroyed during the appearance of the Activity B and created again which can create problems because Activity A creates its UI by doing some asynchronous network requests.
Of course, I'm not able to reproduce the bug (stopping the activity manually would be the nearest reproduction but only if the problem is the concurrence bug I mentioned).
So, in short,
Is it possible that an activity starting another one for result is cut by the OS while the user is in the newly created activity? (and then recreated when the user is finished and when setResult and finish are called on the newly created activity).
-- Update --
Sorry for the imprecision, Activity A is containing a Fragment which is starting the Activity and doing the network stuff, so it's maybe a matter of fragment (so the question is also "could the OS cut a Fragment which started an activity for result?").
Whats the recommaned approach to notifying the hosting activity of a fragment that performs some background processing, that its done. Assuming that the fragments are running some threads that are performing work outside of the main looper.
A simple callback won't do since:
The Activity could be detached due to screen rotation which would lead into a NullPointerException.
Polling from within the activity is just dumb
Only calling the activity once if attached and let the activity check after each onCreate call (i.e. due to screen rotation).
What I currently do but it seems wrong: Whenever the Fragment gets attached, it will check if the work is done and notify the activity via callback. If the fragment finishes the work it will also callback the activity (if attached).
Why I think is is wrong? Because I have some really ugly methods that check if the fragment is attached and also if the work is done in order to maybe call the callback. This becomes very stupid when an exception is raised during performing some work in the fragment and the activity is detached. If android decides to call onSaveInstance in the same moment I will have to put the Exception into the Bundle and deliver it later when the Activity and fragment is recreated from the saved state. Additionally I can run into a situation where a activity will received the same callback twice (once from checking the fragment and the second time when the fragments gets attached; this could happen when the application got saved and restored)
This generates so much code that, in my optinion, could be much more clear if activites won't get detached. That is why I hope I'm doing something wrong and hope someone will provide me with a better solution.
I would say you should use a service for your background processing but if you've chosen a fragment for a specific reason you can stick with that. The way you should notify the activity from either a fragment or a service that might have a different lifecycle from the activity would be through a BroadcastReceiver. With this method the activity can register and unregister a BroadcastReceiver during its own lifecycle callback. From the fragment or service you just send the broadcast and forget about it. If an activity is listening for the broadcast it will receive it, if not nothing will happen.
I'm trying to start an activity (Act2) from another activity(Act1), and it doesn't happen like it should.
In the debugger, I can see that as a result of calling startActivity() the method onCreate() of act2 is called 3 times (!!...), no error shows, or exception caught, and unfortunatly the desired UI doesn't show.
for trying to understand better where is the problem, I run the next 2 tests that showed expected normal behavior:
when I modify Act1 to start Act3 (instead of Act2, just for
understanding if its a problemof Act1), then act3 shows its UI as expected.
when Act4 start Act2, it runs as expected, and show the UI on the screen.
As to the code, I start the activity in the common way of:
Intent intent = new Intent(Act1.this, Act2.class);
startActivity(intent);
Anyone faced such thing?
Thanks.
You might want to read through the documentation on the Activity lifecycle.
OnCreate will only be called one time for each lifetime of the Activity. However, there are a number of situations that can cause your activity to be killed and brought back to life. Thus, onCreate will be called again.
To support this properly, you can save state information in onSaveInstanceState and restore it fron the state bundle you get in on create.
I'm building an application using a service and the fragment compatibility pack and am running into some weird behavior. I have a FragmentActivity and a ListFragment which implements LoaderCallbacks, and when the FragmentActivity starts it kicks off a service to download data and fill in a database.
Suppose I'm on that screen, and I navigate past it by clicking on one of the rows of the ListFragment. If I then hit a nullpointer, or any other exception that causes the regular force close dialog to pop up, I hit the force close button on the dialog and the activity I'm on does indeed get shut down, but I end up back on the FragmentActivity screen, rather than say my Android/launcher home screen.
To me this says that the app is crashing but somehow the fragment activity is getting restarted. The behavior occurs if I hit the red stop button in the debug view in eclipse - the current activity gets killed but that damn fragment activity is still there.
Obviously I don't want my app to ever get a force close dialog, but really what I'm trying to figure out is if this is a symptom of me not coding something correctly. Currently I never stop the service, mostly because it gets reused over and over again throughout the app and I haven't gotten around to coding up a way to close the service safely without prematurely ending a new request to it.
Is the service keeping a reference to the Activity via the ListFragment and LoaderCallback or something? Why is this FragmentActivity seemingly invincible?
This is happening because your process is killed, but there are other activities on the activity stack. This is the expected behavior, as the system attempts to start a new process on the next activity on the stack once your offending activity was removed. See here and here.
If you want to remove all of your activities off the stack after a force close, one thing you can do is hit the back button until you are taken to the home screen. Unless you override the behavior of the back button in your app, it destroys your current activity and takes you to the previous activity. Once there are no more activities left, you will be taken to the home screen and can start your app again from eclipse, and it will start you off at your main activity.
i had run into similar problems, with Databse loading and Nullpointer Exceptions. I don't know your special case but it might help to separate the Databse out into a Content Provider if you aren't already doing that, that way you are decoupling the Fragments form the Database more, it might help with the errors.
I have a tab widget where one of the tabs is a chat-type feature. I want to update the chat data at an interval (variable depending on whether the chat tab is active or not).
The best approach seemed to be using an AsyncTask in my main TabActivity class, as that would avoid any issues of the chat activity being destroyed while in the background, while an AsyncTask was running. I wanted to ensure that the Activity isn't destroyed and recreated, thus causing my AsyncTask to be unable to modify the actual active Activity's data.
However, now that my AsyncTask is in the TabActivity activity, I don't have a direct way to call my Chat's ListAdapter notifyDataSetChanged() from my onPostExecute() method anymore. Is there a way to get a reference to a given Tab's current Activity from the TabHost/TabActivity?
Or, alternatively, can I assume my chat activity will never be destroyed as a child activity of the TabActivity activity (well, never destroyed while the TabActivity is active at least), and then just put the AsyncTask in the Chat Activity?
Really the best way to do this is to have a thread that runs and periodically gets the chat data. Then from your UI you can poll the thread to get new messages. This way you can have the thread running no matter what happens to the Activity.
If you're using the Intent loading mechanism for your tabhost, then you should be safe in assuming the task won't get randomly killed any more than the TabHost itself (only paused), and you can safely modify views in it (as safely as you could from the TabHost, at least).
But beware: Any activity can be killed at any time (example: if a user clicks on a link in the tab that opens a new activity while your task is still running), including the tabhost itself, which can lead to ugly crashes when the task returns and tries to update the UI of the now-dead Activity. So make sure to either cancel your AsyncTasks on destroy, have the asynctasks check that your activity is still active before returning results (see WeakAsyncTask in the Android source tree), or use an Activity-independent (semi)persistent pollable background-thread solution like CaseyB suggests (cwac-bus is a nice premade solution in that vein).
Alternatively you could just have the AsyncTask's UI-updating code catch all exceptions (I've seen a few apps that do this) and fail silently, but that smells funny to me.
Lately I've used a modified version of the WeakAsyncTask in most places that checks that the activity is non-finished on returning, personally.