求解,关于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),
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。