how to send data to multiple activities in controlled manner in Android? - android

I am working on an android application, where there are 4 activities. Activity1 is main activity and there are different buttons on that activity which can open other activities. Other 3 activities can also open each other. There is a thread running in Activity1 which returns some counter. I need to show that counter on all activities.
At an specific time, the thread doesn't know which activity is at top. What is the right way to control this scenario, such that thread output should update on all activities, no matter which one is at top?

I would have that counter on a Service and I would send updates through broadcast intent.
Each Activity will register a listener to that intent on the onStart method and unregister it on onPause. This way the update will reach only the Activity that is on screen.

Related

How to jump to main activity from subchild activity without using Intent?

I have following activities. 1) Main activity 2) Activity 1 3) Activity 2
This is the way Activities is connected together
Main Activity -> Activity 1 -> Activity 2(Create Background Async Task) So "Activity 1" is child activity and "Activity 2" is a subchild activity. And creating Background Async task from "Activity 2"
So Let's say I am currently on "Activity 2" screen and Backround Async task is running. Now after some failure event on "Background Async task", I want go back to "Main activity". What can be good way to do this?
Few way I am thinking is, 1) To restart the app completely 2) To create new Intent of Main activity from Background Async task just like we created "Activity 1 & 2".
I am not sure which one from this is good to use. Is there any other way to do it?
I am kind of newbie to android. I am currently using BroadcastReceiver(on Activity 1 & 2)to finish current activity when Background Async task broadcast failure event but sometimes it jump to "Main activity" and sometimes jump to "Activity 1". So not working as I am looking for.
Will you please suggest a good way to do this?
[Sorry, I had to ask this question once again. Because old question was deleted]
#Rohit, I tried way you suggested to finish Activity 1 before going to Activity2. That also works but It create one another problem.
After doing this, when I press back button it directly go to Main activity rather than Activity 1 since it no longer exist.
Is there any solution which can get this both thing working? I want to jump to Activity 1 when back button is pressed. And I want to jump to Main activity when Background Async task created from Activity 2 find problem.
[Edit]
Let me describe more specific case.
Main Activity list open Wifi access point based hardware.
When clicked on particular listed access point, It opens Login activity and ask for user id & password for hardware access. Login activity onCreate function also create TcpAsyncTask background task which will communicate with hardware(which has WiFi accesspoint feature) for authentication and data passing.
When user enter login detail and click on login button, It will create momentary background task LoginDeviceAsyncTask. This task will communicate to hardware via TcpAsyncTask created earlier to verify authentication. If authentication is successful, it will create Navigation activity using startActivityForResult.
In the Navigation activity, It list options for opening specific window e.g. Dashboard. History. When user select Dashboard from options, it creates Dashboard activity using startActivity. When user select History from options, it creates History activity using startActivity.
So if Dashboard activity is opened, it display some data periodically received from hardware using TcpAsyncTask(created earlier in Login activity)
Similarly if History activity is opened, it display some data periodically received from hardware using TcpAsyncTask(created earlier in Login activity)
Dashboard/History activity has options to move to History/Dashboard activity directly. For this it creates selected activity using startActivity and finish current activity.
Now my problem is,
Let's say I am in Dashboard activity and it is displaying data received from hardware using TcpAsyncTask. Now somehow TcpAsyncTask fails to communicate with hardware and at this point I want to move to Main activity directly.
In TcpAsyncTask, I don't have context of activity like Navigation/Dashboard/History which was created after TcpAsyncTask. May be I can get this context in TcpAsyncTask using some MainActivity variables which is updated as per create/finish. Am I correct?
I am current broadcasting to close from TcpAsyncTask and receiving broadcast message in Navigation/Dashboard/History activity using BroadcastReceiver and finish particular activity which received broadcast close message. But sometimes it jump to Main activity and sometimes it jump to Navigation activity when sendBroadcast from TcpAsyncTask to close.
Pass Context in your AsyncTask and through that you can kill your Activity 1 as well as Activity 2
((Activity)context).finish();
You can do this for both activities by passing context of both.
One possible solution is to start Activity 2 with startActivityForResult() then during its processing, you can call setResult() to indicate success or failure. In Activity 1, override onActivityResult() and detect the result of Activity 2. If Activity 2 indicates a failure, simply call finish() on Activity 1 to return to the main activity.
Firstly, remember that code being run in an inactive activity when it is not in the foreground cannot be relied upon. So you should not rely on background async task. Instead, use a Service which does the background processing; this is precisely what Services are meant to encompass (among other persistent processing). While it is quite a lot for a beginner to learn, it will save you a LOT of trouble long term, as its lifecycle is far easier to manage than complex webs of activities and their relationships and lifecycles.
You should read up on android "Back Stacks". If you finish an activity, the previous activity on the back stack will be displayed. These are like the history browsers maintain that determine how browser back-buttons to operate.
So what you need is the main activity spawning a new instance of the sub-activity. Then when the user navigates the back button, the previous activity in the back stack (your main activity) will be resumed. This will not need intents.
However, for an activity to be triggered by a background processing task, I strongly recommend using a Service and intents to co-ordinate it all.

