How to stop Application with exception and user message - android

I want to throw an exception in Android so that the app is shut down and a the user gets the ability to report this error to the developer.
I put this into a UI class:
throw new Exception("error...");
but I get an unhandled error. When I use RuntimeException it wont crash and end my application.

You can put in try ... catch a messagebox that ask to you customer to send an email to developer and on the response you can shut down your application.
try {
......
} catch (Exception e) {
dialog.setMessage("Your Message " + e.toString() + ". Send Email?");
dialog.setButtonNegativeText("NO");
dialog.setButtonPositiveText("YES");
dialog.show(getFragmentManager(), "NoticeDialogFragment");
}

Create a user defined exception and throw the exception in the catch block..
MyOwnExceptionClass.java
public class MyOwnExceptionClass extends Exception {
private int price;
public MyOwnExceptionClass(int price){
this.price = price;
}
public String toString(){
return "Price should not be in negative, you are entered" +price;
}
}
your working class
public class Client {
public static void main(String[] args)throws Exception
{
int price = -120;
if(price < 0)
throw new MyOwnExceptionClass(price);
else
System.out.println("Your age is :"+price);
}
}

Related

How to fix getResourceID Not found issue in android?

Is there anyone here had an experience with having an error when getting the resourceId in the context?
I am using context.getResourceID() but it says a NotFoundException Error.
I am fetching a layout resource just to be specific.
I already tried cleaning and rebuilding it but I haven't got any luck.
By the way I'm creating a library to be used for creating an Adobe Native Extension.
Here is my sample code:
public class RunVRFunction implements FREFunction {
public static final String TAG = "RunVRFunction";
#Override
public FREObject call(FREContext extContext, FREObject[] args) {
int layoutID;
Intent i = new Intent(extContext.getActivity(), Main2Activity.class);
try {
layoutID = extContext.getResourceId("layout.activity_main2");
} catch (Exception e) {
System.out.printf("getResourceID() failed with error:\n\"%s\"\n",
e.toString());
Toast.makeText(extContext.getActivity(), "getResourceID() failed" +
e.toString(), Toast.LENGTH_SHORT).show();
return null;
}
i.putExtra("layoutID", layoutID);
try {
extContext.getActivity().startActivity(i);
} catch (Exception e) {
System.out.printf("startActivity() failed with error:\n\"%s\"\n",
e.toString());
Toast.makeText(extContext.getActivity(), "startActivity() failed: " +
e.toString(), Toast.LENGTH_SHORT).show();
}
return null;
}
}
Here is the error in logcat:
android.content.res.Resources$NotFoundException: layout.activity_main2
Thanks.

How to display error messages to user in AsyncTask in 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.

NullPointerException (etc) from Parcel.readException

Exceptions that look like this are confusing:
FATAL EXCEPTION: main
java.lang.NullPointerException
at android.os.Parcel.readException(Parcel.java:1437)
at android.os.Parcel.readException(Parcel.java:1385)
at com.yourpackage.ipc.IYourClass$Stub$Proxy.yourMethod(IYourClass.java:488)
at com.yourpackage.ipc.YourClassShim.yourMethod(YourClassShim.java:269)
I found a bunch of related questions for this, but none with the answer to "how do you debug this". So I'm making this Question/Answer.
By looking at the android source here and here you'll see that it can be throwing any of these (the NullPointerException is just what I had):
SecurityException(msg);
BadParcelableException(msg);
IllegalArgumentException(msg);
NullPointerException(msg);
IllegalStateException(msg);
RuntimeException("Unknown exception code: " + code + " msg " + msg);
But what's causing these?
What's going on here is that readException() is checking the IPC byte stream for a header that says that an exception occurred; if it finds one, then it throws a new exception of that type, with the same message, but missing the original stack trace. (It only actually knows a few exception types; anything else gets translated into a base RuntimeException.)
So where's the original exception coming from? Well, somewhere down in the guts of the real implementation of YourClass.yourMethod() -- not in any of the parcelable or IPC code. So go there, wrap the whole method in a try/catch, and log whatever you caught.
(Or set a breakpoint there if you've got remote process breakpoints working.)
I think android SHOULD provide more binder remote exception information
so i modify Parcel.java to wrap more binder remote exception information
public final void writeException(Exception e) {
int code = 0;
if (e instanceof SecurityException) {
code = EX_SECURITY;
} else if (e instanceof BadParcelableException) {
code = EX_BAD_PARCELABLE;
} else if (e instanceof IllegalArgumentException) {
code = EX_ILLEGAL_ARGUMENT;
} else if (e instanceof NullPointerException) {
code = EX_NULL_POINTER;
} else if (e instanceof IllegalStateException) {
code = EX_ILLEGAL_STATE;
}
writeInt(code);
StrictMode.clearGatheredViolations();
if (code == 0) {
if (e instanceof RuntimeException) {
throw (RuntimeException) e;
}
throw new RuntimeException(e);
}
// I replace writeString(e.getMessage()) with writeString(remoteExceptionToString(e))
writeString(remoteExceptionToString(e));
}
static String remoteExceptionToString(Exception e) {
final StringWriter sw = new StringWriter(1024);
final PrintWriter pw = new PrintWriter(sw, true);
pw.println();
e.printStackTrace(pw);
return sw.toString().replace("\n", String.format("\n(%5d %5d): ", Process.myPid(), Process.myTid()));
}
SerializeExceptionSecondService defination:
public class SerializeExceptionSecondService extends Service {
private static final String TAG = "SerializeExceptionSecondService";
public SerializeExceptionSecondService() {
}
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
return mServiceBinder;
}
private final ISerializeExceptionSecondService.Stub mServiceBinder = new ISerializeExceptionSecondService.Stub() {
#Override
public void throwException() throws RemoteException {
// TODO Auto-generated method stub
Log.e(TAG, "throwException");
throw new IllegalStateException("Cause1", new IllegalStateException("Cause2", new IllegalStateException("Cause3")));
}
#Override
public void noThrowException() throws RemoteException {
// TODO Auto-generated method stub
}
};
}
AndroidManifest.xml fragment:
<service
android:name=".SerializeExceptionSecondService"
android:enabled="true"
android:exported="true"
android:process=":second_remote" >
</service>
in this way, the binder exception logcat will look like the below:

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.

