android 关于Application中使用System.exit(0)退出应用的一个问题。

求解,关于android Application中使用System.exit(0)退出应用导致启动Activiry时闪退的一个问题:
在一个项目中看到在Application中使用System.exit(0)来实现应用的完全退出,因此自己也照着做了,但项目中应用的退出并没有让Activiry走完它的生命周期,所以我用了以下的方法:

public class App extends Application {
    private int mLock = 0;
    @Override
    public void onCreate() {
        registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
            @Override
            public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
                mLock++;
            }
            @Override
            public void onActivityDestroyed(Activity activity) {
                try {
                    //模拟Activity Destroyed耗时过长,增大问题出现的概率
                    Thread.sleep(300);
                } catch (InterruptedException e) {
                }
                mLock--;
                if(mLock<=0){
                    exit();
                }
            }
            @Override
            public void onActivityStopped(Activity activity) {}
            @Override
            public void onActivityStarted(Activity activity) {}
            @Override
            public void onActivitySaveInstanceState(Activity activity, Bundle outState) {}
            @Override
            public void onActivityResumed(Activity activity) {}
            @Override
            public void onActivityPaused(Activity activity) {}

        });
    }

    public void exit() {
        System.exit(0);
    }

}

但是这样的话问题就出现了,如果我退出了最后一个Activity(退出应用)后,马上又快速地启动应用,这时Activity没有启动完成就退出了(闪退)。
求解决办法,谢谢!

无论如何,不应该在Android中使用System.exit(0),不是标准的退出App的做法。

强制关闭一个Activity后不能继续调用它的生命周期,尤其是onDestroy()。用finish()

void exit()
{

    finish();

}

没有用过system.exit(0)。那个和android编码业务相悖。它的设计是要立即退出应用程序,但是这不是你想要的。如果用户按下了“home”或者是“back”键,Activity将从stack中弹出,而且所有的生命周期方法都会被调用。如果你有理由离开app的pre-maturely,另一种方法是用finish()方法。

如果你想要按退出的时候能够一下子退出应用,那么把所有的 activity实例在application中维护一个 ArrayList 退出的时候遍历这个list ,每个都finish掉就O实现了完全退出了。
System.exit(0) 这个是直接干掉的,不走生命周期方法

没有完全明白你为什么要System.exit.如果是为了异常处理,可以用CrashHandler 来时先退出而且不会出现楼主得状况。

用 finish()啊

System.exit(0)的效果就是黑下屏,然后退出。写个接口给activity基类,再遍历退出........

System.exit(0); 直接就退出进程,出现你这种情况应该是重新“启动应用”的时候,该应用还没有完全退出,
Activity的代码
protected void onDestroy() {
if (DEBUG_LIFECYCLE) Slog.v(TAG, "onDestroy " + this);
mCalled = true;

    // dismiss any dialogs we are managing.
    if (mManagedDialogs != null) {
        final int numDialogs = mManagedDialogs.size();
        for (int i = 0; i < numDialogs; i++) {
            final ManagedDialog md = mManagedDialogs.valueAt(i);
            if (md.mDialog.isShowing()) {
                md.mDialog.dismiss();
            }
        }
        mManagedDialogs = null;
    }

    // close any cursors we are managing.
    synchronized (mManagedCursors) {
        int numCursors = mManagedCursors.size();
        for (int i = 0; i < numCursors; i++) {
            ManagedCursor c = mManagedCursors.get(i);
            if (c != null) {
                c.mCursor.close();
            }
        }
        mManagedCursors.clear();
    }

    // Close any open search dialog
    if (mSearchManager != null) {
        mSearchManager.stopSearch();
    }

    getApplication().dispatchActivityDestroyed(this);
}
可以看到onDestroy()方法的最后才执行注册的回调方法onActivityDestroy(),所以说在执行到此回调方法的时候,Activity基本上完成了它的声明周期。也就是主界面上已经看不到了,但是后台还是在继续执行,进程没有退出。   代码中可以看到睡眠0.3s,然后才走完Activity的生命周期。你的那个exit()根本没有起到应用闪退作用,由于延时导致最终应用“二次启动”的时候,执行到System.exit(0),退出进程,进而闪退。
如果没有在onDestroy()中执行System.exit(0)方法,应用的进程是不会马上退出的,这样做的目的是为了让应用第二次启动快一些。知道系统在一定的策略下(如资源不足等)才会进行资源的回收,和释放,进而杀掉一些低等级的进程。、