Android : Stop Activity(s) after starting Service

I have the following flow in my code:
Activity1 : startActivity(Activity2) --->
Activity2: startActivity(Activity3) --->
Activity3: startService(MyService) --->
MyService: startActivity(Activity4)
Each Activity above shows a single view and represents a step in a 4-step setup. The final Activity - Activity 4 - is started after some setup work is done inside MyService, which basically tells the user,
"The service has started, you can close the application by pressing Back or Home button"
When the user presses Back or Home, I want to destroy Activities 1-4 , and only have MyService running. Also, after stopping the Application as above, when the user navigates back to the Application via the menu and starts it, I'll be checking if MyService is already running. If it is already running, I don't want to show Activities 1-3, I want to show another Control Panel View (Another Activity), which says,
"Dude, the service is already running, do you want to Stop or Restart it?"
This view will have a Stop and Restart button, to do the appropriate tasks.
My Questions:
How do I stop Activities 1-4 from inside Activity 4 when Back or Home is pressed,safely? My thought was to add a static stopActivity() method to each Activity, and calling Activity[1-3].stopActivity() from onBackPressed() or onPause() of Activity4. Then inside each stopActivity(), I'll call finish(), thus ending each Activity. But is it safe and efficient to do it this way?
The flow I have illustrated above, is it the optimal way of doing things, or is there a cleaner way? I have BroadcastReceivers registered in these Activities, so I need to perform clean exits for each Activity, without leaked receivers, or worse, crashing the App or affect the User's phone due to unclean exit strategies.
Thanks for your suggestions.
You don't need to stop activities, Android will do it for you. Start your activities using intents with the flag FLAG_ACTIVITY_NO_HISTORY so they won't appear when the user presses back. Those activities will be stopped as soon as the user leaves them.
In the onStop method of each of your activities, write any code you want to deallocate memory if there is something you want to deallocate manually, although that wouldn't be necessary because Android will deallocate it for yourself when the device is short on memory. In those onStop methods unregister any BroadcastReceiverpreviously registered.

How do I start two activities at same time?

