5

I am new to Android Development. Sorry for a dumb question.

I need to check several http resources (resource1, resource2... etc) and check if they are up. If resource 1 is unavailable, then the app needs to check if internet is up (probably ping google?) and then if the connection is actually working it needs to check all the other resources and place the information about what is down to the notification drawer.

It's pretty straightforward to do it with AsyncTask and HttpURLConnection for one resource but i don't quite understand how to follow execution logic with async calls (resource1 -> google -> resource2 -> gather info in one place -> display notification). What is the best practice for it?

4 Answers4

9

@FD_'s answer is valid but I think there is a better way that avoids the horrors of the Async Task. For the record I upvoted FD_'s answer as it is valid I am just pointing out another way.

So I would make a result object. This can be used to work out what happened when you tried to communicate with the various services. You could have something like

public class ResponseResult {

    public String displayName; // so we know what this was all about e.g. "google request"
    public boolean success;
    public String message;
    public int httpStatusCode; //useful to help workout what went wrong e.g. 500, 302 etc.

}

You could then use something like the Android Volley Library that is better than an AsyncTask as it uses a RequestQueue in another thread, which survives the Activity lifecycle better. It also might make your code a little easier to read/manage.

You can read a little about Volley Vs AsyncTask here - Volley and AsyncTask

Once you have issues all your requests and put the results in an Array or List, you could then iterate over them to print the result.

You can get Volley from here https://android.googlesource.com/platform/frameworks/volley

Additional Info

You might also find this inforgraphic from Robospice to be useful as it helps to explain the drawbacks of an AsyncTask.

https://raw.github.com/octo-online/robospice/master/gfx/RoboSpice-InfoGraphics.png

Another implementation

You may find this implementation is not suitable but it makes some sense and would produce even less code.

You could write some server side code to do the checks for you and return an XML/JSON array of result objects. This has the advantage of a single request to a hardwired server with a more reliable connection, that possibly could make the requests in a shorter space of time.

Your Android device would only issue a single request to the server and then process the result array per my other method above.

The major drawback is that this would introduce another set of code and additional hardware.

Community
  • 1
  • 1
Graham Smith
  • 25,627
  • 10
  • 46
  • 69
  • sounds great! the only thing with the voley -- i need to show notification when all requests are finished, but they are async. so how to check if all are finished? or am i missing something again? – Fyodor Dostoyevsky Feb 08 '14 at 22:38
  • How would you do this with AsyncTask? It is the same issue. You would either chain the logic (might get a bit messy and a poor separation of concerns), or you could count the number of objects in your array on each response in Volley, if there are an equal number of result objects to requests then you have done, or you could check if the RequestQueue's pending requests is empty when each request completes. There are probably other options too. – Graham Smith Feb 08 '14 at 22:46
  • in AsyncTask(as suggested by FD_) i would probably just do the requests one after another in doInBackground. This will be okay since it's already in the background thread and my task is simple. But I need to look into Volley, it seems quite promising. Thanks for your reply, I am new to Android and the huge problem is that it lacks good "best-practices" reviews and examples in the docs. Many things change from version to version, many proposed out-of-the-box solutions are unusable and each built-in function has its 3rd party lib. :) Also there's so much outdated info around. – Fyodor Dostoyevsky Feb 08 '14 at 23:01
  • You could use my other suggestion, write a simple server script and call that via Volley. Then you would simply get an array back. I still would say there is a small possibility of a faster load time, especially on 3G, when using a server. – Graham Smith Feb 08 '14 at 23:04
3

I would encourage using Volley library for that purpose also. Check past Google IO 2013 interesting video about it.

Advantages of using Volley:

  • Volley automatically schedule all network requests. It means that Volley will be taking care of all the network requests your app executes for fetching response or image from web.
  • Volley provides transparent disk and memory caching.
  • Volley provides powerful cancellation request API. It means that you can cancel a single request or you can set blocks or scopes of requests to cancel.
  • Volley provides powerful customization abilities.
  • Volley provides Debugging and tracing tools

enter image description here VIDEO: Google I/O 2013 – Volley: Easy, Fast Networking for Android

**source*: http://www.technotalkative.com/android-volley-library-example/


On the other hand, once one of those resources is unavailable, you don't have to ping google as you said. Android API has facilities to check whether your mobile is connected to the Internet; something like this would be enough:

private boolean isConnectedToInternet() {
  return (((ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo() != null); 
}
Filipe Brito
  • 5,329
  • 5
  • 32
  • 42
GoRoS
  • 5,183
  • 2
  • 43
  • 66
1

Just perform all your logic and internet operations in one place, in the same AsyncTask. Create a class that holds all result information and implement your AsyncTask to return (eg send to a delegate/listener/call main thread method) an instance of that class.

FD_
  • 12,947
  • 4
  • 35
  • 62
0

If you like to execute your async task using similar syntax as Jquery's $ajax, this article shows you how to do it. With very little code in the article and Java 8's lambda expression, you will be able to write your async code like this:

 Async.run(() -> {
       //code will be executed on a background thread
       MyAPI api = new MyAPI()
       return api.loadData();
   })
   .whenComplete((data) -> {
       //back on UI thread, update UI using data returned
   })
   .onError((ex) -> {
       //handle exception on UI thread  
   })
   .execute();
Changhong
  • 121
  • 1
  • 6