I start Activity B from Activity A. Activity B does something to my Data and at some point I call finish();, however Activity B is still doing something with my Database in the background and when its finished I want to get notified in Activity A, that this process is finished.
Because there is no way to my knowledge to call a method from another activity I tried to solve this problem with startActivityForResult but because Im calling finish(); before actually setting a Result this does not seem to work either.
Any Idea on how to solve this problem?
Don't do task in Activity that may live beyond Activity lifecycle. In that case do your task in Service and notify the Result to Activity. There are some ways to communicate between Activity and Service using BroadcastReceiver , Messenger, Handler, Bound Service . You can also use EventBus library for this communication.
Check this and this thread for communicating between Activity and Service
Try to close your database, and after it's been closed successfully, 'notify' your activity A about this result and finish activity. Quite an imprecise question, frankly :P
And if you want to invoke some method from another class, pass the activity's Context.
Related
Here is my situation:
I want to make an Activity A which start an IntentService, and write the ResultReciever on Activity B. In another words, I have an Activity A that have some works to do but the results should be written in Activity B, any solution to do this? Note that I don't know when the work of the service finishes.
I have 2 activities
Activity A has a registered receiver that updates a static generic list.
Activity B accesses the static generic list in Activity A.
The problem is:
If Activity A ended (killed by the system), the registered receiver stops, which makes the data in the static generic list unreliable, as it depends on the registered receiver to be updated.
And the biggest problem that the static generic list doesn't get terminated (null / zeroed) along with the registered receiver, though both of them created by the same activity.
So there's no way for me to know that my static generic list has become unreliable to reload it all over with fresh data when Activity B gets created.
Also there's no way - listener - to listen to the registered receiver termination, where I'd have terminated the generic static list, and check it in Activity B creation, if it's null, I'll reload a fresh data.
And as you know it's not guaranteed that onDestroy will get called when the system terminates the activity, otherwise I'd have terminated the generic static list.
I even added a static Boolean var (mAlive) to Activity A that has a default value (false) and becomes (true) in onCreate, in hope that when Activity A gets destroyed, (mAlive) will become false (the default value in its declaration), which I could check in Activity B to know that the registered receiver is terminated and the data is unreliable and reload it again, but it turns out, that even destroying Activity A, doesn't reset static Boolean var (mAlive) to its default value (false).
So, any suggestions please, I got a brain freeze trying to find a solution in the past 2 weeks.
Thank you
You seem to be greatly misunderstanding the Activity Lifecycle.
Only one Activity at a time can be running. The current one is suspended when a new one starts and you cannot access directly anything contained in one Activity from a different Activity. Static variables can hold simple data but that is not recommended as a way to avoid dealing with the Activity Lifecycle.
To pass data between activities, you use Intents and Extras.
How do I pass data between Activities in Android application?
If you want two Activities to share the same data, you could use a Service that contains the data which can be accessed from both Activities.
You can fire a Broadcast(BroadcastReceiver Example) from your desired activity's onDestroy() method. Afterwards Receive broadcast in your required activity.
You can put your data into a separate object so you don't dipend on your activity A's lifecycle. You can see an example here at Finder section
I think you could make a parent activity extended by both your Activity A and B. In your parent activity you could register your receiver into its onResume method and then unregister it into its onPause method. By this way you should have always your receiver registered to the current activity.
Then if you have read the previous link, if you make a Finder responsible to keep your fresh data and you reference it into your parent Activity (so you have a reference into both Activity A and Acitivity B) you should be sufficiently sure that a variable referenced by the current active activity can't be destroyed by the system.
I'm not sure to have understood what you need, let me know
I searched through most answers here and all suggest we add a flag to the intent to kill old activities. The problem is my activity only receive intents from other app and has no control over it.
More specifically, my activity receive an intent to load a picture, then it uses Asynctask to load and do some complicated background processing of that picture, say, may be 2 minutes.
If the user at this moment back out (assuming that only onStop is called, not yet onDestroy) and share another picture to the app , this will start a new activity, and the previous activity cannot be accessed, but its Asynctask hold up the thread so that my new activity just freeze without starting its own Asynctask.
(I later tried the parallel thread executor, but this doesn't stop the old thread from running, thus consuming computational resources).
Any idea what I should do?
(I don't want to stop the task in onStop as this is to easy to be called. But I do want to stop the task if new picture is shared, since it is no longer needed.)
(The Asynctask will spit out a huge array of self-defined Objects declared in the main activity, and thus the activity gets immediate updates of the result from the background process, and the UI updates immediately after onPostExecute is called.)
EDIT:
It seems that your problem is that you're trying to do all this image processing work in asynctasks launched by your activity. Have you considered changing your app architecture to rely all this background processing to a service?
You can use the activity to show some UI information while you process the image in your service, or if you don't need this UI just simply communicate with the service (through broadcast, for example) to provide it the image and let the service show some information of the process through notifications.
If you don't want to keep your activity alive when you exit it you can use
android:noHistory="true" in your activity declaration at the manifest
More info here
This is the workaround, and seems it is working very well for the moment:
After getting a sharedpreference prefs, do this in onCreate:
prefs.edit().putBoolean("ForceClose", true).commit();
In the onPreExecute() of the AsyncTask, put:
prefs.edit().putBoolean("ForceClose", false).commit();
In the doInBackground() of the AsyncTask, constantly check for
if (prefs.getBoolean("ForceClose", false))
cancel(true);
and call finish() in onCancelled() to finish off the activity.
here's my problem:
I'm in activity A
Activity A starts a new activity B to call a number (Intent.ACTION_CALL)
How is it possible to resume activity A - I don't want to finish activity B, I simply want to bring activity A to the front
At the moment I have a broadcastReceiver which is able to start a new instance of activity A when the call takes place. If I start activity A from there with "FLAG_ACTIVITY_SINGLE_TOP", I get the error
Calling startActivity() from outside of an Activity
context requires the FLAG_ACTIVITY_NEW_TASK flag.
Is this really what you want?
But I don't want a new task, I want to RESUME activity A
Thanks a lot!
EDIT:
Perhaps I could simply simulate a click on the BACK-button?
Considering your use case - BroadcastReceiver that doesn't have a tasks in which to start the activity - singleTask in the manifest should do what you want.
"singleTask"
The system creates a new task and instantiates the activity at the root of
the new task. However, if an instance of the activity already exists in a
separate task, the system routes the intent to the existing instance through
a call to its onNewIntent() method, rather than creating a new instance.
Only one instance of the activity can exist at a time.
Note: Although the activity starts in a new task, the Back
button still returns the user to the previous activity.
Taken from: http://developer.android.com/guide/components/tasks-and-back-stack.html
Have you tried using FLAG_ACTIVITY_REORDER_TO_FRONT ?
http://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_REORDER_TO_FRONT
It seems to do exactly what you need.
I writing the network application and i have a problem with starting activity if the application in background. I want to start activity when some data comes to network. In my Actity A a have a receiver and when it receive some answer from server, it must run the Activity B. But if the App in background, Activity B not starting and metod onCreate() doesn`t execute. It execute only when the user go back to App. But its not really what i want, becouse in Activity B i need to start timer and i neen to enable GPS and some other work. Besides that, Activity B receive some data too, and if B not existing - this receiver will never receive anything.
I tryed IntentServise, but its not working - result the same as without him.
Any ideas? Thanks for any information :-)
Maybe your receiver is not getting intents when your app is background, for example if you're unregistering it in onDestroy method...
try declaring your broadcast receiver in manifest. In broadcast receiver class use starActivity to call act B. This works for me.
If you still have some problems maybe you should provide some source code(for example function where you're working with intents) to clarify your question.
You can't force activity to come back from background. You can use status bar to show notification for a user. Think also about it that this a mobile device, someone can in the middle of conversation or use GPS as navigation in car.