Today I found a wierd problem. What I want is to check server availability (Particularly SSL checking) once application started and display proper message if server is down. This process should work in background and user is able to navigate the app if server has problem (app can works offline).
What I did is simple. In main activity I have
@Override
protected void onStart()
{
super.onStart();
// Check Internet connection
// Check Location sensor
// Check server accessibility
BackendCheck backendCheck = new BackendCheck(this);
if (!backendCheck.execute())
{
displayErrorDialog();
return;
}
}
This is BackendCheck
class:
public class BackendCheck implements Callable<Boolean>
{
private static final String TAG = BackendCheck.class.getSimpleName();
// Thread sleep time
private static final int THREAD_SLEEP = 5000;
// Number of attempts to call an API in order to get response
private static final int MAX_ATTEMPT = 3;
// Current attempt
private int counter = 0;
// The url that should be used in order to get server response
private String mTestUrl;
// App mContext
private Context mContext;
// Server status
private boolean mServerStatus = false;
public BackendCheck(Context context)
{
this(context, "");
}
public BackendCheck(Context context, String url)
{
this.mTestUrl = url;
this.mContext = context;
}
public boolean execute()
{
// Check #mTestUrl and use Feature API if this variable is empty
if (TextUtils.isEmpty(mTestUrl))
{
mTestUrl = PassengerConstants.URL_BASE + mContext.getResources()
.getString(R.string.uri_feature_payments);
}
// Get ExecutorService from Executors utility class, thread pool size is 10
ExecutorService executor = Executors.newFixedThreadPool(10);
do
{
// Increment counter
counter++;
// Submit Callable tasks to be executed by thread pool
Future<Boolean> future = executor.submit(this);
try
{
// Break Do-While loop if server responded to request (there is no error)
if (!future.get())
{
mServerStatus = true;
break;
}
}
catch (InterruptedException e)
{
Logger.error(TAG, e.getMessage());
}
catch (ExecutionException e)
{
Logger.error(TAG, e.getMessage());
}
} while (counter < MAX_ATTEMPT);
// Shut down the executor service now
executor.shutdown();
// Return server status
return mServerStatus;
}
@Override
public Boolean call() throws Exception
{
// Sleep thread for a few seconds
Thread.sleep(THREAD_SLEEP);
try
{
HttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet(mTestUrl);
Logger.debug(TAG, "Attempt (" + counter + "), try to check => " + mTestUrl);
HttpResponse httpResponse = client.execute(get);
int connectionStatusCode = httpResponse.getStatusLine().getStatusCode();
Logger.debug(TAG,
"Connection code: " + connectionStatusCode + " for Attempt (" + counter
+ ") of request: " + mTestUrl);
if (isServerError(connectionStatusCode))
{
return true;
}
}
catch (IllegalArgumentException e)
{
Logger.error(TAG, e.getMessage());
}
catch (Exception e)
{
Logger.error(TAG, e.getMessage());
}
return false;
}
/**
* Server status checker.
*
* @param statusCode status code of HTTP request
* @return True if connection code is 5xx, False otherwise.
*/
private static boolean isServerError(int statusCode)
{
return (statusCode >= HttpURLConnection.HTTP_INTERNAL_ERROR);
}
}
What happens is, When I launch the application splash screen displays. Then after a few seconds mainActivity runs (first code) then - since my server is down (for testing purposes) - I have black screen for 15 seconds (since I set MAX_ATTEMPT to 3 and have 5 seconds thread sleep) and after that I'm able to see UI of mainActivity and my error message.
I expect Callable<> should works in background and I see mainActivity after splashScreen without problem (black screen).
What you think? What problem might be? Thanks.