今天介绍一下面试时被问到的关于Activity的问题。
*
一、什么是Activity,介绍一下Activity的生命周期。
Activity四大组件之一,一般一个用户交互界面对应一个 activity * Activity
是Context的子类,同时实现了window.callback和keyevent.callback, 可以处理与窗体用户交互的事件.Activity的生命周期通过7个生命周期方法onCreate(),onRestart(),onStart(),onResume(),
onPause(),onStop(),onDestroy()来体现。 * 当程序启动之后,第一个Activity经过的生命周期方法是:
onCreate() →onStart() → onResume()方法,当第一个Activity A启动第二个Activity B的时候,这两个Activity经历的生命周期方法是:
A onPause() → B onCreate() → B onStart() → B onResume() → A onStop()当通过点击后退键退出Activity B的时候:
B onPause() → A onRestart() → A onStart() → A onResume() → B onStop() → B onDestroy() 此时B被销毁
二、切换横竖屏时Activity的生命周期
步骤一:运行activity
onCreate–> onStart–> onResume–>步骤二:切成横屏
onSaveInstanceState–> onPause–> onStop–> onDestroy–> onCreate–> onStart–> onRestoreInstanceState–> onResume–>步骤三:在切成竖屏,会打印两次相同log
onSaveInstanceState–> onPause–> onStop–> onDestroy–>
onCreate–> onStart–> onRestoreInstanceState–> onResume–>
onSaveInstanceState–> onPause–> onStop–> onDestroy–>
onCreate–> onStart–> onRestoreInstanceState–> onResume–>步骤四:修改AndroidManifest.xml把该Activity添加 Android:configChanges=”orientation“,
执行步骤3时,发现不会再打印相同信息,但多打印了一行onConfigChanged
onSaveInstanceState–>onPause–>onStop–>onDestroy–>
onCreate–>onStart–>onRestoreInstanceState–>onResume–>
onConfigurationChanged–>修改步骤四的**android:configChanges=”**orientation” 改成
android:configChanges=”orientation|keyboardHidden“, 执行步骤2,就只打印:
onConfigChanged–>此时执行步骤3会打印:
onConfigurationChanged–> onConfigurationChanged–>
总结一下:
1、不设置Activity的android:configChanges时,切屏会重新调用各个生命周期,切横屏时会执行一次,切竖屏时会执行两次
2、设置Activity的android:configChanges=”orientation”时,切屏还是会重新调用各个生命周期,切横、竖屏时只会执行一次
3、设置Activity的android:configChanges=”orientation|keyboardHidden”时,切屏不会重新调用各个生命周期,只会执行onConfigurationChanged方法
三、Activity的四种启动模式
standard 默认模式:
每次激活Activity时都会创建Activity实例,并放入任务栈中singleTop 栈顶复用模式,:
如果在任务的栈顶正好存在该Activity的实例,就重用该实例(会调用实例的onNewIntent()),否则就创建新的实例并放入栈顶,即使栈中存在该实例,只要不在栈顶,就会创建新的实例。
如新闻类或者阅读类App的内容页面singleTask单栈模式:
如果栈中已有该Activity的实例,就重用该实例(会调用实例的onNewIntent())。重用时会让该实例回到栈顶,因此他上面的实例将会被移出栈。栈中不存在就会创建新的实例放入栈中。如浏览器的主界面。singleInstance 单例模式:
在一个新栈中创建该Activity的实例,并让多个应用共享该栈中的该Activity实例。一旦该模式的Activity实例已经存在于某个栈中,任何应用再激活该Activity时都会重用该栈中的实例(
会调用实例的 onNewIntent() )。其效果相当于多个应用共享一个应用,不管谁激活该 Activity都会进入同一个应用中。
使用场景如闹铃提醒,将闹铃提醒与闹铃设置分离。
四、Activity有几种启动方式?
1.显式启动:通过实例Intent传入Context和目标Activity
Intent intent = new Intent(mContext,targetActivity.class);
startActivity
2.隐式启动:在清单文件中定义意图过滤器,其中有自定义action,写死的category。
<activity android:name=".SecondActivity">
<intent-filter>
<action android:name="android.intent.action.second"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
然后通过Intent的setAction和addCategory来过滤到指定的Activity。
Intent intent = new Intent();
intent.setAction("android.intent.action.second");
intent.addCategory("android.intent.category.DEFAULT");//匹配AndroidManifest里面的信息
startActivity(intent);
五、如何将一个Activity设置成窗口的样式?
在AndroidManifest.xml文件当中设置当前activity的一个属性(系统自带的属性):
Android:theme="@android:style/Theme.Dialog"
六、两个Activity之间怎么传递数据?
在Intent的对象请求中,使用putExtra(“键”,”值”);
在另外一个Activity中将Intent中的请求数据取出来:
Intent intent = getIntent();
String value = intent.getStringExtra(“键”);
七、两个Activity 之间传递数据,除了intent,广播接收者,content provider 还有啥?
* 利用 static静态数据,public static成员变量
* 利用外部存储的传输, File 文件存储 、SharedPreferences首选项 、Sqlite 数据库
八、如何启动系统的Activity
调用系统浏览器
Intent intent = new Intent();
intent.setAction(intent.ACTION_VIEW);
intent.setData(Uri.parse(address));
context.startActivity(intent)
调用系统相册
Intent intent = new Intent();
intent.setAction(intent.ACTION_GET_CONTENT);
intent.setType("image/*");
context.startActivity(intent)
调用系统电话,需添加权限
Intent intent = new Intent();
intent.setAction(Intent.ACTION_DIAL);//进入打电话界面,还没打
// intent.setAction(Intent.ACTION_CALL);//直接拨打电话
intent.setData(Uri.parse("tel:"+num));
context.startActivity(intent);
调用系统短信界面
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SENDTO);
intent.setData(Uri.parse("sms:"+num));
intent.putExtra("sms_body", message);
context.startActivity(intent);
调用系统界面播放音视频资源
String path = Environment.getExternalStorageDirectory().getAbsolutePath()+"/a.mp3"; //音频文件
// String path = Environment.getExternalStorageDirectory().getAbsolutePath()+"/b.mkv"; //视频文件
Uri uri = Uri.parse(path);
// String type = "video/*"; //视频类型
String type = "audio/*"; //音频类型
Intent intent = new Intent();
intent.setAction(intent.ACTION_VIEW);
intent.setDataAndType(uri, type);
startActivity(intent);
九、Android 中的 Context, Activity,Appliction 有什么区别?
* 相同点:Activity 和Application都是 Context的子类。
* Context从字面上理解就是上下文的意思, 在实际应用中它也确实是起到了管理上下文环境中各个参 数和变量的总用,方便我们可以简单的访问到各种资源。
* 不同:维护的生命周期不同。 Context维护的是当前的 Activity 的生命周期,Application维护 的是整个项目的生命周期。
* 使用 context的时候,小心内存泄露,防止内存泄露,注意一下几个方面:
* 1. 不要让生命周期长的对象引用activity context,即保证引用 activity 的对象要与 activity 本身 生命周期是一样的。
* 2. 对于生命周期长的对象,可以使用application,context。
* 3. 避免非静态的内部类,尽量使用静态类,避免生命周期问题,注意内部类对外部对象引用导致 的生命周期变化。
十、什么时候会走onCreate()而不执行onStart()方法
这个问题细想不是很难,但是面试时冷不丁被问到,相信大家一定很懵吧,留个心眼:
在onCreate方法中直接finish(),这样在执行完onCreate方法后会直接执行onDestroy()。
关于Activity的面试题主要就是这几个,有遗漏或者好的想法可以留言提出。