这也是为什么会出现本问题的原因(进程没有退出,下次启动在同一个进程中,执行到System.exit(0),进程退出,所以就闪退了)

综上,应用完全退出的目的,一般都是为了释放占用的大量资源。例如浏览器在使用过程中,会占用系统非常庞大的内存资源,当浏览器退出进入后台,此时浏览器并没有完全释放占用的内存,知道该进程被kill掉,才会释放。

对于使用Activity来说,finish()最后还是会调用onDestroy()来完成Activity的退出的一些资源的释放,数据的存储等。所以,让应用闪退本身就是一个问题。
方法两种:
1.System.exit(0),

  1. Android.os.Process.killProcess(android.os.Process.myPid()); 杀死当前进程。 作用是一样的,一般都是在调用应用的finish()后,让后调用这些函数,完全退出应用程序进程,进而释放资源。

System.exit(0)的效果就是黑下屏,然后退出。写个接口给activity基类,再遍历退出

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.app.Application;

public class MyExit extends Application {

public static List<Activity> mylist = new ArrayList<Activity>();

public static void my() {
    for (Activity a : mylist) {
        a.finish();
    }
    System.exit(0);
}

}
1.此处我写了一个类 名字MyExit
2.每次活动oncrent 时我把活动添加到集合MyExit.mylist.add(this);
3.点击退出 执行MyExit.my();

1、Android 的多个Activity 可能运行于多个进程中,事实上,一个Android 应用代表着一个Linux 下面的用户,由此可见,这一个用户运行多个进程,是理所当然的了。
2、一个Android 应用包,可以由多个组件组成,并且它可以启动其它的应用来完成用户操作历史堆栈的构建,达到满足用户操作过程完成预期的目的;

由此可见,单独的 exit 并不能真正解决问题,而每一个组件正确地 finish 自已,或被别人调用 finish,以正确结束,这才是王道,就像线程的结束,直接杀掉不是做不到,而是太粗暴,会有意想不到的情况发生,那么线程的退出,我们还是采用让线程不再循环,即跳出循环自然运行到尾部退出。

这样一来,就需要你能很好地利用 Android 提供的默认历史堆栈,利用 FLAG_ACTIVITY_CLEAR_TOP 和 FLAG_ACTIVITY_NEW_TASK 来达到一步回退到根 Activity 的目的,或者你自已构建返回堆栈,这些都能很好地达到对启动过的 Acitivty 的管理;

总体来说,你的应用预期的操作流程应该是已知的,这样你就能很好地管理它们,如果你自已在这方面很混乱,没有去考虑,那就确实不是技术的问题了,而且架构的问题。

你启动的这些 Acitivty、Service、线程等都能正常退出了,那么其间的资源也就能正确释放了,至于最后剩下的 Application 所占用的资源会很小很小了,当所有的资源都退出了,在适当的时侯它自已也就退出了。

建议细看一下官方文档的 : /guide/components/tasks-and-back-stack.html 这一部分。

Application 用system.exit(0)这个方法我个人有点不喜欢,跨activity finish有很多种方法,activity集合finish 或 更改页面启动方式 startActivityForResult.. 同时要考虑activity的启动模式, singTask..我比较常用

ystem.exit(0)的效果就是黑下屏,然后退出。写个接口给activity基类

写个Activity接口给基类

你把每个打开的activity放到list里面,然后退出的时候遍历整个list 每个activity都finish。