I have an android app widget that gets some information from the internet when it is first launched.
More precisely it launches a service that asynchronously does a network call. At the end of that network call, in the UI thread it updates the remoteview for the widget with new information.
Touching particular parts of the widget loads an activity which does check to see if the network call stored anything, but that is a conditional statement based on the size of the network call response, if that object doesn't contain the right things then it won't load that.
My problem is that touching the widget doesn't seem to load the activity UNTIL the asynchronous network call finishes. And this doesn't make since to me because that is a separate thread.
There never seems to be a circumstance where my activity gets to even check the condition for an empty object. Instead, I touch the widget, and that seems to be put into a queue, so when the network call finishes it then loads my activity and displays information about that network call.
Why is this happening? Is it something about how I update my remoteView? My views have listeners on them from when they are first placed on the launcher screen in the onUpdate method of the widget. Thanks
Related
The question is more conceptual than coding-related.
I have an app with Activity A and B.
I call an AsyncTask from Activity A, while the call is being made, I don't want to block the user showing the progressdialog, so my user can freely move around the application without getting bored of waiting.
Now, the query is AsyncTask or lets say a Service is being called from Activity A which is responsible for downloading some kind of data from the server. While the call is being made, the user has changed the Activity and Activity A has gone to background.
Now, while the user is freely moving around the application, he just wants to come back to Activity A to check the download status,(which is something lets say I set some data to my TextView).
Now the question is, once the download is over , while my Activity A is still in background, my UI should be updated while Activity is still in background. This way the user feels he gets the data before he switches to Activity A.
Is this possible, if so how?
Summarizing my question, can I update the UI of an Activity while it is still in background with the Asynctask or Service which the Activity invoked to fetch data from server.
One post suggested that ideally I need to update the **UI in onResume(). My question is, is this the only approach?
once the download is over , while my Activity A is still in background, my UI should be updated while Activity is still in background. This way the user feels he gets the data before he switches to Activity A.
It isn't possible. You see, the Activity has to pass through the onCreate() and onResume() callbacks for the UI to be changed.
Also, you should be using a bound Service to update the Activity when it returns to the foreground.
onResume() would be the best approach. You may save the changes in a SharedPreferenes or Pass the data using Intent and show the changes before the UI is visible.
Another approach would be running a service and checking if the activity is visible. If its visible immediately update the UI or wait until user visits the activity. To check if the activity is currently visible see here,
How to check if activity is in foreground or in visible background?
what would be the best way to continue the current Activity once its internal BroadcastReceiver onReceived has been called.
is it possible to start another thread from within the onReceived() method, and also can I start a AsyncTask inside the onReceived() ?
is it possible to start the same activity again from within the onReceived method?
thanx
Please note that an Activity does not survive a screen orientation change -- it gets re-created along with the View hierarchy. From the MVC viewpoint, an Activity is a Controller. Data that must survive an orientation change must go to the Model.
If you keep a reference to the Activity that has gone from the screen due to orientation change, that's a resource leak, and if the Activity receives the result of some AsyncTask, that's also a waste of CPU time and battery power.
Having said that, Activity defines runOnUiThread (Runnable action) which most likely is not what you really need, but it will at least work.
I mean, after the receiver's method is called, the normal cycle continues (reaction on events etc.), so you just need to react on the event reported to your BroadcastReceiver and reach the closing brace of the function.
If you ask if you can rely on that the same instance of SomeActivity will be shown when a long operation completes, the answer is no. For example, the user starts a long operation, then changes the screen orientation. The first SomeActivity, the one that started the long operation, will not be shown when the long operation completes.
in my app, i'm uploading some files that can take up to several minutes. i'm thinking of a way to notify the user about activity going on passively by adding a progress bar in my custom title bar. what i want to do is have every activity, each which uses the custom titles, appear with the progress bar until the thread finishes and does a callback which would make invisible the progress bar. can something like this be accomplished?
what seems to make this impossible is that if the user is in an activity with the view loaded, the thread finishing callback would have to manipulate the loaded view resources to disable the progess bar which doesn't seem feasible. are there any suggestions to accomplish this or alternative solutions in keeping a global and passive indication of something going in the background?
You can use a service to achieve this. Services
Basically how it would work, is you bind to the service in each activity when you create the activity. You use this service to start your upload method.
When you bind to the service you pass a handler, which is then used to update your UI in that specific activity. The service will never directly affect the UI (it will be running on a separate thread) instead the handler passes a message back to the UI thread with data in a Bundle, such as upload progress, or a bool to say it's finished.
I am developing an appwidget that uses the RemoteViews to display a ListView. For simplicity's sake, I will give an analogy of the appwidget's functionality:
The user will select to add the appwidget to the home screen. Upon selecting the widget, a configuration activity is launched and the user selects from one recipe from a list of recipes.
Upon selecting the recipe from the configuration activity, the configuration activity broadcasts the AppWidgetManager.ACTION_APPWIDGET_UPDATE intent. This intent received and handled in the onReceive method of my AppWidgetProvider class. From here the RemoteView is instantiated and passed into the AppWidgetManager.updateAppWidget() method. This proceeds to fill in the ListView of ingredients.
This all works as expected, except when I attempt to manually update the ListView from the appwidget. I have set a PendingIntent to re-launch the configuration activity, which also works. Unfortunately, the call to AppWidgetManager.updateAppWidget() does not get called instantly as it did when being launched upon adding it to the home screen and the ListView does not get updated. The update does get called, however, after scrolling down the list a ways (until it gets passed the number of rows it has loaded in its cache, I reckon). This fires off my FlightBoardAppWidgetService and ViewsFactory as it should. It is almost as if the updateAppWidget is getting put into some lazily-loaded queue. I tried to look at the Android source code to see how AppWidgetManager.updateAppWidget() is coded, but it appears to be hidden.
tl;dr: AppWidgetManager.updateAppWidget() does not always get called instantly, what gives?
Is there any way to get the ListView to update when it is actually called? What am I doing wrong? Thanks!
Well, I ended up solving the problem finally. It is somewhat of a hack, but I ended up solving the problem by declaring a refresh broadcast and an update broadcast. Each time I want to update the widget I call updateAppWidget(), and then from the function that receives and handles this broadcast, I launch another broadcast that calls notifyChanged. This works all of the time!
I read a lot about handling rotation in android applications, but I still have so many questions and need to much to understand.
Let me explain my problem or implementation, that I'm using now in my application.
If an activity will be opened, a get request will be sent to server. This request will be executed in a Thread (new Thread(...)) and if request was completed, activity's ui will be refreshed.
But what should I do, if the user rotate his device?
By default, the activity will be destroyed and request will be started again and start a new thread, but the thread of destroyed activity may be still running.
I guess, it's a quite wrong way, I have now.
But what is the best approach, to handle this?
Probably is the best way to forbid rotation, but what If I don't want that?!
May be it's the second part of my question:
I saw a video form Google IO. Mr. Dobjanschi suggested to use services and to store retrieved data in content provider. So, probably I can use a service for executing my requests. But should data be replaced every time the get request was completed?!
Well dont know exactly how its done, You can try saving the instance and retrieving the same when config changes with following methods:
I have read about them but haven't really implemented them yet. I hope it can give you some start.
#Override
public Object onRetainNonConfigurationInstance() {
return(myServerThread);
}
private void restoreServerFunctions() {
if (getLastNonConfigurationInstance()!=null) {
myServerThread=(Thread)getLastNonConfigurationInstance();
}
}
You can specify that the activity handles the rotation itself. This is done through adding:
android:configChanges="keyboardHidden|orientation"
in the tag of the activity inside your android manifest. You don't have to actually handle the rotation but this will tell android to not destroy your activity. The base activity class will handle all the rotating of the user interface for you and your thread will be executed correct.
A small side note: if you are doing only a small server task use AsyncTask to execute the call to the server in the background instead of creating a thread. This will minimze some of the programming effort you need to communicate the results from the thread to the activity and update your UI.
One easy way, though I've never tried it. Instead of refreshing the current UI, when the thread finishes, start a new Activity with the just downloaded content. So first, you start an Activity with a blank page (or just the page's frame), then you rotate the blank page as much as you like, then the downloading Thread spawns a new Activity, replacing the blank page Activity with the loaded content page using the current orientation.