I'm using RoboSpice and I'm trying to reconnect to pending requests upon rotation. I'm doing most of the RoboSpice work in a fragment. I'm trying to figure out how to detect which pending request got connected.
Here's my scenario. I have two network calls that are executed in succession, let's call them Operation A and Operation B. I'm displaying a indeterminate progress bar saying something like "Performing Operation A" and "Performing Operation B". This is all fine.
Upon rotation, I'm trying to reconnect to the two potentially pending request, but not sure how to figure out what to display in my progress bar details. I can only detect misses, but not successful attachment to pending requests.
Any ideas on how to do that? If I use a generic message like "Loading..." in my progress bar, then I guess I could go with a synchronized reference counting type approach where I hide the progress bar if it ever gets to zero, but I was hoping there's an easier way. Any thoughts?
Related
I feel that the answer to this question is too obvious, but part of me still wants to ask it anyway.
I am creating an Android app that makes several HTTP POST/GET requests using APIs when the app is launched for the first time by the user. All these requests are made by launching Asynctasks within the activity.
For example, there is an activity where athe user has to select an item from a list retrieved from the API. After he selects one, a progress bar is displayed to the user while the app sends the selection to the API to retrieve another list, and in the next activity, the user selects items from this list. Clearly, the user can't go this second list until a response has been received from the server after the app sends it the first list's selection.
In such a case, is there any point in using an Asynctask to send the selection of the first list, since the user is prevented from doing anything (by being shown a progress bar) until a response is received and the next activity is started. Wouldn't it make the code less complex if I just made the API call on the main thread?
I hope this wasn't too confusing.
Thanks
I got your doubt completely. Good question. The root cause of the doubt because you are thinking you don't need to interact with the app till the process completes. But you actually want to. Event the progress bar will freeze if you could do something like it.
Ok, let's just assume you don't even have a ProgressBar. However, handling the different UI components such as Spinners, EditTexts is not the only duty of the main thread. It should define different callbacks in the activity lifecycle. Doing big tasks in main thread will also freeze callbacks like onPause(), onStop() etc. That is why the 'NetworkOnMainThreadException' is being thew.
Basically you cannot call the api on main thread as it will block the UI. Also now Android does not allow it to happen and throws 'NetworkOnMainThread Exception'. Its fine to use Asynctask for any task that takes few seconds and you get the callback in it , which in your case is required before you proceed to next screen.
Best way to do it is by using Networking libraries:
Refer this
https://developer.android.com/training/volley/simple.html
First of all you cannot do netwok call on main thread, it will raise NetworkOnMainThreadException , You can still by pass this exception by adding the couple of following lines in your activity
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
but it is always recommended to perform network operation in background,
else it may cause your app to stop responding, and can result in the OS killing your app for being badly behaved , go through this article once link
Any operation that takes more than a few seconds to perform should be added in a separate thread. All network operations should be performed on AsyncTask or do have a look at RxJava and RxAndroid. To be specific to your operation, any UI Operations during a network call can be performed in onPostExecute. If you're working with thread class then use a Handler.
As others mentioned, if main thread is used for network operation, it would make your app unresponsive.
User may want to start a different flow in your app by starting an activity from menu or action bar whatever is available in your app to start other flow.
I have a requirement in my Android app, that makes an HTTP request to the server to perform a long running task. The architecture on the server is that; the HTTP request returns immediately with a transaction ID. What I need next is to poll the server to check whether the job has completed and once completed show the result to the user.
When the first HTTP task completes I show a UI Fragment which has a progress bar asking the user to wait while the task completes. Ideally, I would like to show the result to the user on the same Fragment once the task has been done. But I would also need to consider situations where the user might press the Home button or move out of the app/screen in some way.
My current solution is:
Poll every 10-15s with some sort of exponential backoff, as long as
the activity is still attached.
The server sends a push notification regarding task completion - but
I'm worried about reliability of this.
Is there a better way to achieve this? If so, what would be a good design pattern for this? Are there any libraries available that handles this scenario?
I'm using Robospice. I want to write some reusable code to stop ProgressBars and ProgressDialogs as soon as pending network requests have cleared for the current activity. However, I'm running into a couple of problems.
I'm watching when requests have completed by instrumenting a custom SpiceServiceListener to call my custom callbacks implemented within each activity. During onRequestAdded(), I show any Progress UI element. During onRequestSucceeded(), onRequestFailed(), and onRequestCancelled(), I check getSpiceManager().getPendingRequestCount() to see if it reaches zero and then hide any Progress UI elements.
The pending request count never reaches zero in my app (at least inside these three methods), but it seems to stop at one. This is true even though I can see from the Retrofit logging that my requests all appear to be completed.
Is the pending request count global or is it specific to the current Activity and its spice manager instance? Is there a better method to watch for all requests finishing within the current activity?
I have an answer. I missed instrumenting onRequestProcessed(), so the number of pending network requests never appeared to reach zero. The pending request count now does reach zero.
I still don't know if the count is global or local to the current activity and its SpiceManager instance, but I'm getting useful results from my new code.
My Widget has two buttons for right and left navigation with in the widget. If I have a set of data then I switch between data using left and right arrow button. To update data I make a Http Call every minute. If http call takes time to return, my button clicks start getting accumulated and get suddenly fired in series after a pause of 7-8 seconds. I am using pendingIntents for buttons and receiving it in broadcast receiver of widget.
Button clicks work fine if HTTP call is fast.
But if HTTP call is slow to return, and I click on let say 10 times on right arrow, while clicking nothing will happen and after 7-8 secs 10 clicks will be fired in a flash.
Please suggest how can I stop my button clicks getting blocked and then getting fired in a row.
Is the slowness of HTTP call the actual reason of buttons getting stuck ?
You should not make HTTP call from your UI thread, so make sure you use an AsyncTask to perform any i/O or networking operation.
AsyncTask
Its probably because your doing the HTTP request on the UI thread which is not a good idea as HTTP request can take time as can other network tasks or I/O tasks, and android will detect this and may present the user with ANR message (App not responding) and ask the user if they want to force close the app.
You would need to run the HTTP request within an ASyncTask that the onclick event would fire. This way, a new thread would be created for the HTTP stuff while the user interface can carry on working and accepting user input instead of locking.
Within an AsyncTask, I am making a REST call to retrieve data. Within that AsyncTask, I may encounter an exception which I would like to package up (the HTTP code) and inform the Activity, which based on the HTTP response code (Timeout, Unauthorized, etc), would display different messages to the user.
What would be the best way to bubble that information up to the Activity for processing?
I have looked at a number of different Android mechanisms such as Notification, Handler, etc but I can't seem to determine a good architectural pattern for this situation.
If the error causes a halt in the users workflow, then you need to obtrusively interrupt using a dialog alert and then direct the user to the fix. If the error does not stop the user, then interrupt unobtrusively using a toast or notification.