Android 启动退出时的相关问题

最近公司需求需要往两个app加启动页广告,研究发现,其中一个app在点击退出键退出时再启动有很明显的白屏现象,而另一个app则没有,于是在做了一系列测试后有了下面的博客。

这是普通app第一次启动时的过程图:

刚启动 启动页



可以看出:
app在第一次启动时,有很明显的白屏现象;
在点击退出键退出程序后,再次启动,则不再有白屏现象;
当手动杀死进程后,再次启动app,白屏现象复现。

原因分析:

Android在第一次启动时,会先启动application,再启动activity,故会有一段启动application导致的白屏时间,此时并没有任何页面(activity)被启动;

而点击退出后,Android实际上只finish掉了activity,应用以一种低优先级进程的方式存在内存中,此时基本不占用cpu和消耗电量,但是占用一定量的内存。当内存不足时,该类进程会被优先杀死。但正是由于有该类进程的存在,使得我们再次启动app时,由于application已经初始化完毕,该app可以实现快速的启动,这也正是android的优势所在(想起360手机动不动就杀掉后台进程的行为…只能呵呵…),所以再次启动app时,没有白屏现象发生。

但是为什么公司的其中一个app每次启动都白屏呢?

研究代码发现,该app的退出在调用了所有activity的finish之后,直接调用了System.exit(0) ; 简化代码如下:

    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        if (event.getKeyCode() == KeyEvent.KEYCODE_BACK
                && event.getAction() == KeyEvent.ACTION_UP) {
            System.exit(0);
        }
        return super.dispatchKeyEvent(event);
    }

原因就在于 :
finish只是关闭Android的一个类–activity。而System.exit(0)则是杀死进程。进程都被杀死,application必然不复存在,再次启动也必然白屏。这也是为什么除非特殊情况,否则不推荐直接System.exit(0)的方式退出程序,这相当于把android的快速启动优势直接抹杀掉了啊…

还有个疑问:
System.exit(0); 会把Service杀掉吗?
于是开始新一轮测试,下面的service代码:

public class MyService extends Service {
    public MyService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    Log.e("TestExit", "Test");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }
}

1.运行在主线程中的service,然后System.exit(0)退出程序。不出意外service会被杀掉。
测试结果:确实被杀掉了

2.给service指定一个process,使其运行在另一个进程中。然后System.exit(0)退出程序。
测试结果:System.exit(0) 不会杀掉该service
测试结论:service非bind模式下,是否存活与进程和自身相关。
System.exit(0)只杀死当前进程

3.通过下图方式杀死进程:

刚启动

测试结果:主线程和该Service都被杀死了
测试结论:测试2说明service的存活与进程有关,现在service被杀死了,说明service所在的新进程也被杀死了。那么为什么呢?

打开设置-应用程序管理-app,如下图:

刚启动

原来如此,在上滑关闭app就等同于在此图中点击停止运行,这个操作会关闭与app所有相关的进程或服务。

综上:停止运行(关闭app所有相关)>System.exit(0)(关闭当前进程)>finish(关闭activity)

白屏的解决办法

无论是首次启动白屏,还是由于程序中使用System.exit(0)退出导致的次次启动白屏,对于程序而言都是很不美观的。如何解决呢?

只需要给Application添加一个带背景的theme(可以是app Logo,也可以是启动页图片,可以实现无缝过渡),就可以解决这种白屏突兀的现象。

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".LaunchActivity"
            android:theme="@style/StartBackGroundTheme">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

theme内容写在res-values-styles下:

NoTitle和Fullscreen根据需要可以自行删去,个人觉得启动页这样写比较美观,并且很多app也是这样做的。同时这两个属性也是Theme要写在启动页Activity里的原因,这样只有启动页会全屏无状态栏的显示…

    <style name="StartBackGroundTheme" parent="AppTheme">
        <item name="android:windowNoTitle">true</item>
        <item name="android:windowFullscreen">true</item>
        <item name="android:windowBackground">@drawable/start_background</item>
    </style>

关于Android的各种进程,会在下次进行学习讨论

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值