Android中的系统ANR(Application Not Responding)异常通常会使得我们很烦恼,为了捕获异常以更友好的界面显示,在Android系统中有Thread.UncaughtExceptionHandler()方法,将异常类处理到线程,通过线程处理异常,继承该类就可以。


以下是具体实现方法:


1:本实例是通过Button触发抛出异常,MainActivity.java代码如下。

package activity.exceptionhandler.com.exceptionhandler;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.util.Log;import android.view.Menu;import android.view.MenuItem;import android.view.View;public class MainActivity extends AppCompatActivity implements View.OnClickListener{    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        initUI();      //  initData();    }    private void initData() {        CrashHandler catchExcep = new CrashHandler(this);        Thread.setDefaultUncaughtExceptionHandler(catchExcep);    }    private void initUI() {        findViewById(R.id.bt).setOnClickListener(this);        findViewById(R.id.tv);    }    @Override    public boolean onCreateOptionsMenu(Menu menu) {        // Inflate the menu; this adds items to the action bar if it is present.        getMenuInflater().inflate(R.menu.menu_main, menu);        return true;    }    @Override    public boolean onOptionsItemSelected(MenuItem item) {        // Handle action bar item clicks here. The action bar will        // automatically handle clicks on the Home/Up button, so long        // as you specify a parent activity in AndroidManifest.xml.        int id = item.getItemId();        //noinspection SimplifiableIfStatement        if (id == R.id.action_settings) {            return true;        }        return super.onOptionsItemSelected(item);    }    @Override    public void onClick(View v) {        switch (v.getId()){            case R.id.bt:{                Thread thread = new Thread(new Runnable() {                    @Override                    public void run() {                        Log.d("abc", "I am a  thread");                        String s = null;                        s.toString();  //抛出NullPointException                    }                }, "thread");                thread.start();            }            break;        }    }}


2:button事件编写完成,上述MainActivity.java通过Button抛出空指针异常,下面编写CrashHandler.java文件处理异常。

package activity.exceptionhandler.com.exceptionhandler;import android.app.AlarmManager;import android.app.PendingIntent;import android.content.Context;import android.content.Intent;import android.os.Build;import android.os.Environment;import android.os.Looper;import android.os.StatFs;import android.text.format.Formatter;import android.util.Log;import android.widget.Toast;import java.io.BufferedReader;import java.io.File;import java.io.FileReader;import java.io.IOException;public class CrashHandler implements Thread.UncaughtExceptionHandler {    private static CrashHandler instance;  //单例引用,这里我们做成单例的,因为我们一个应用程序里面只需要一个UncaughtExceptionHandler实例    private static Context myContext;    private String errorInfo;    private Thread.UncaughtExceptionHandler defalutHandler;    public CrashHandler(Context context) {        myContext = context;        defalutHandler = Thread.getDefaultUncaughtExceptionHandler();        Thread.setDefaultUncaughtExceptionHandler(this);    }    CrashHandler() {    }    public synchronized static CrashHandler getInstance() {  //同步方法,以免单例多线程环境下出现异常        if (instance == null) {            instance = new CrashHandler();        }        return instance;    }    public void init(Context context) {  //初始化,把当前对象设置成UncaughtExceptionHandler处理器        myContext = context;        defalutHandler = Thread.getDefaultUncaughtExceptionHandler();        Thread.setDefaultUncaughtExceptionHandler(this);    }    @Override    public void uncaughtException(Thread thread, Throwable ex) {  //当有未处理的异常发生时,就会来到这里。。        final String threadName = thread.getName();        errorInfo = ex.toString();//错误信息        String ThreadInfoName = thread.getName();//线程名        String packageName = thread.getClass().getPackage().toString();        StackTraceElement[] stack = ex.getStackTrace();        for (int i = 0; i < stack.length; i++) {            errorInfo = errorInfo + stack[i] + "\n";        }        /**         * 该处编写相应事件即可         * 通过线程捕捉异常(非线程方法可能导致事件不能正常运行)         * 具体原因:涉及系统层,此处不方便讲解         */        new Thread() {            @Override            public void run() {                Looper.prepare();                Toast.makeText(myContext,errorInfo,Toast.LENGTH_LONG).show();                Looper.loop();            }        }.start();    }}

注意:上述代码在uncaughtException中处理异常,最好是采用线程的方法,这样系统在处理时可以及时分配内存以相应相应的处理事件,否者可能导致事件无法相应(开发者可自行测试)。


3:再编写一个OurApplication.java类,继承Application,设置我们的异常处理器为UncaughtExceptionHandler处理器,具体代码如下。

package activity.exceptionhandler.com.exceptionhandler;import android.app.Application;import android.widget.Toast;public class OurApplication extends Application {    @Override    public void onCreate() {        super.onCreate();        CrashHandler handler = CrashHandler.getInstance();        handler.init(getApplicationContext()); //在Appliction里面设置我们的异常处理器为UncaughtExceptionHandler处理器    }}


4:附上xml布局文件代码,此处简单。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    tools:context=".MainActivity">    <TextView        android:id="@+id/tv"        android:text="aaa"        android:layout_width="wrap_content"        android:layout_height="wrap_content" />    <Button        android:id="@+id/bt"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="Button"/></LinearLayout>

5:附上执行后视图。

弹框显示是捕获异常信息。



Good luck!

Write by Jimmy.li







更多相关文章

  1. SpringBoot 2.0 中 HikariCP 数据库连接池原理解析
  2. Andriod Service
  3. Android(安卓)WIFI框架分析(2)
  4. android 去锯齿
  5. android velocityTracker 简介
  6. Android(安卓)monkey自动化/压力测试(一)
  7. android xml解析 - sax
  8. Android(安卓)JNI 之 JNIEnv 解析
  9. Android_Button

随机推荐

  1. android自定义滚动条(ScrollBar)样式
  2. Android(安卓)ScrollView用法
  3. android 状态栏提醒 Notification 的使用
  4. 修改android studio 新建项目的build.gra
  5. Android(安卓)Permission denied 错误
  6. Android图文识别
  7. android apk签名生成及配置
  8. Android(安卓)SDK Download List
  9. 通过gae访问android官方文档
  10. Android(安卓)对多个EditText监听