How to display error messages to user in AsyncTask in Android? - android

I am using AsyncTask to get the data form a web service that I created. Now I want to display proper error messages to user like if the Internet is not available it will display toast for that similarly if server is down it will display toast for that. I want to set a string with error like "server is down" or "internet problem occured" in doInBackground() and display Toast in onPostExecute() but I want to know if my server is down that what exception is thrown? and if my server is active but during transfer internet is disconnected so what exception is thrown ?

Probably modelling the response is the best and easiest way.
For example,
you can compose a model from the data you got such as:
class ApiResponse {
public final String responseString;
public final Throwable error;
public ApiResponse (String responseString,Throwable error){
this.responseString = responseString;
this.error = error;
}
}
Then, you can bind response or error to that model and return from doInBackground();
Pseudo code :
class ApiAsyncTask extends AsyncTask<Void, Void, ApiResponse> {
....
protected ApiResponse doInBackground() {
try {
//callApi and get response, if success pass null in error
return new ApiResponse(responseString, null)
} catch (Exception e) {
e.printStackTrace();
//otherwise pass that error
return new ApiResponse(null, e);
}
}
protected void onPostExecute(ApiResponse apiResponse) {
//now just need to check if error is null
if (error == null) {
String json = apiResponse.responseString;
//parse response
} else {
//get error and check with instanceOf
Throwable error = apiResponse.error;
if (error instanceOf SocketTimeoutException){
//show timeout error
}
else if (error instanceOf SomeXYZException){
//handle that exception
}
}
}
}
This is just an example. You can put anything you want in ApiResponse and compose model of that data. (such as status code got from api, generated pojo class of json response by some converter etc. anything). Once you have the data bounded, you can use it in onPostExecute() as it will always be running on your UI thread. Note that Third type param Result of AsyncTask is built for that by definition : AsyncTask<Params, Progress, Result>.

