Android 启动退出时的相关问题
来源:互联网 发布:尚德自考靠谱 知乎 编辑:程序博客网 时间:2024/06/06 00:08
这是普通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的各种进程,会在下次进行学习讨论
- Android 启动退出时的相关问题
- 解决eclipse异常退出后再次启动时自动退出的问题
- android bootanimation的启动与退出
- cordova SplashScreen插件在android上退出app后不再显示启动画面的问题
- android 启动退出
- android 退出应用程序时的static变量问题
- android使用webview时按后退退出的问题
- android 退出程序 重新启动服务 的 问题
- 关于android程序完全退出的问题
- 关于android应用退出的问题
- 关于android应用退出的问题
- Android完全退出App的一些问题
- 关于android应用退出的问题
- 解决Banshee 启动后异常退出的问题
- shell脚本启动,tomcat意外退出的问题
- Android应用启动、退出分析
- Android应用启动、退出分析
- Android应用启动、退出分析
- PostgreSQL 百万级每秒的流式实时统计应用
- Luogu 1111 修复公路
- LeetCode: 566. Reshape the Matrix
- Char 和 Varchar 的区别
- Entity Framework Code First实体对象变动跟踪
- Android 启动退出时的相关问题
- Android_WebView踩坑系列
- 关于前端兼容所有浏览器的一些想法和总结
- 高级I/O之多路转接epoll
- SwipeRefreshLayout 上拉刷新和下拉刷新
- iOS逆向:在任意app上开启malloc stack追踪内存来源
- CRC循环冗余校验
- Intellij学习笔记 --- Ubuntu将Intellij图标固定到工具栏
- 计算一个数的二进制表示中0和1个数的方法