1、什么是Activity?
四大组件之一,一般的,一个用户交互界面对应一个 activity
•setContentView() ,// 要显示的布局
•button.setOnclickLinstener{}, activity 是 Context 的子类,同时实现了 •window.callback 和keyevent.callback, 可以处理与窗体用户交互的事件.
•我开发常用的的有
FragmentActivitiyListActivity ,PreferenceActivity ,TabAcitivty 等…
2、请描述一下 Activity 生命周期
•Activity 从创建到销毁有多种状态,从一种状态到另一种状态时会激发相应的回调方法,这些回调方法包括:onCreate onStart onResume onPause onStop onDestroy
•其实这些方法都是两两对应的,onCreate 创建与 onDestroy 销毁;
onStart 可见与 onStop 不可见;onResume 可编辑(即焦点)与 onPause;
如果界面有共同的特点或者功能的时候,还会自己定义一个 BaseActivity.
进度对话框的显示与销毁
onCreate:与onDestroy配对,表示Activity正在被创建,这是生命周期的第一个方法。在这个方法中可以做一些初始化的工作(加载布局资源、初始化Activity所需要的数据等),耗时的工作在异步线程上完成。
onRestart:表示Activity正在重新启动。一般情况下,在当前Activity从不可见重新变为可见的状态时onRestart就会被调用。这种情形一般是由于用户的行为所导致的,比如用户按下Home键切换到桌面或者打开了一个新的Activity(这时当前Activity会暂停,也就是onPause和onStop被执行),接着用户有回到了这个Activity,就会出现这种情况。
onStart:与onStop配对,表示Activity正在被启动,并且即将开始。但是这个时候要注意它与onResume的区别。两者都表示Activity可见,但是onStart时Activity还正在加载其他内容,正在向我们展示,用户还无法看到,即无法交互。
onResume:与onPause配对,表示Activity已经创建完成,并且可以开始活动了,这个时候用户已经可以看到界面了,并且即将与用户交互(完成该周期之后便可以响应用户的交互事件了)。
onPause:与onResume配对,表示Activity正在暂停,正常情况下,onStop接着就会被调用。在特殊情况下,如果这个时候用户快速地再回到当前的Activity,那么onResume会被调用(极端情况)。一般来说,在这个生命周期状态下,可以做一些存储数据、停止动画的工作,但是不能太耗时,如果是由于启动新的Activity而唤醒的该状态,那会影响到新Activity的显示,原因是onPause必须执行完,新的Activity的onResume才会执行。
onStop:与onStart配对,表示Activity即将停止,可以做一些稍微重量级的回收工作,同样也不能太耗时(可以比onPause稍微好一点)。
onDestroy:与onCreate配对,表示Activity即将被销毁,这是Activity生命周期的最后一个回调,我们可以做一些回收工作和最终的资源释放(如Service、BroadReceiver、Map等)。
3 、 常 见 的 Activity 类 型 有 FragmentActivitiy ,ListActivity,TabAcitivty 等。请描述一下 Activity 生命周期
Activity 从创建到销毁有多种状态,从一种状态到另一种状态时会激发相应的回
调方法,这些回调方法包括:onCreate onStart onResume onPause onStop
onDestroy
其实这些方法都是两两对应的,onCreate 创建与 onDestroy 销毁;
onStart 可见与 onStop 不可见;onResume 可编辑(即焦点)与 onPause。
4、如何保存 Activity 的状态或者(Activiy 重启怎么保存数据?)
Activity 的状态通常情况下系统会自动保存的,只有当我们需要保存额外的
数据时才需要使用到这样的功能。
一般来说, 调用onPause()和onStop()方法后的activity 实例仍然存在于内
存中, activity 的所有信息和状态数据不会消失, 当 activity 重新回到前台之后,
所有的改变都会得到保留。
但是当系统内存不足时, 调用onPause()和onStop()方法后的activity 可能
会被系统摧毁, 此时内存中就不会存有该activity 的实例对象了。如果之后这个
activity 重新回到前台, 之前所作的改变就会消失。为了避免此种情况的发生, 我
们可以覆写 onSaveInstanceState()方法。onSaveInstanceState()方法接受一
个 Bundle 类型的参数, 开发者可以将状态数据存储到这个 Bundle 对象中, 这
样即使 activity 被系统摧毁, 当用户重新启动这个 activity 而调用它的
onCreate()方法时, 上述的Bundle 对象会作为实参传递给 onCreate()方法, 开
发者可以从 Bundle 对象中取出保存的数据, 然后利用这些数据将 activity 恢复
到被摧毁之前的状态。
需要注意的是, onSaveInstanceState()方法并不是一定会被调用的, 因为有
些场景是不需要保存状态数据的. 比如用户按下 BACK 键退出 activity 时, 用户
显然想要关闭这个 activity, 此时是没有必要保存数据以供下次恢复的, 也就是
onSaveInstanceState()方法不会被调用. 如果调用 onSaveInstanceState()方
法, 调用将发生在 onPause()或 onStop()方法之前。
5、 两个 Activity 之间跳转时必然会执行的是哪几个方法?
一般情况下比如说有两个activity,分别叫A,B,当在A 里面激活B 组件的时候,
A 会调用 onPause()方法,然后 B 调用 onCreate() ,onStart(), onResume()。这
个时候 B 覆盖了窗体, A 会调用 onStop()方法. 如果 B 是个透明的,或者
是对话框的样式, 就不会调用 A 的 onStop()方法。
6、 横竖屏切换时 Activity 的生命周期(★★★★)
此时的生命周期跟清单文件里的配置有关系。
1.不设置 Activity 的 android:configChanges 时,切屏会重新调用各个生
命周期默认首先销毁当前 activity,然后重新加载。
2.设置 Activity
android:configChanges="orientation|keyboardHidden|screenSize"时,切
屏不会重新调用各个生命周期,只会执行 onConfigurationChanged 方法。
通常在游戏开发, 屏幕的朝向都是写死的。
@Override
protected void onSaveInstanceState(Bundle outState) {
// TODO Auto-generated method stub
super.onSaveInstanceState(outState);
}
7、 如何将一个 Activity 设置成窗口的样式
只需要给我们的 Activity 配置如下属性即可。
android:theme="@android:style/Theme.Dialog"
8、 如何退出 Activity?如何安全退出已调用多个Activity 的 Application?(★★★★)
1、通常情况用户退出一个 Activity 只需按返回键,我们写代码想退出 activity
直接调用 finish()方法就行。
2、记录打开的 Activity:
每打开一个 Activity,就记录下来。在需要退出时,关闭每一个 Activity 即可。
3、发送特定广播:
在需要结束应用时,发送一个特定的广播,每个 Activity 收到广播后,关闭
即可。
//给某个 activity 注册接受接受广播的意图
//伪代码
List<Activity> lists ;// 在 application 全局的变量里面
lists = new ArrayList<Activity>();
lists.add(this);
for(Activity activity: lists)
{
activity.finish();
}
lists.remove(this);
registerReceiver(receiver, filter)
//如果过接受到的是 关闭 activity 的广播 就调用 finish()方法 把当前的
activity finish()掉
4、递归退出
在打开新的 Activity 时使用 startActivityForResult,然后自己加标志,在
onActivityResult 中处理,递归关闭。
5、其实 也可以通过 intent 的 flag 来实现
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)激活一个新的 activity。
此时如果该任务栈中已经有该 Activity,那么系统会把这个 Activity 上面的所有
Activity 干掉。其实相当于给 Activity 配置的启动模式为 SingleTop。
9、 Activity 的 四 种 启 动 模 式 , singletop 和singletask 区别是什么?一般书签的使用模式是singletop,那为什么不使用 singletask?
singleTop 跟 standard 模式比较类似。唯一的区别就是,当跳转的对象是
位于栈顶的 activity(应该可以理解为用户眼前所 看到的 activity)时,程序将
不会生成一个新的activity 实例,而是直接跳到现存于栈顶的那个 activity 实例。
拿上面的例子来说,当 Act1 为 singleTop 模式时,执行跳转后栈里面依旧只有
一个实例,如果现在按返回键程序将直接退出。
singleTask 模式和 singleInstance 模式都是只创建一个实例的。在这种模
式下,无论跳转的对象是不是位于栈顶的 activity,程序都不会生成一个新的实
例(当然前提是栈里面已经有这个实例)。这种模式相当有用,在以后的多activity
开发中,常会因为跳转的关系导致同个页面生成多个实例,这个在用户体验上始
终有点不好,而如果你将对应的 activity 声明为 singleTask 模式,这种问题将
不复存在。在主页的 Activity 很常用
10、Android 中的 Context, Activity,Appliction 有什么区别?(★★)
相同:Activity 和 Application 都是 Context 的子类。
Context 从字面上理解就是上下文的意思,在实际应用中它也确实是起到了管理
上下文环境中各个参数和变量的总用,方便我们可以简单的访问到各种资源。不同:
维护的生命周期不同。 Context 维护的是当前的 Activity 的生命周期,
Application 维护的是整个项目的生命周期。
使用 context 的时候,小心内存泄露,防止内存泄露,注意一下几个方面:
- 不要让生命周期长的对象引用 activity context,即保证引用 activity 的对象
要与 activity 本身生命周期是一样的。
- 对于生命周期长的对象,可以使用 application,context。
- 避免非静态的内部类,尽量使用静态类,避免生命周期问题,注意内部类对
外部对象引用导致的生命周期变化。
11、两个Activity 之间传递数据,除了 intent,广播接收者,content provider 还有啥?
1)利用 static 静态数据,public static 成员变量
2)利用外部存储的传输,
例如 File 文件存储
SharedPreferences 首选项
Sqlite 数据库
12、Context 是 什 么 ? , 一 个 应 用 有 多 少 个Context(2020.5.15)(★★)
1、它描述的是一个应用程序环境的信息,即上下文。
2、该类是一个抽象(abstract class)类,Android 提供了该抽象类的具体实
现类(ContextIml)。
3、通过它我们可以获取应用程序的资源和类,也包括一些应用级别操作,
例如:启动一个 Activity,发送广播,接受 Intent,信息,等。
4、一个应用 Context 数量=Activity 个数+service 个数+1 个
13.activity 之间还有 activity 和 service 之间如何传值,可以传图片吗? (2020.5.15)(上海)
Activity 之间的传值:startActivity,通过 Intent 对象的各种 putExtra 方法来
进行传递。在第二个 Activity 对象中,可以通过 getIntent() 方法来得到跳转
到这个 Activity 的 Intent 对象,然后通过 Intent 对象的各种 getXXExtra 方
法来得到我们的传过来的值。
Activity 和 service 之间传值:
1、在 activity 中通过 startService(intent)即可,同样 intent.putStringExtra(),
然 后 再 service 中 的 onStart 函 数 中 获 取 该
值,this.getIntent(),intent.getString()
在这里我们需要在 Mainfeist 文件中注册这个 service
<service Android:enabled="true" android:name=".Service">
</service>
2、service 可以从 public int onStartCommand(Intent intent, int flags, int
startId)中取出从 activity 中传过来的值。intent.getExtra()获得 bundle 对象,
可从中取值。
3、activity 也可以用 bindService(intent, conn,BIND_AUTO_CREATE);传
值,把要传的值绑定在 intent 里,在 service 的 public IBinder onBind(Intent
intent) 方法里取得 intent。
4、同时也可以在 reseiver 里面注册一个广播,在 activity 里sendbroadcast
(intent)传值。
可以传递图片,用 Intent 把图片的地址或者把图片对象用 Intent 传过去,用
bitmap 对象。
14.Activity的启动过程
Activity的启动过程,我们可以从Context的startActivity说起,其实现是ContextImpl的startActivity,然后内部会通过Instrumentation来尝试启动Activity,这是一个跨进程过程,它会调用ams的startActivity方法,当ams校验完activity的合法性后,会通过ApplicationThread回调到我们的进程,这也是一次跨进程过程,而applicationThread就是一个binder,回调逻辑是在binder线程池中完成的,所以需要通过Handler H将其切换到ui线程,第一个消息是LAUNCH_ACTIVITY,它对应handleLaunchActivity,在这个方法里完成了Activity的创建和启动,接着,在activity的onResume中,activity的内容将开始渲染到window上,然后开始绘制直到我们看见。
网友评论