I want to start two activities A and B. I want A to be in the foreground and I want B to be in the background.
At some point, I want to switch the order of the two Activities: A is moved to the background and B is moved to the foreground.
But here there are three different activities comes live, Acitivity A will start actvity B in bacground and activity C in foreground
You can use below link to start one of your activity in background
Sending Activity to background without finishing
Other activity which you want to start in foreground can be started normally.
You don't really want to do this. Activities in Android are meant to be shown to a user and be interacted with. If you launch more than one Activity, there is no guarantee that your other Activity will even be around when you need to display it.
Perhaps it would help to know more about what you are trying to accomplish.
If you want to have code running in the background, you should consider writing a Service or an AsyncTask.
Service: http://developer.android.com/guide/topics/fundamentals/services.html
AsyncTask: http://developer.android.com/reference/android/os/AsyncTask.html
Your question is not clear, if you are asking whether or not you can start two activities at the same time? The answer is no, Android's mechanism is such that an activity can start another activity and so forth.
Read this for more reference on how you can start and use activities.
http://developer.android.com/guide/topics/fundamentals/activities.html
Moreover read this to understand how you can switch between your activities to get the desired result http://developer.android.com/guide/topics/fundamentals/tasks-and-back-stack.html
There are 2 ways to do what you want:
The first way is to launch one of the activities (the one you want "in the background") and have that Activity launch the other one (the one you want "in the foreground") immediately (in onCreate(). When the top Activity is finished, the other one (the "background" Activity) will be shown.
The second way to do this is to simply launch the Activity that you want to be in the "foreground". In this Activity you can override onBackPressed() to launch the other ("background") Activity. In this way, the user experience is as you desire, but you don't need to launch the "background" Activity until it needs to be shown to the user. Depending on your requirements, you can also switch back and forth between these 2 activities, by simply calling startActivity() with an Intent where you have set Intent.FLAG_ACTIVITY_REORDER_TO_FRONT when you want to move from one Activity to another. In this case, Android will bring an existing instance of the target Activity to the front of the task (if it exists) or will launch a new instance of the target Activity (if one does not already exist).
However, none of your terminology is correct and that causes problems when communicating with other developers. An Activity isn't in the "foreground" or the "background". These terms are used when talking about tasks. A task is in the "foreground" when the user is interacting with it and it is shown on screen. Other tasks are in the "background". A task is made up of one (or more) activities, and they are stacked in such a way that the top-most Activity is the one that the user is interacting with. The other activities in the task are not "in the background", they are just paused.

Running a thread while Android app is in foreground

I have an Android app. I have a main activity, that has a button. When the button is clicked, another activity comes to the foreground. The thing is, I want to run a background thread that polls updates from the server. However, I want it to run only when the app is in foreground (either the main activity or the second one), and to stop polling when the user clicks the Home button or clicks the Back button till it's going back from the main activity.
But how do I know if the app is still in the foreground? I can catch the onPause of the main activity, but it's called also when I'm launching the second activity.
So how do I know when the app is in background?
Thanks
You should make a Service for the work you are doing in the background.
For stopping it when you click the Home or Back button, just make a listener for them and stop the Service when either one is pressed.
Seems easiest to me that each activity polls. Is it super important that it can poll when it is between the two activities? Otherwise you will have problems about knowing who is in front or not.
You can have a singleton with reference counting.
You main activity should add the first reference on it's onResume and from now, upon calling for every new activity (startActivity for example) you should add a reference.
Each activity should decrease the reference counting on its onPause.
Another option is to use services: Services

Sending a message to a not yet started activity

In my application I start a Register activity from the Main Activity with a button
startActivity( new Intent(getBaseContext(),Register.class));
This Register activity creates records that can be viewed in a ListActivity.
If I go to the ListActivity from the Main Activity (with another button) and decide that I want to send the data of a record from the ListActivity to the Register activity in order to edit it, there are two possibilities:
1- the Register activity has never been called
2- the Register activity is opened in the background
I have two questions:
-Calling startActivity Register.class once from Main and once from ListActivity will it make two copies of Register or one?
-When I call Register activity from ListActivity and try to pass data with a handler, the handler message arrives before the activity is opened and the data do not show in the Register screen? How can I do that? Is there a way to know from the ListActivity when the view of Register is opened?
Thanks.
Charles.
The first question has a complex answer, but shortly you can control instantiation of activities, only it has implications in flow of user interaction: see Activities and Tasks, particularly Launch modes.
For the second, I don't know what kind of data you're going to pass, but consider putting it in the intent with some Intent.putExtra() method (there are many for many types of data).

Categories

Resources