Catching numberformatException while parsing to Double

I want to validate input set with some condition.
here i am getting NumberFormatException while pasring the number. I want to throw InvalidInputException if number which was entered in textbox contains anything except numbers.
Now if I'm inputting numbers only then also I'm getting NumberFormatException.
Here is the sample code.
call to validateInput is as follows
try {
if (true == validateInput(name.getText().toString(), number
.getText().toString())) {
// do something
}
} catch (InvalidInputException iie) {
Log.d("#gaurav", "not a valid input" + iie);
Toast.makeText(this, "Invalid input set", Toast.LENGTH_LONG)
.show();
} catch (Exception ex) {
Toast.makeText(this, "Problem while cerating contact", Toast.LENGTH_LONG)
.show();
Log.d("#gaurav", "Problem while cerating contact", ex);
} finally {
// do something
}
ValidateInput() is as follows:
* Name is valid if it starts with an alphabet otherwise not valid Number is
* valid if the entered text is integer only,
* if not valid number/name throws InvalidInputException, otherwise true
* */
private boolean validateInput(String name, String number)
throws InvalidInputException {
InvalidInputException iie = new InvalidInputException();
try {
if (name.isEmpty() || number.isEmpty()) {
Log.d("#gaurav.exception", "input field empty");
iie.addDescription("Input field is empty");
throw iie;
} else {
if (false == Character.isLetter(name.charAt(0))) {
Log.d("#gaurav.exception", "first letter of name is not a letter");
iie.addDescription("first letter of the name is not character");
throw iie;
}
Log.d("#gaurav.exception", "checking number");
Log.d("#gaurav.exception","number is :"+number+":");
Double.parseDouble(number);
}
} catch (NumberFormatException e) {
Log.d("#gaurav.exception", "In numberFormatexception, adding description, re-throwing iie");
iie.addDescription("Number field should contain integer only");
throw iie;
}
catch (Exception e) {
Log.d("#gaurav.exception", "Exception, re-throwing iie");
throw iie;
}
iie = null;
return true;
}
and MyCustomException is as follows
package com.gaurav.contactmanager.model;
public class InvalidInputException extends Exception {
/**
*
*/
private static final long serialVersionUID = 5585822470459144546L;
String description;
public InvalidInputException() {
super();
}
public InvalidInputException(String desc) {
this.description = desc;
}
public void addDescription(String desc) {
description = desc;
}
#Override
public String toString() {
return description + "\n\n" + super.toString();
}
}
Logcat shows something like this:
01-02 02:11:59.310: D/#gaurav.exception(408): checking number
01-02 02:11:59.321: D/#gaurav.exception(408): number is :6666:
01-02 02:11:59.330: D/#gaurav.exception(408): In numberFormatexception, adding description, re-throwing iie
01-02 02:11:59.330: D/#gaurav(408): not a valid inputNumber field should contain integer only
01-02 02:11:59.330: D/#gaurav(408): com.gaurav.contactmanager.model.InvalidInputException
You're trying to do
Double.parseDouble(number);
Which won't work on any input except input which can be parsed to Double.
You might want to do something like
try{
Double.parseDouble(number);
}catch(NumberFormatException e)
{
throw iie;
}
There was some issue in the type/format of the number i was inputting and that was root cause of the problem. Trying to run the same code on other device confirms that it was input type/format issue.

Categories

Resources