Mobile app responsive until client establish connection with server - android

Is there a known / common pattern of how a mobile application should behave from the point it is launched (more the case of fast launch from suspended mode) until the point a connection with the server is establish and ready?
I'll try to explain, when the app comes from suspended mode, the UI is quickly shown, but for the connection it usually takes a bit more time to re-connect with the server.
Even more, a lot of time the app needs to re-login with the server so it will take some more time.
My question is, how responsive should the app be at that time?
Of course blocking the all UI is a bad idea, but should I for example block the buttons that trigger some network activity until the login phase is finished?

I have the EXACT same issue with my App. A secure app that has to ping a server for login credentials after a programmer defined time-out or the user choosing to exit. I've found it to be better, from my very limited experience, to show a simple progress dialog that informs the user the App is connecting to the server for secure logon. My UI isn't blocked completely. The progress bar spins because the login process is always in an AsyncTask(Asynchronous Task). I hope this applies to you in some ways. I choose to make the dialog completely Modal so all other buttons beneath it aren't active. I also inflate my dialog to completely fill the screen to stop anyone who might have just picked up another person's phone from seeing sensitive data on the screen.

You should do the server connection thing on other thread or use GCD.
In that way the main thread will be responsive and it will act accordingly on establishing connection with server.

Related

Codename One - ToastBar when "No connectivity detected"

What is a correct approach to deal with Internet connection unavailability (that is common on mobile devices)?
Maybe it's a big question (or maybe not), however I didn't find any Codename One tutorial / article / video or API to deal with an unstable Internet connection (that is the normality on mobile) without errors or unexpected behaviors. I've found an app (Protonmail) that has a functionality that I would like to replicate in my apps. Please look at the following two screenshot: the first one is taken when the Internet connection is available, the second one when it's not available.
I noted that the ToastBar appears not only when Internet is explicitly disabled, but every time that the server is not reachable. When the "No connectivity detected" message is shown, the app pauses the Internet activity, so no errors are generated (and the messages written by the user are not lost). When the app server returns to be reachable, the ToastBar disappears automatically (without pressing the "RETRY" button).
What is a correct way to implement a similar functionality in Codename One, in a way that is as most as possible independent from the specific app? Is it possible to suspend the Internet activity of a Codename One app and then restore it?
I'm imagining something like this:
the app tries to do a simple request (like a ping) to a server every few seconds, implementing the performBackgroundFetch method;
if there is no response in a fixed time (i.e. three seconds), the Internet activity is suspended and the ToastBar is shown;
if there is response, the Internet activity is restored, the paused or failed downloads are restarted and the ToastBar disappears;
ideally all of this should works also with a BrowserComponent.
You can detect a networking error in the NetworkManager class by using:
NetworkManager.getInstance().addErrorListener(e -> {
// prevents the error from propagating into the ConnectionRequest class
e.consume();
ToastBar.showMessage("Connectivity error, retry?", FontImage.MATERIAL_ERROR,
ee -> ee.getConnectionRequest().retry());
});
As explained here: https://www.codenameone.com/manual/files-storage-networking.html
The toast bar code just prompts in a similar way and offers a retry on the connection request. Notice that this is the generic global approach.
This will not work for things like browser component which connects on its own without "us". In there you will need to handle errors in the JavaScript side.

Is there a way to limit the resources allocated by a Service?