Catch exceptions of your doInBackground() to string and than, depends what you need, you can show toast message from onPostExecute() method, something like this:
#Override
protected Void doInBackground(Void... arg0) {
try {
// do you stuff here
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
response = "UnknownHostException: " + e.toString();
} catch (IOException e) {
e.printStackTrace();
response = "IOException: " + e.toString();
} finally {
...
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
protected void onPostExecute(Void result) {
if (response.contains("IOException: java.net.ConnectException:")) {
Toast.makeText(getApplicationContext(), "YOUR TEXT HERE", Toast.LENGTH_SHORT).show();
mProgressDialog.dismiss();
}
else if (response.contains("IOException: java.net.SocketTimeoutException:")) {
Toast.makeText(getApplicationContext(), "YOUR TEXT HERE", Toast.LENGTH_SHORT).show();
mProgressDialog.dismiss();
}
else if (response.contains("IOException: java.net.SocketException:")) {
Toast.makeText(getApplicationContext(), "YOUR TEXT HERE", Toast.LENGTH_SHORT).show();
mProgressDialog.dismiss();
}
}
Of course, this is yust an example, but you could see how that can be worked out.

Related

OnPostExecute Method is Executing before Doinbackground Fetching Data from Server To Local

In my Android async task class, I'm fetching data from an Azure server to local database inside DoinBackground method
But before finishing the DoinBackground method, it's executing the OnPostExecute method
Inside OnPostExecute method I am disabling the ProgressBar
Help me to solve this issue.
My code:
public class AsyncTaskSync_UserGroupMappingTableClass extends AsyncTask<String, String, Boolean>
{
{
#Override
protected void onPreExecute()
{
super.onPreExecute();
}
#Override
protected Boolean doInBackground(String... values)
{
try
{
mToDoTable_Form5_SPINNER_DataTable456_ServerAzure
.execute(new TableQueryCallback<FormsObjectTable2TaskHopsSPinnerValues>() {
public void onCompleted(List<FormsObjectTable2TaskHopsSPinnerValues> result, int count, Exception exception, ServiceFilterResponse response) {
if (exception == null) {
if (!result.equals("")) {
for (int i = 0; i < result.size(); i++) {
/*Table 5 SPinner Data Table*/
IdValue_TableValue5 = result.get(i).getId();
ImeiStringval1_TableValue5 = result.get(i).getImeINumberValOne();
Spinner_IDStringVal1_TableValue5 = result.get(i).getSpinner_id_StringOne();
Spinner_data_StringVal1_TableValue5 = result.get(i).getSPinner_data_Value_StringOne();
Log.i("From SErver DataBase", " Spinner : " + ImeiStringval1_TableValue5 + " : " + Spinner_IDStringVal1_TableValue5 + " : " + Spinner_data_StringVal1_TableValue5);
Asynxfor_DATAinsert5_SpinnerTable(IdValue_TableValue5, ImeiStringval1_TableValue5, Spinner_IDStringVal1_TableValue5, Spinner_data_StringVal1_TableValue5);
}
} else {
Log.i("Data Retrieval Not Found", "No Data In Server For Specific IMEI......!");
}
} else {
Log.i("SOme Exception", "Data Retrieval From Server FORMTABLE1 Data......!");
exception.printStackTrace();
}
}
});
}
catch (Exception e)
{
e.printStackTrace();;
Log.i("Data Retrieval", "Exception Occur......!");
}
// PrgDialog.dismiss();
return null;
}
#Override
protected void onPostExecute(Boolean results)
{
try
{
Log.i("DONE ", "Data Sync Done Successfully 5 Spinner Values");
PrgDialog.dismiss();
}
catch (Exception e)
{
e.printStackTrace();
Log.i("Exception ", "Post Excecute");
}
}
};
Edit 1
My Logcat message:
// From OnPostExecute first Executing also disabling the Progressbar
DONE: Data Sync Done Successfully Form Master 1
// From Doinbackground
From Server database
The requests you are doing inside doInBackground are made asynchronusly that's means that doInBackground is already execute before you get the TableQueryCallback. In other words It's a thread which is launching another thread. I think you do not need to surround it in an AsyncTask, you could handle your respond on TableQueryCallback.onCompleted() with a Handler or an Interface.

Best approach to make a login screen

I am writing here because this is my last solution of understanding this type of programming.The problem is that I got stuck on what to use to handle the connection to a server and log-in. Should I use async task, handler or thread ? I didn't find a concrete answer stating which one to use, only found that async task is used to download images or other download stuffs.
Until now I have used a thread to connect to the server. The problem I encountered was when I catch the exception ( Putting invalid username/password ) and try to log-in again. ( I needed to "close" the last thread and start one again )
After this I started to use async task but I don't really understand how it should work and I am stuck on a toast of invalid username/password.
private class connectStorage extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
try {
api = DefaultClientFactory.create(host, getUser, getPassword);
if (api.getAuthToken().trim().length() > 3) {
//TO DO LAYOUT CHANGE;
}
} catch (StorageApiException e) {
e.printStackTrace();
Log.i("TEST", "" + e.getMessage());
}
return null;
}
Also, I am 100% sure that calling inflate in the doInBackground method won't work too ( there I wanted to change the activity ).
I am starting the async task on a button press.
When you are using asynctask
You have doInBackground and onPostExecute
So basically get a json or string or boolean as a result from doinbackground
and in onpostexecute check if the login in succesful or not if its succesful save the data from server and start an intent to go to another activity or toast the user that that user login details are wrong and try again.
So your asynctask can be an inner class of your activity class which is login and onClickSubmit button call the asynctask class and on post execute parse the json and according to the result decide what to do
Example:
public class SignInAsycTask extends AsyncTask<RequestParams, Void, String> {
#Override
protected String doInBackground(RequestParams... params) {
return new HttpManager().sendUserData(params[0]);
}
#Override
protected void onPostExecute(String result) {
String[] details = parseJsonObject(result);
if (details != null) {
user.setUser_id(Integer.valueOf(details[0]));
user.setName(details[1]);
if (details.length > 2) {
user.setProfilePic(details[2]);
}
setSharedPreferences();
startActivity(new Intent(Signin.this, MainActivity.class));
finish();
} else {
Toast.makeText(Signin.this, "please try again",
Toast.LENGTH_LONG).show();
}
}
}
public String[] parseJsonObject(String result) {
JSONObject obj = null;
try {
obj = new JSONObject(result);
if (obj.has("success")) {
if (obj.getInt("success") == 1) {
if (obj.has("user_pic")) {
return new String[] {
String.valueOf(obj.getInt("user_id")),
obj.getString("user_name"),
obj.getString("user_pic") };
} else {
return new String[] {
String.valueOf(obj.getInt("user_id")),
obj.getString("user_name"), };
}
} else {
return null;
}
} else {
return null;
}
} catch (JSONException e) {
e.printStackTrace();
return null;
}
}
here my RequestParams are just a object where I stored all the details like url parameters to send etc and the output of the doinbackground is a String and I am parsing it in my postexecute method

AsyncTask slow with OnClick

Goodmorning,
I have a button on my android app that launches a search on the web (through google endpoints) through an AsyncTask. My problem is that the button does not "unclick" until the AsyncTask is completed, which may take several seconds. When the internet connection is slow, this even makes the application crash, in any case the application is completely stuck until the AsyncTask is completed. Now the reason for using AsyncTask was exactly to eliminate this problem, so I don't really get what happens!
Here is the OnClickListener:
SearchListener = new OnClickListener() {
#Override
public void onClick(View v) {
String cname=TextCourse.getText().toString();
if (!cname.isEmpty()){
try {
CollectionResponseWine listavini= new QueryWinesTask(messageEndpoint,cname,5).execute().get();
} catch (InterruptedException e) {
showDialog("Errore ricerca");
e.printStackTrace();
} catch (ExecutionException e) {
showDialog("Errore ricerca");
e.printStackTrace();
}
} else{
showDialog("Inserisci un piatto");
}
}
};
and here is the AsyncTask that is being called:
private class QueryWinesTask
extends AsyncTask<Void, Void, CollectionResponseWine> {
Exception exceptionThrown = null;
MessageEndpoint messageEndpoint;
String cname;
Integer limit;
public QueryWinesTask(MessageEndpoint messageEndpoint, String cname, Integer limit) {
this.messageEndpoint = messageEndpoint;
this.cname=cname;
this.limit=limit;
}
#Override
protected CollectionResponseWine doInBackground(Void... params) {
try {
CollectionResponseWine wines = messageEndpoint.listwines().setCoursename(cname).setLimit(limit).execute();
return wines;
} catch (IOException e) {
exceptionThrown = e;
return null;
//Handle exception in PostExecute
}
}
protected void onPostExecute(CollectionResponseWine wines) {
// Check if exception was thrown
if (exceptionThrown != null) {
Log.e(RegisterActivity.class.getName(),
"Exception when listing Messages", exceptionThrown);
showDialog("Non ci sono vini associati al tuo piatto. Aggiungine uno!");
}
else {
messageView.setText("Vini piu' votati per " +
cname + ":\n\n");
for(Wine wine : wines.getItems()) {
messageView.append(wine.getName() + " (" + wine.getScore() + ")\n");
}
}
}
}
...execute().get() is blocking. It makes UI thread wait for Task to complete.
Don't do get(). Use onPostExecute() to get the result (wines) of task and update the UI.

Android exception handling

I'm having trouble handling an exception called by a method. What I'm trying to do is create an alert dialog whenever an exception is caught (I know how to create the alert dialog). The method throwing the exception is in a different class, which is why I can't create an alert dialog when the exception is caught. See below:-
protected Boolean doInBackground(final String... args) {
try{
ParserLive parser = new ParserLive();
feeds = parser.parse(); // this is the method throwing the exception
return true; //won't return true because it gets stuck here
} catch (Throwable t){
return false;
}
}
Below is the ParserLive class where the method is:-
public class ParserLive {
//variables and constructor
//Below is the method I want to handle
//Ideally I'd like to wrap the code inside this method with a try-catch,
//and put the dialog in the catch statement, but this is not allowed.
public List<Feed> parse() {
//some code
// the following code is throwing the error, when I try to create an alert dialog inside this catch statement it says "the constructor AlertDialog.Builder(ParserLive) is undefined"
try {
Xml.parse(this.getInputStream(), Xml.Encoding.UTF_8, root.getContentHandler());
} catch (Exception e) {
throw new RuntimeException(e);
}
return feeds;
}
}
EDIT
I've edited the above code to include the line of code throwing the following error in LogCat - " java.lang.RuntimeException: org.apache.harmony.xml.ExpatParser$ParseException: At line 1, column 0: no element found
"
protected Boolean doInBackground(final String... args) {
try{
ParserLive parser = new ParserLive();
feeds = parser.parse();
return true;
} catch (Exception e){
log.d("Error", e.getMessage());
yourActivity.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(context, e.getMessage(), 3000).show(); }
});
//Here you can create dialog also
return false;
}
}

