What does App do to never crash, done in minutes

Does try catch affect program performance?

First, try catch is used to minimize the scope as much as possible. When no exception is thrown within the try catch scope, the performance impact is small, but when an exception is thrown, the performance impact is multiplied.Specifically, I have conducted a simple test for the following three cases.

  • No try catch

  • try catch but no exceptions

  • There are both try catch es and exceptions.

 fun test() {

        val start = System.currentTimeMillis()

        var a = 0

        for (i in 0..1000) {

            a++

        }

        Log.d("timeStatistics", "noTry: " + (System.currentTimeMillis() - start))

    }



    fun test2() {

        val start = System.currentTimeMillis()

        var a = 0

        for (i in 0..1000) {

            try {

                a++

            } catch (e: java.lang.Exception) {

                e.printStackTrace()

            }

        }

        Log.d("timeStatistics", "tryNoCrash: " + (System.currentTimeMillis() - start))

    }



    fun test3() {

        val start = System.currentTimeMillis()

        var a = 0

        for (i in 0..1000) {

            try {

                a++

                throw java.lang.Exception()

            } catch (e: java.lang.Exception) {

                e.printStackTrace()

            }

        }

        Log.d("timeStatistics", "tryCrash: " + (System.currentTimeMillis() - start))

    }



     2021-02-04 17:10:27.823 22307-22307/com.ted.nocrash D/timeStatistics: noTry: 0

     2021-02-04 17:10:27.823 22307-22307/com.ted.nocrash D/timeStatistics: tryNoCrash: 0

     2021-02-04 17:10:28.112 22307-22307/com.ted.nocrash D/timeStatistics: tryCrash: 289 

Two conclusions are obvious from the log

    1. When there are no abnormalities, there is little effect of having or not having a try, both of which are 0 milliseconds.
    1. 289 times lower performance in case of abnormalities

Of course, the above tests are extreme cases in order to zoom in and face the problem directly, so try catch should minimize scope in the future.

How do I collect exception logs?

This question is already answered at the beginning of this article by inheriting Thread.UncaughtExceptionHandler and rewriting uncaughtException().Note: Initialization needs to be called in Application

class MyCrashHandler : Thread.UncaughtExceptionHandler {

    override fun uncaughtException(t: Thread, e: Throwable) {

        Log.e("e", "Exception:" + e.message);

    }



    fun init() {

        Thread.setDefaultUncaughtExceptionHandler(this)

    }

} 

Log collection and uploading can now be done in the uncaughtException() method.

Why does an exception stop the program?

This problem requires an understanding of Android's exception handling mechanisms. Before we set up the Thread.UncaughtExceptionHandler, one will be set by default. Refer to ZygoteInit.zygoteInit()

 public static final Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,

            String[] argv, ClassLoader classLoader) {

        if (RuntimeInit.DEBUG) {

            Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");

        }



        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");

        RuntimeInit.redirectLogStreams();



        RuntimeInit.commonInit();

        ZygoteInit.nativeZygoteInit();

        return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,

                classLoader);

    }



 protected static final void commonInit() {

        if (DEBUG) Slog.d(TAG, "Entered RuntimeInit!");



        /*

         * set handlers; these apply to all threads in the VM. Apps can replace

         * the default handler, but not the pre handler.

         */

        LoggingHandler loggingHandler = new LoggingHandler();

        RuntimeHooks.setUncaughtExceptionPreHandler(loggingHandler);

        Thread.setDefaultUncaughtExceptionHandler(new KillApplicationHandler(loggingHandler));

        ...

} 

You can see that setDefaultUncaughtExceptionHandler() has been set in ZygoteInit.zygoteInit(), which is the process of process initialization.Thread.setDefaultUncaughtExceptionHandler (new KillApplicationHandler);

Callback to KillApplicationHandler.uncaughtException (Thread, Throwable) when an exception occurs in the program

 @Override

        public void uncaughtException(Thread t, Throwable e) {

            try {

                ensureLogging(t, e);



                // Don't re-enter -- avoid infinite loops if crash-reporting crashes.

                if (mCrashing) return;

                mCrashing = true;



                // Try to end profiling. If a profiler is running at this point, and we kill the

                // process (below), the in-memory buffer will be lost. So try to stop, which will

                // flush the buffer. (This makes method trace profiling useful to debug crashes.)

                if (ActivityThread.currentActivityThread() != null) {

                    ActivityThread.currentActivityThread().stopProfiling();

                }



                // Bring up crash dialog, wait for it to be dismissed

                ActivityManager.getService().handleApplicationCrash(

                        mApplicationObject, new ApplicationErrorReport.ParcelableCrashInfo(e));

            } catch (Throwable t2) {

                if (t2 instanceof DeadObjectException) {

                    // System process is dead; ignore

                } else {

                    try {

                        Clog_e(TAG, "Error reporting crash", t2);

                    } catch (Throwable t3) {

                        // Even Clog_e() fails!  Oh well.

                    }

                }

            } finally {

                // Try everything to make sure this process goes away.

                Process.killProcess(Process.myPid());

                System.exit(10);

            }

        } 

