Android - Downloading data from the internet >> catch connection errors - android

In my app i connect to a server, which responds with an xml. I parse it with the SAX Parser, and get the data.
The question is:
What is the best way to handle connection issues?
(At this moment if there is no internet connection available the app simply continues showing the ProgressDialog i implemented)

So you basically do (Pseudo code)
ProgessDialog pd = new ProgressDialog(this).show();
Sax.parseStuff();
pd.dismiss();
In this case, wrap the parsing stuff and cancel the dialog on Exception
ProgessDialog pd = new ProgressDialog(this).show();
try {
Sax.parseStuff();
}
finally {
pd.dismiss(); // or cancel
}
You can also do a try { .. } catch (XYZException e ; pd.cancel(); throw e) if you want to process the Exception in a different layer of your app.

As well as following the suggestion of Heiko Rupp, you can also check for the availability of a network connection prior to performing your download. See my post on the subject.

Related

Request a non-blocking server AsyncTask Android Studio?

I'm developing my first robust App in Android Studio is an application that communicates with a remote database, for this I am using the AsyncTask class, also made the request in a separate thread, all this I have already done, the question is that I am using a DrawerLayout and every time a menu item is selected, this gets stuck while the data request to the server is done, as I do to make such request is made the one you see DrawerLayout be hidden.
This is how I am running the AsyncTask class.
BD = new TaskExecuteHttpHandler(service, parametros, CONTEXTO);
String resultado="";
try {
resultado = BD.execute().get();
} catch (ExecutionException e) {
e.printStackTrace();
}
I appreciate the help.

Should I use AsyncTask to establish an XMPP connection?

