I've got two Activitys in Android. Lets call them A and B.
Activity A has a ViewPager and its data will be loaded via AsyncTask.
The user can start Activty B from Activity A.
In Activity B I've got an AutocompleteTextView and its content will be loaded with a AsyncTask, too. (The App will only make an request when it is not cached)
My problem is when I search in Activity B, the AutoCompleteTextView will generate too much AsyncTasks and when I leave Activity B it takes a while too load the data for the ViewPager (in Activity A).
I think the App can only handle some of the AsyncTask at the same time. The rest is waiting and when I leave Activity B there are still waiting some AsyncTasks (for AutocomplteTextView)
My question is: How can I improve this. Can I use a Service (with an extra process)
Related
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.
I want to build a "smart downloader" that can download images in background (using AsyncTask).
There are two Activity, A and B. In activity A, I can choose the image list I want to view, (first download if not have been download once). Then enter activity B, here I launch a asynctask to download the image in background and in the UI thread, show the image to the user.
there are some large list that may take minutes to finish downloading. One tricky problem is when the asynctask is still downloading the list, the user may exit activity B (come back to activity A. (I know the asyntask will still continue working even if activity B is destroyed).
But if at this time user choose another list to view (then enter activity B). I want to stop the previous task for a while, began to downloading the new list first, and then the old list.
My thoughts to do that is retrieve the previous asynctask and modify the downloading order. But I don't know how to retrieve the asynctask, I have search some questions about recreate asynctask, but they are all about after re-configuration (like rotate the screen). is there a way to retrieve the background working asynctask, after i destroy the activity and recreate it.
Thanks!
Once you destroy an Activity, the AsyncTask is gone. For this reason, AsyncTasks are not the optimum solution if you want to avoid running the background operation from scratch.
I think you should structure your app to download images using an IntentService. In activity A, choose the image list. Once it's chosen, fire off an IntentService to download the images. Once the IntentService is done, it can notify the user that the operation is complete or send a local broadcast message back to the activity. In either case, even if the user has navigated away from the activity, the work hasn't disappeared. If the activity was destroyed, you can figure out if the download is done, and if so, display the images. If it's not done, you can put up an activity indicator.
How can i transfer data between two activities, without actually move to that activity? The scenario is as follows:
Activity A is a splash screen. While the splash screen is showing, some data is being generated in the background of type ArrayList. After This data is loaded, i need to start Activity B (lets say a Login screen) and just before that i need to transfer the data to Activity C. I know i can use PutExtras for transferring data, but wont this run the target Activity instead only sending the data?
Thanks
The full flow of the app is as follows:
Activity A (splash screen) --> Activity B (Login screen) --> Activity D (some user interface and buttons) --> Activity C (the activity which should be able to load the data generated in the splash screen upon certain Button press).
I think You don't fully understand life cycle of Activity and application.
Rule of thumb, there is always just one activity, (it is the worst scenario when each activity has to be recreated when You go back to it) the one visible at the moment. You can't do things like start activity but don't show it yet or anything like this.
If You have expensive task to do like downloading data do it in AsyncTask
if this task has to be start and finish when You enter and leave Activity A use fragments
if it has to finish once You start whether Activity A is still existing or it was already destroyed use services
Places You can store this loaded data so it may be easily accessed later form any Activity is database with help of Loaders(loader is optional but really nice) or SharedPreferences.
If you want to pass data to an activity that is running and not start a new instance of that activity you just need to set flags on your intent. For example:
Intent i = new Intent()
i.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
will not re-launch an activity if it is already running at the top of the stack. If all you want to do is get data to Activity C which is running without starting it again you could try this or one of the other flags. There's a bunch of them. Just look look through the list and see if one fits your needs.
I hope you can help me understanding the Android Lifecycle and how I can manage navigation between several kinds if activities. Suppose the following scenario:
Activity A "MainMenu" is started: User clicks on a menuentry
Activity B is started and UI is loaded with content from local database
user interacts with Activity B
user presses Backbutton and returns to Activity A
user presses again the same menuentry for returning to activity B
At the moment: The activity is loaded from scratch
Whished: The previous instance of Activity B with all its UI entries and User interactions should resume
I thought of saving all activities in a static manager. If a activity is started, the manager looks if it has already been started previously. If so, resume the previous activity else startActivity(ActivityA). Is that a good way of handling those navigations? How can I directly resume via code an instance of an activity?
Or is there another way to do this in a better way?
Thanks in advance!
greetings,
faiko
Your not going to be able to "cache" an activity once its off the stack. Activities are very quick to start, Im guessing its your database stuff that is slowing you down. That you could do something about.
In theory, if you knew the user was going to click on entries multiple times going from A -> B, you might want to just load the DB stuff into memory in Activity A, and then send it via Parcel into B. Then when you go back to A, its still in memory, and it will be to go back to B instantly.
If you are unsure of whether this is true, try debugging it and stepping through. You will see the activity is launched fairly quickly, but you need to identify which operations are lagging. From your description above it is probably your database calls, but it could be other things like network calls, or other long standing calls
The life cycle of android activities makes it not possible to start a new intent but keep the old state.
You should save the state of the activity by saving the fields and restore it to this state when needed.
You cannot resume an instance of an activity in the scenario that you have posted. Because due to the android lifecycle, when you press the back button on activity B that activity is destroyed, with all its states and information.
One option to get the information to persist is to extend the Application class and save the information into some variables inside the application class. Although alot of what you do even then can be garbage collected if the system needs the memory. I dont believe there is any good way to have that information persist through the activities even using Jameo's solution, if activity A is killed then if you return to Activity A from activity B then that activity is reloaded and the database access has to happen again.
I have 2 activity.
Activiy A will list links to download.
Activity B has a listview of download item.
When I click the link in activity A, how to send the link to activity B to download without change activity A (while activity B still downloading on background) ?
You need to understand that Activities Dont need any result to work, activities need data. And Activities can use these data to load contents of its. And there is no use of this data into activity untill its into background. SO Here is solution:
Create some Data ArrayList or Flag, Global to the application.
Changes this Data into Second activity, which is in forground, and want to notify about some result.
When First Activity which is in background, and want to listen results, check for changes into data in onResume method, and on change load new contents.
My approach would be:
Activity A: Shows a list of items to download.
Service B: Downloads the item in the background. Maybe you can queue
multiple download items.
File C: When you finish downloading something you should save that
fact in a file.
Activity D: When this activity starts it should read 'File C' and
display its contents.
You can't really send data to an Activity without starting it. When an Activity is not visible it is pretty much asleep.
You should read this: Application Fundamentals, read it many many times ... then read it again. I still go back and read it after years of working with Android.