I have an app that has a Service that offloads photos that people are taking to the server.
Specifically, users are sent to the device's native camera to take a photo and then the photo is returned via intent to the app from which they "approve" it.
This act of approval saves it out to the file system and the Service comes along every x seconds, notices files awaiting offload and offloads them.
This all works fine.
However... in situations where there is bad connectivity but enough for the HTTP handshake, the app finds itself in a state where even though the offload is happening in a Service, at the point where the user is coming *back to my app from the photo taking (and Android is delivering the 4-8mb photo back to my approval Activity, my app hangs - sometimes long enough to provoke the "do you want to kill or wait" prompt. Eventually (if you wait) it does succeed in making its way back to the app.
I've verified that this is Network related because when the connectivity is strong (or when the app is in airplane mode - so the upload just fails instantly) everything works perfectly smoothly. The *only time this happens is when the offloader in the Service is hampered by a hinky connection.
So, my question is - what can I do about this? Is there some way I can isolate the Service to not have a larger effect on the app? Is my solution to write a partner app that sits on the device and just looks to offload the files (would that even solve the problem?).
HERE is the report I'm getting when the WAIT/KILL prompt is offered to the user. I'm not sure what to make of it.
The answer turned out to be that Services are actually running on the main Display thread (I was mislead by the fact that when you make an HTTP call in a Service you don't have to run it in a separate thread manually).
http://gmariotti.blogspot.com/2013/03/antipattern-freezing-ui-with-service.html

What is the good practice on android app development integrated with web services?

I have developed android apps, and have a web server application which serves REST style JSON, to the apps.
My apps are strongly dependent on that web services but as traffic gets higher, users' complaint started, as force close problems. I am not sure but maybe my server (AWS small instance) may not answer all requests correctly or in time.
I am planning to retry the web request when a problem on getting json response arise instead giving the error/net-connection alert.
I guess there are many developers who integrates apps with web services, so what is the good practice on handling network problems?
Or is the frequency of such network problems acceptable?
I take about 10-20 problem per day.
I have about 200.000+ web requests per day, for a AWS small instance (1.7 RAM), dedicated to server Tomcat. I analyze the logs there is no clue, no error log. Also the errors are spreaded.
You need to start with analyzing the problem, and determine the root cause or root causes of your issues. You always need to take into account that
a network connection might drop
a users switches from 3G / WiFi
the android devices "thinks" it's connected while in fact it's not
Also, be very sceptical when using the Android ConnectivityManager / NetworkInfo. Only trust it when it states that it is not connected. If it is connected, check it yourself (as sometimes, user is on a hotspot and the only connectivity he has is with a login page).
The application needs to handle all these scenarios properly. The way it's presented to the user depends on the use-case (do you want the user to be informed of the error, do you silently ignore it and just retry, ....)
In terms of retrying webservice connections, there are several ways to implement this :
exponential backoff
periodic rescheduling
event-driven triggering
retry-after moratorium intervals
You need to start by putting sufficient logging both on the client (Android) and on the server (AWS) so that you can analyze the issues and draw the proper conclusions.
I think the answer to your problem lies in the design of your android app.
You need to take into consideration the worst case scenario and redesign your application to take that into account and recover. Dealing with the chaos monkey - jeff atwood.
Personally I never allow an android app to be in a state where it needs to force close. For any or all network connection I assume that the connection is down, lossy, not all data can be retreived and (finally) up and working correctly.
That way my app will degenerate gracefully. If it needs web access it'll make an attempt in a background thread allowing the user to continue using the app, it will cache previous requests and will retry until it gets a connection or gives a nice toast to the end user.

Heavy traffic on server causes app to force close

I have developed an app to communicate with my own server and published it. However, sometimes the app force closes. I know there is no bug in the code because the app works properly most of the time, but sometimes it is waiting for an answer from the server forever. I think this is due to the fact that so many people are using the app, and the app refreshes every 1 second or so, so this heavy traffic causes the server to take a large amount of time to respond. So how do you take care of such a use case? should I have a use case where if the server does not respond after some time you just stop the app and throw a message saying that the server is not responding or something like that?
Right now, your main application is timing out due to server load. If you put your connection details in a thread, you will be able to avoid having that main thread time out. You can check for updated data from the connection thread (through some shared object) and then present a message to the user if the data has stopped.
It sounds like you have your server communication code within your main Activity. Any code running in this Activity will be run in the main UI thread. If your code sends a request to your server, and is then waiting for a response, the main UI thread is blocked until your server responds. The Android OS recognises that the UI thread has effectively hung, and kills your app.
What you need to do is to separate out the UI code in your Activity from the server communication code. You should move this into an AsyncTask or a new Thread/Handler combination. This will allow the UI to remain responsive even when your server is under load.
Documentation for AsyncTask
Designing for Responsiveness
Android Thread Messaging
Thread example

What's good way to display a start up message in an Android app?

All,
I'm developing an Android application that connects to other hardware on start up via TCP (over WiFi) . I'm pretty happy with the software that handles the connection -- it does a good job of establishing the socket connection as well as handling things when the connection is unexpectedly lost.
Unfortunately, my application currently just displays a blank, empty screen until the connection is established, and I expect that this sort of thing may produce unwarranted worry on the part of my users.
I can't figure out how to put up a start-up message informing the user that I have a towel and that there's no need to panic. Can anybody point me to a method for accomplishing this? I'll be happy with just about anything that's legible, whether graphical or textual.
Thanks,
R.
Whatever you choose, you need to get the startup screen displayed and more importantly start responding to UI events before the TCP connection is made - ie, you shouldn't do the TCP connection attempt on the UI thread, as if it takes longer than expected you may get an application not responding error.
Do the networking in AsyncTask (another thread, so it won't block the UI). Then you can display all kinds of progress indicators in the UI.
You could use a ProgressDialog. http://developer.android.com/reference/android/app/ProgressDialog.html

Categories

Resources