I am connecting to an XMPP server in Android using Smack. Here is my code:
static void openConnection() {
try {
if (null == connection || !connection.isAuthenticated()) {
XMPPTCPConnectionConfiguration.Builder configuration = XMPPTCPConnectionConfiguration.builder();
configuration.setHost(SERVER_HOST);
configuration.setPort(SERVER_PORT);
configuration.setServiceName(SERVICE_NAME);
configuration.setUsernameAndPassword(new TinyDB(context.getApplicationContext()).getString("username"), new TinyDB(context.getApplicationContext()).getString("password"));
configuration.setDebuggerEnabled(true);
connection = new XMPPTCPConnection(configuration.build());
connection.setUseStreamManagement(true);
connection.setUseStreamManagementResumption(true);
ReconnectionManager reconnectionManager = ReconnectionManager.getInstanceFor(connection);
reconnectionManager.enableAutomaticReconnection();
reconnectionManager.setReconnectionPolicy(ReconnectionManager.ReconnectionPolicy.RANDOM_INCREASING_DELAY);
connection.connect();
connection.login();
}
} catch (XMPPException xe) {
xe.printStackTrace();
} catch (SmackException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
So when I call openConnection() should I do that in an AsyncTask or is that not necessary? I am a little confused.
You should manage your XMPP(TCP)Connection within an Android Service. The service state (running/stopped) should reassemble the connection state: When the service is running the connection should be established or the service should try to establish the connection (if data connectivity is available). If the service stops, then also disconnect the connection.
When i call openConnection() should i do that in an asynctask or that is not neccesary?
Shortly, YES. Everything related with networking should be moved to another thread to avoid blocking main thread. Hence doInBackground() of AsyncTask runs on another thread, which is where you should call that function.
Yes, as the official documentation points it out:
AsyncTask enables proper and easy use of the UI thread. This class
allows to perform background operations and publish results on the UI
thread without having to manipulate threads and/or handlers.
I chose not to use AsyncTask for my smack project after searching around.
its threading model have been quite different between Android version and need to take care about, also after honeycomb, it is single thread, long blocking this will cause issue on the whole device that also use AsyncTask , xmpp and bosh can cause long blocking up to seconds/minutes
AsyncTask has implicit reference to activity and such a long operation will cause memory issues, or easy memory leakage when exception handling is not proper
AsyncTask 's result will be lost if reference activity got reset, but activity in Android can be reset as easy as a simple device rotation or network configuration change, too many save and restore instance to make this usable as every xmpp operation may be long task

Should I launch a Thread to parse some xml?

I'm kinda new to android development, but i'm trying to make a xml parser. I've been using android.sax library, following some tutos, and this works great.
One thing that is making me sceptical, is that I don't actually launch the parser in a separate thread, I just use a handlers to communicate between my parser and my main activity.
Should I parse in a Thread ?
Here's my main activity code :
tv = (TextView)findViewById(R.id.tv);
try {
URL url = new URL("https://www.googleapis.com/shopping/search/v1/public/products?key=AAAAABBBBBCCCCDDDEEEEFFF&country=FR&restrictBy=gtin=5030999075254&alt=atom");
XMLHandler xHandler = new XMLHandler();
Feed feed = xHandler.parse(url.openStream());
if(feed.getTotalResults()==0 || feed.getItems() == null || feed.getItems().isEmpty()) {
Log.w("XMLPARSENull", "No items
}
else {
tv.setText(feed.getTotalResults()+" " + feed.getItemsPerPage() + " " + feed.getStartIndex() + " " + feed.getTitle());
Iterator<Product> it = feed.getItems().iterator();
while(it.hasNext()) {
Log.w("XMLPARSEFeed",it.next().getName());
}
}
} catch(Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.e("XMLPARSEException", "ERROR",e);
}
I don't think that it's the parsing so much as the network operation, as any network request should not be performed in the UI thread. You can either spawn a new Thread or an AsyncTask to perform your network request. Here are some links to help:
AsyncTask
Painless threading
Expensive operations
Designing for responsiveness
Thread documentation
Handler documentation
A simple answer:
If you have connections in your main ( UI ) thread, the user interface will become frozen whilst the thread is used to download the information and parse it. It takes some time for a connection so it may appear to freeze.
Apart from that, android 4.0 now does not actually allow you to call HTTP requests from this thread, it will throw an error which will be seen in logcat before crashing.
It is best practise to use an Async Task here, here is some more information on that.
Information on Async Tasks!
Yes, it is imperative that you move your parsing into a background thread, particularly if your XML is being streamed across the network; otherwise your app is likely to be killed off by the system for blocking the main thread.
You don't have to use a raw Thread, though; Android provides things like ASyncTask to make it a bit easier.
Everything which isn't related to direct interaction with GUI should be moved to separate thread, prefferably AsyncTask if you need interaction with GUI from that thread since Android won't allow accessing GUI from regular Thread class.
http://developer.android.com/reference/android/os/AsyncTask.html

The onLoadResource function sporadically generates not found errors

I have a webview application that uses hooks to execute native java code (ie populate a local db) and to catch these hooks I use the onLoadResource function.
It works as expected, but about 10% of the time I get server log errors of the hook being fired and its clogging up my logs with "not found" errors.
So it basically works like this:
User loads their webview app
In the app they click on of the hooks (http://domain.com/hook/datatopass)
The onLoadResource does its processing and forwards the user to
another page (http://domain.com/home)
The majority of the time it works, but sporadically I get the "ERROR [http://domain.com/hook/datatopass] not found" error.
From what I can tell the user doesn't see any error pages, they get forwarded to the correct place - but I don't know why the onLoadResource doesn't catch every request before it logs an error. Anyone know how to avoid these errors being thrown, and why this is happening?
It seems for me that a Timeout occurs - sometimes.
Have you tried to set the timeout time higher ?
Or have you tried to show an ProgressDialog like below to locate the problem?
public void onLoadResource(WebView view, String url) {
// Check to see if there is a progress dialog
if (progressDialog == null) {
// If no progress dialog, make one and set message
progressDialog = new ProgressDialog(activity);
progressDialog.setMessage("Loading please wait...");
progressDialog.show();
// Hide the webview while loading
webview.setEnabled(false);
}
}

Need an example showing how to do async HTTP requests

Im using a web service, so I want to use an async thread for the HTTP authentication request and another thread later to make additional service requests while my main thread runs.
Would like to see a good example of how to do this and how to show busy messages somehow in main app. How does the main app know when the thread finished? And what if my thread encounters exceptions, how do I deal with that?
HTTP requests are sent later, use the same cookies setup up by the first auth request, so will the later requests pick up the same cookies and just work?
Even better look here for the async part: Is there an accepted best-practice on making asynchronous HTTP requests in Android?
Look at here How to execute web request in its own thread?
AndroidAsync library I wrote to handle this automatically, it will run in the background and reinvoke onto the UI thread:
https://github.com/koush/AndroidAsync
// url is the URL to download. The callback will be invoked on the UI thread
// once the download is complete.
AsyncHttpClient.getDefaultInstance().get(url, new AsyncHttpClient.StringCallback() {
// Callback is invoked with any exceptions/errors, and the result, if available.
#Override
public void onCompleted(Exception e, String result) {
if (e != null) {
e.printStackTrace();
return;
}
System.out.println("I got a string: " + result);
}
});

Categories

Resources