Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Catch Exception from child activity in Parent activity

Tags:

android

I've been wondering if it's possible to stop a crash in an Android App by capturing said crash in a parent activity.

Lets say I cause a Fatal Exception in the onCreate Method of a child activity, will I be able to capture that exception in anyway? Or will the app crash no matter what I try?

Here is an example of what i mean:

Main.java

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.ly_main);
    // My Main activity starts
    try{
        // Call the next activity
        Intent intent = new Intent(getApplicationContext(), Child.class);
        startActivity(intent);
    }catch(Exception e){
        Log.wtf("Exception_WTF","Exception from child activity woohoo \n "+ e.toString());
    }

Child.java

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.ly_child);
    // Create exception... for science
    int a = 0;
    a = 1/a;
}

This does not work. The child activity dies and takes the parent with it.

Will it be possible to do it via startActivityForResult?

Thanks,

Edit: I don't need the crash data, i just want to know how can i avoid the app crashing.

Looking around i found: Using Global Exception Handling on android

which includes this piece:

   Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
        @Override
        public void uncaughtException(Thread paramThread, Throwable paramThrowable) {
            Log.e("Alert","Lets See if it Works !!!");
        }
    });

That Let me log the uncaughtException, avoiding the "Crash", nevertheless, the App went blackscreen and stopped responding...

Edit 2: After a lot of reading (thanks to user370305) in the thread How do I obtain crash-data from my Android application?

I've reached a dead end, either I handle the uncaughtException and call defaultUEH.uncaughtException(paramThread, paramThrowable); so the app Crashes, or i don't call defaultUEH.uncaughtException, the app doesn't crash, but doesn't respond either... Any ideas?

final Thread.UncaughtExceptionHandler defaultUEH = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
    @Override
    public void uncaughtException(Thread paramThread, Throwable paramThrowable) {
        Log.e("Alert","Lets See if it Works !!!");
        defaultUEH.uncaughtException(paramThread, paramThrowable);
    });
like image 517
RdPC Avatar asked Jan 15 '14 13:01

RdPC


3 Answers

Hope I understand correctly what you want. You can look at FBReaderJ 's source code, it is an real world example to deal with your problem. They can do it very well: whenever app has error, they will show the error report dialog to user and they can filter the error by reading Throwable information.
For example, take a look at BookInfoActivity, they registered the Exception Handler like this:

Thread.setDefaultUncaughtExceptionHandler(
        new org.geometerplus.zlibrary.ui.android.library.UncaughtExceptionHandler(this)
    );

then the UncaughtExceptionHandler class will handle errors:

  @Override
public void uncaughtException(Thread thread, Throwable exception) {
    final StringWriter stackTrace = new StringWriter();
    exception.printStackTrace(new PrintWriter(stackTrace));
    System.err.println(stackTrace);

    if(myContext != null && myContext instanceof Activity){
        ((Activity)myContext).finish();
        return;
    }


    // filter the error by get throwable class name and put them into 
    // intent action which registered in manifest with particular handle activity.
    Intent intent = new Intent(
        "android.fbreader.action.CRASH",
        new Uri.Builder().scheme(exception.getClass().getSimpleName()).build()
    );
    try {
        myContext.startActivity(intent);
    } catch (ActivityNotFoundException e) {
    // or just go to the handle bug activity
        intent = new Intent(myContext, BugReportActivity.class);
        intent.putExtra(BugReportActivity.STACKTRACE, stackTrace.toString());
        myContext.startActivity(intent);
    }

    if (myContext instanceof Activity) {
        ((Activity)myContext).finish();
    }

        // kill the error thread
        Process.killProcess(Process.myPid());
    System.exit(10);
}

Hope this can help.

like image 77
ductran Avatar answered Nov 10 '22 06:11

ductran


Activities in Android must be managed independently since they have their own lifecycle. So, catch exceptions just within the activity producing them.

If your activity requires interaction to return to a previous user activity, finish the activity which is catching the exception (child) and let the previous activity (parent) having knowledge of the result. See Starting Activities and Getting Results as a method that communicates parent and child activities each other.

like image 6
caligari Avatar answered Nov 10 '22 08:11

caligari


Crashes need to come from some particular point in the code. You can filter out the conditions that cause the crash with an if statement in the child and then throw the exception. The parent will have the try {} catch {} statements around the call to its child so the exception is handled in the parent. See here. So for your code, I guess the child would look like

import java.io.TantrumException;

public class Child throws TantrumException() {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.ly_child);
    // Create exception... for science
    int a = 0;
    if (a == 0)
         throw new TantrumException("Arrrggghhh!");
    a = 1/a;
    }
}

Sorry, couldn't resist it :)

Seriously, catching global exceptions sounds kind of dangerous because you don't know where it is going to come from but have decided in advance how to handle it and besides, looking at your code, no matter what the call to the child will terminate.

like image 1
Daniel Wong Avatar answered Nov 10 '22 08:11

Daniel Wong