天天看点

android程序崩溃后重启

有时候由于测试不充分或者程序潜在的问题而导致程序异常崩溃,这个是令人无法接受的,在android中怎样捕获程序的异常崩溃,然后进行一些必要的处理或重新启动

应用这个问题困恼了我很久,今天终于解决了该问题,写篇文章记录一下。

首先捕获程序崩溃的异常就必须了解一下java中uncaughtexceptionhandler这个接口,android沿用了此接口,在android api中:

android程序崩溃后重启

通过实现此接口,能够处理线程被一个无法捕捉的异常所终止的情况。如上所述的情况,handler将会报告线程终止和不明原因异常这个情况,如果没有自定义handler,

线程管理组就被默认为报告异常的handler。

threadgroup 这个类就是实现了uncaughtexceptionhandler这个接口,如果想捕获异常我们可以实现这个接口或者继承threadgroup,并重载uncaughtexception方法。

在java api中对该接口描述的更详细:

android程序崩溃后重启

我就不翻译了,太吃力了....%>_<%。在实现uncaughtexceptionhandler时,必须重载uncaughtexception(thread thread, throwable ex) ,如果我们没有实现该接口

也就是没有显示捕捉异常,则ex为空,否则ex不为空,thread 则为出异常的线程。

接下来上代码,实现uncaughtexceptionhandler接口,显示处理线程异常终止的情况:

public class uncehandler implements uncaughtexceptionhandler {  

    private thread.uncaughtexceptionhandler mdefaulthandler;    

    public static final string tag = "catchexcep";  

    catchexcep application;  

    public uncehandler(catchexcep application){  

         //获取系统默认的uncaughtexception处理器    

         mdefaulthandler = thread.getdefaultuncaughtexceptionhandler();  

         this.application = application;  

    }  

    @override  

    public void uncaughtexception(thread thread, throwable ex) {      

        if(!handleexception(ex) && mdefaulthandler != null){   

            //如果用户没有处理则让系统默认的异常处理器来处理    

            mdefaulthandler.uncaughtexception(thread, ex);                

        }else{         

            try{    

                thread.sleep(2000);    

            }catch (interruptedexception e){    

                log.e(tag, "error : ", e);    

            }     

            intent intent = new intent(application.getapplicationcontext(), mainactivity.class);  

            pendingintent restartintent = pendingintent.getactivity(    

                    application.getapplicationcontext(), 0, intent,    

                    intent.flag_activity_new_task);                                                 

            //退出程序                                          

            alarmmanager mgr = (alarmmanager)application.getsystemservice(context.alarm_service);    

            mgr.set(alarmmanager.rtc, system.currenttimemillis() + 1000,    

                    restartintent); // 1秒钟后重启应用   

            application.finishactivity();  

        }    

    /**  

     * 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成.  

     *   

     * @param ex  

     * @return true:如果处理了该异常信息;否则返回false.  

     */    

    private boolean handleexception(throwable ex) {    

        if (ex == null) {    

            return false;    

        //使用toast来显示异常信息    

        new thread(){    

            @override    

            public void run() {    

                looper.prepare();    

                toast.maketext(application.getapplicationcontext(), "很抱歉,程序出现异常,即将退出.",   

                        toast.length_short).show();    

                looper.loop();    

            }   

        }.start();    

        return true;    

    }    

}  

public class catchexcep extends application{  

    arraylist<activity> list = new arraylist<activity>();  

    public void init(){  

        //设置该crashhandler为程序的默认处理器    

        uncehandler catchexcep = new uncehandler(this);  

        thread.setdefaultuncaughtexceptionhandler(catchexcep);   

    /** 

     * activity关闭时,删除activity列表中的activity对象*/  

    public void removeactivity(activity a){  

        list.remove(a);  

     * 向activity列表中添加activity对象*/  

    public void addactivity(activity a){  

        list.add(a);  

     * 关闭activity列表中的所有activity*/  

    public void finishactivity(){  

        for (activity activity : list) {    

            if (null != activity) {    

                activity.finish();    

            }    

        }  

        //杀死该应用进程  

       android.os.process.killprocess(android.os.process.mypid());    

然后人为制造一个异常:

    button btn;  

    textview tv;  

    private catchexcep application;  

    protected void oncreate(bundle savedinstancestate) {  

        super.oncreate(savedinstancestate);  

        setcontentview(r.layout.activity_main);  

        btn = (button)findviewbyid(r.id.btn);  

        tv = (textview)findviewbyid(r.id.tv);  

        application = (catchexcep)getapplication();  

        application.init();  

        application.addactivity(this);  

        btn.setonclicklistener(this);         

    }     

     * 人为制造的异常*/  

    public void press(){  

        new thread(new runnable() {           

            @override  

            public void run() {  

                tv.settext("dfsd");  

            }  

        }).start();  

    public void onclick(view v) {  

        press();  

上诉代码就能够实现 应用出现无法捕捉的异常时,杀死当前进程,重新启动一个应用。

我之前困扰的地方:搜了很多资料,杀死异常进程,重新启动应用,网上应用都是通过application对象调用startactivity(intent),然后杀死异常进程。但是我怎样试都不成功,

进程是杀死了,但是应用却没启动起来,如果不将异常进程杀死,那么关闭应用时就得关闭两次,显然不能够接受。网上的一些方法都是错误的:如下几篇博客:

<a target="_blank" href="http://blog.csdn.net/xianming01/article/details/7711160">http://blog.csdn.net/xianming01/article/details/7711160</a>

<a target="_blank" href="http://blog.csdn.net/ryantang03/article/details/9336295?reload">http://blog.csdn.net/ryantang03/article/details/9336295?reload</a>

他们的方法能够捕获异常,杀死异常进程,但是却不能够重新启动应用。

如何杀死异常进程,重启应用,就得使用pendingintent,这个类是android中对intent类的包装,具体了解我会在写一篇博客,自己也可以去查看android api。

通过alarmmanager 启动它,并且关闭打开的activity杀死异常进程就能够实现重新启动应用。

参考链接:

<a target="_blank" href="http://zheyiw.iteye.com/blog/1670990">http://zheyiw.iteye.com/blog/1670990</a>

继续阅读