一.Activity 因系统内存不足被Kill或是因为Crash闪退的异常退出怎么保存数据:
Activity 被销毁了以后调用了onSaveInstanceState来保存数据,这个只会在Activity即将销毁并且有机会重新显示的情况下才会去调用onSaveInstanceState;与之配对的是在onRestoreInstanceState里恢复数据;
我教大家来模拟实现下,随便建立一个TestActivity,实现这两个方法,运行到模拟器上,打开DDMS,选中我们正在运行的进程包名,然后点击DDMS里边有结束这个进程的按钮结束掉这个进程,模拟器或手机上的效果是闪一下这个界面就销毁了,这种方式可以执行到这两个方法,亲测可用!
当然了,上述是因为异常的情况才会调用的,我们平常保存数据都是在onPause,其实onStop也是可以的,因为当A Activity 跳转到 B Activity时必须先执行A的onPause方法,因此A中的onPause方法中不要进行耗时的操作,否则这个跳转会有黑屏或者很慢的感觉,影响用户体验,这个时候可以在onStop里边存储些数据,当然,也不做太多的耗时操作!
二.资源不足时Activity的杀死顺序
1.前台Activity - 正在和用户交互的Activity,优先级最高
2.可见但非前台Activity-比如Activity 中弹出了一个对话框,导致Activity可见但是位于后台无法和用户直接交互。
3.后台Activity-已经被暂停的Activity,比如执行了onStop,优先级最低
上述情况Activity被杀死时会执行 “一” 中的方法来保存数据和恢复数据,因此,一些后台工作不适合脱离四大组件而独自运行在后台中,这样进程很容易被杀死。比较好的方法是将后台工作放入Service中从而保证进程有一定的优先级,这样就不会轻易的被系统杀死。
三.Activity的启动模式
Activity是基于任务栈的实现
1.standard:标准模式,也是默认的模式,每次启动Activity都会创建新的实例,不管这个实例是否存在,一个任务栈里可以有多个实例,每个实例也可以用不同的任务栈。在这种模式下,谁启动了这个Activity,那么这个Activity就运行在启动它的那个Activity所在的栈中。比如A Activity启动了B Activity(B是默认启动模式),那么B就会进入到A所在到栈中。因此当我们用ApplicationContext去启动standard模式的Activity 时候会报错,android.util.AndroidRuntimeException:Calling startActivity from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want? 这是因为standard模式的Activity默认会进入启动它的Activity所属的任务栈中,但是由于非Activity类型的Context(ApplicatonContext)并没有所谓的任务栈,所以就报错了,除非加上FLAG_NEW_TASK的flag,这个将会重新为它创建一个新的任务栈,就相当于singleTask模式启动的了。
2.singleTop:栈顶复用模式。在这种模式下,如果新Activity已经位于任务栈的栈顶,那么此Activity不会被重新创建,同时它的onNewIntent方法会被回调,通过此方法的参数我们可以取出当前请求的信息(一般是Intent携带的数据Bundle),需要注意的是,这个,Activity的onCreate,onStart不会被系统调用,因为它并没有发生改变。如果新Activity的实例已存在但不是位于栈顶,那么新Activity仍然会重新创建。例如,假设目前栈里有ABCD四个Activity,A是栈底,D位于栈顶,这个时候要再次启动D,如果D的启动模式为singleTop,那么栈内的情况仍然是ABCD;如果D的启动模式是standard,则运行后栈内结果为ABCDD。
3.singleTask:栈内复用模式。这是一种单实例模式,只要Activity在一个栈中存在,那么多次启动此Activity都不会重新创建实例,和singleTop一样,系统也会回调onNewIntent。具体一点,当一个具有singleTask模式的A Activity请求启动后,系统首先会寻找是否存在A的任务栈,如果不存在,就重新创建一个任务栈,然后创建A的实例同时把A压入栈中。反之,如果存在A的任务栈,这时要看栈中是否有A的实例存在,如果有实例存在,那么系统就会把A调到栈顶并调用它的onNewIntent方法,比如目前任务栈S1中的情况为ABC,这个时候启动Activity D(singleTask模式),则Activity D所需要的任务栈为S2,由于S2和D的实例均不存在,所以系统会先创建任务栈S2,然后再创建D的实例并将其入栈道S2;如果D所在的任务栈为S1,栈内情况为ADBC,根据栈内复用原则,此时D不会被重建,系统会把D切换到栈顶并调用其onNewIntent方法,同时由于singleTask默认具有clearTop的效果,会导致栈内所有在D上的Activity全部出栈,于是最终S1中的情况为AD。
4.singleInstance:单实例模式。是一种加强的singleTask模式,具有singleTask的所有特性,区别在于,此种模式的Activity只能单独的位于一个任务栈中,比如A Activity 是singleInstance模式,当A启动后,系统会为其创建一个新的任务栈,由于栈内复用模式, 频繁启动A均不会创建新的Activity,除非这个任务栈被系统销毁了。
上述论述,建议大家建议个TestActivity亲自来验证下,加上理解与运用。
四.IntentFilter的隐式调用
这种的面试题是非常之多,很基础,都是一些细节,需要会理解使用
隐式调用的Activity必须在清单文件中添加 android.intent.category.DEFAULT这个category
Intent intent = new Intent("com.example.intent.test");//这里的Action 要和清单文件中配置的一样,因为它是个纯的字符串,并且区分大小写
intent.addCategory("com.exaple.category.test");//同上
intent.setDataAndType(Uri.parse("file//test"),"text/plain");
startActivity(intent);//会默认为Intent“android.intent.category.DEFAULT"这个category,这也是我们上面说的在配置文件中一定要加上这个category的缘由。
隐式调用就需要注意Action,Categroy,和Data,这些都很基础,大家多多练习来验证这些问题即可。
五.Activity的生命周期
这个就是老生常谈了,基础面一般也会问的,如果面试官比较菜,会问这些的。
借用艺术探索的图
Activity的面试题大概就这些,我做的比较多的就是生命周期,隐式调用,上面的基本都遇到了。
参考资料:
Android开发艺术探索