In direct observation finally, Process.killProcess (Process.myPid()) is called;System.exit(10);,The process end logic is triggered, which causes the program to stop running.

If an exception occurs, will the program stop running?

  • First of all, we need to decide what the concept of stop-running is. There are two main situations.

    1. Program process exits (flashback to standard)
    1. Program process persists, but clicks do not respond to user events (benchmark ANR)

The first is a good understanding, that is, we exit the process of the above process, and we focus on the second case, where the process persists but cannot respond to user events.

I want to popularize a little bit of knowledge here. Why can the Android system respond to all kinds of (human/non-human) events?

  • This involves the concept of Handler, which actually relies on the mechanism of Handler Message Looper to run the whole operating system. All the actions are assembled into a Message Sage message. Looper then opens a for loop (dead loop) and takes out a message for Handler to process, and Hander process completes responding.Our actions are also answered, and the sooner the impact, the smoother the system will be.

This is just a description of the Handler mechanism. If necessary, you can see this blog authorized to Hongyang. It's really rough, so you can see the whole process in a minute.

5 minutes to learn about Handler mechanism, the wrong scenario for using Handler

OK, what process do we come back to continue to pull, but we can't respond to user events?In fact, it was already mentioned when we just described Handler.An exception occurred, causing the main thread's Looper to exit the loop, and how to respond to you if they both exit the loop.

The above two situations are clearly analyzed, so let's focus on how to solve these two problems, the first one.

If there is an exception, how can I prevent the process from exiting?As mentioned above, the process exits when the default KillApplicationHandler.uncaughtException() calls Process.killProcess (Process.myPid());System.exit (10).Prevent exit, don't let KillApplicationHandler.uncaughtException() be called?

As we described at the beginning of this article, we just need to implement a Thread.UncaughtExceptionHandler class by ourselves and initialize it in Application

class MyCrashHandler : Thread.UncaughtExceptionHandler {

    override fun uncaughtException(t: Thread, e: Throwable) {

       Log.e("e", "Exception:" + e.message);

    }



    fun init() {

        Thread.setDefaultUncaughtExceptionHandler(this)

    }

} 

The logic above sets Thread's default UncaughtExceptionHandler, so when a crash occurs again, ThreadGroup.uncaughtException() is called, and then handling the exception will go to our own MyCrashHandler implementation, so we won't quit the process.

Last

Today's sharing about the interview is here, or that sentence. There are some things that you should not only understand, but also express well and allow the interviewer to recognize your understanding, such as the Handler mechanism, which is a question that must be asked during the interview.There's some obscure point, maybe it's just living in an interview and you won't use it at all in real work, but you need to know what it is.

Finally, here is a small edition to share the 19-year interview questions of Tencent, Headlines, Ali, Meituan and other companies that compiled the above technical system maps. It organizes the technical points into videos and PDF s (which actually took a lot more effort than expected), including the knowledge context + many details. Due to the limited space, this part is shown as a picture.

There are Advanced Architecture Technology Advanced Brain Map, Android Development interview materials, Advanced Architecture materials to help you learn to improve, also save you time to search for information online to learn, can also be shared with friends around you to learn.

CodeChina Open Source Project: "Android Learning Notes Summary + Mobile Architecture Video + Factory Interview True Topics + Project Actual Source"

[Android Core Advanced Technology PDF Document, BAT Factory Interview True Question Analysis]

[algorithm set]

[Extend Android Essentials]

[Android Part of Advanced Architecture Video Learning Resources]

Send interview materials**, Advanced Architecture materials to help you learn to improve, also save you time to search for information on the Internet to learn, or share with friends around you to learn.

CodeChina Open Source Project: "Android Learning Notes Summary + Mobile Architecture Video + Factory Interview True Topics + Project Actual Source"

[Android Core Advanced Technology PDF Document, BAT Factory Interview True Question Analysis]

[img-QCnngPIs-1630512956665)]

[algorithm set]

[img-FIdzcheg-1630512956667)]

[Extend Android Essentials]

[img-vp7pV9gj-1630512956669)]

[Android Part of Advanced Architecture Video Learning Resources]

**Android makes video collection even more useful!**Enter BATJ factory etc. (Ready for battle)!Now say that the winter of the Internet, in fact, it is no more than you get on the wrong car and wear less (skills). If you get on the car, you have strong technical ability and the cost of replacing the company is high, how can you be cut off? It is just the end of the business Curd that is eliminated!Now the market is flooded with junior programmers. This set of tutorials is targeted at people who have been working for Android development engineers for 1-6 years and are in the bottleneck. If you want to break through your salary increase after this year, advanced middle-level and senior Android architects are just like fish in water for you. Get them now!

Keywords: Android Design Pattern

Added by raouleduke on Wed, 01 Sep 2021 19:42:03 +0300