Network communication layer. AsyncTask error handling [duplicate]

This question already has answers here:
AsyncTask and error handling on Android
(12 answers)
Closed 9 years ago.
Currently I'm working on implementing network communication layer. And I thought it's good to consult with more experienced Android developers first.
I have a class called WebApiController which is responsible for: making requests and parsing responses, and storing them in the models. WebApiController methods execute on the main thread, so I wrap them in AsyncTasks to take the load out of the main thread. WebApiController methods potentially throws exceptions such as ServerBadResponseException, XmlParserException, etc. And I want to be able to handle them accordingly to the type of error (i.e. show different error messages based on the type of error). So, what would be the best way to notify the onPostExecute about the error type, and nicely handle it there.
Or this:
class SomeTask extends AsyncTask<Void, Void, Params> {
#Override
protected Params doInBackground(Void... voids) {
Params params = new Params();
try {
.....
params._result = .....
} catch (Throwable e) {
params._error = e;
}
return params;
}
#Override
protected void onPostExecute(Params params) {
if(params._error != null){
....
} else {
....
}
}
}
class Params {
public Throwable _error;
public Object _result;
}
Basically the easiest way is to set a return code like "SUCCESS", "FAILURE_XY" and process that in your onPostExecute(). This works also, when you normally would return data...
doInBackground() {
try {
// code
return data;
} catch (Exception e) {
Log.e(TAG, "error description", e);
resultCode = FAILURE;
return null;
}
}
onPostExecute(Data data) {
if (data == null) {
// check resultCode!
} else {
// work with your data
}
}
You can try this (in doInBackgroung method):
try {
........
} catch (final Throwable e) {
runOnUiThread(new Runnable() {
public void run() {
Log.e(TAG, e.getMessage(), e);
Toast.makeText(......).show();
}
});
}

Categories

Resources