【Android】基础问题—Activity

【Android】基础问题

        • 1.Activity的生命周期
        • 2.Activity A 启动另一个Activity B 会调用哪些方法?如果B是透明主题的又或则是个DialogActivity呢
        • 3.说下onSaveInstanceState()方法的作用 ? 何时会被调用?
        • 4.Activity的启动流程
        • 5.Activity的启动模式和使用场景
        • 6.Activity之间传递数据的方式Intent是否有大小限制,如果传递的数据量偏大,有哪些方案
        • 7.Activity的onNewIntent()方法什么时候会执行
        • 8.scheme使用场景,协议格式,如何使用
        • 9.ANR 的四种场景
        • 10.onCreate和onRestoreInstance方法中恢复数据时的区别
        • 11.跨App启动Activity的方式,注意事项
        • 12.其他了解性内容

1.Activity的生命周期

1.onCreate:Activity首次被创建时调用。
2.onStart:使Activity显示给用户看时调用。
3.onResume:使Activity位于前台(位于栈顶)时调用。
4.onPause:当Activity被覆盖时调用。(此时新Activity还未入栈,原有Activity还可见。原有Activity的数据会被保存起来)
5.onStop:使Activity不可见时调用。(新Activity显示,原有Activity隐藏)
6.onDestroy:销毁当前Activity。
7.onRestart:当Activity从隐藏状态(onStop)被唤醒时调用。
[注意事项]:
a.当内存资源不足时,系统就可能杀死处于onpause的Activity所在的进程。
b.生命周期的方法都是回调方法,可重新方法的内容,什么时候调用什么方法是由Activity决定的,能手动调用的只要finish()方法,该方法用于关闭并销毁Activity。
【Android】基础问题—Activity_第1张图片

2.Activity A 启动另一个Activity B 会调用哪些方法?如果B是透明主题的又或则是个DialogActivity呢

1.Activity A 启动另一个Activity B

    A-onCreate() ——> A-onStart() ——> A-onResume() ——> A-onPause() ——> B-onCreate() ——> B-onStart() ——> B-onResume() ——> A-onStop()

2.Activity B显示后 点击返回按钮 回调的方法

    B-onPause() ——> A-onRestart() ——> A-onStart() ——> A-onResume() ——> B-onStop() ——> B-onDestroy()

3.Activity A启动另一个Activity B 如果Activity B完全透明 会回调那些方法

   A-onCreate() ——> A-onStart() ——> A-onResume() ——> A-onPause() ——> B-onCreate() ——> B-onStart() ——> B-onResume()

4.Activity B(完全透明)显示后 点击返回按钮 回调的方法

	B-onPause() ——> A-onResume() ——> B-onStop() ——> B-onDestroy()

5.Activity A启动一个DialogActivity 回调哪些方法

	A-onCreate() ——> A-onStart() ——> A-onResume()
3.说下onSaveInstanceState()方法的作用 ? 何时会被调用?

作用:onSaveInstanceState 这个方法会在activity 将要被kill之前被调用以保存每个实例的状态,以保证在将来的某个时刻回来时可以恢复到原来的状态。
调用情况:
1.用户主动按下home 键,系统不能确认activity 是否会被销毁,实际上此刻系统也无法预测将来的场景,比如说内存占用,应用运行情况等,所以系统会调用onSaveInstanceState保存activity状态 ;
2.activity位于前台,按下电源键,直接锁屏;
3.横竖屏切换;
4.activity B启动后位于activity A之前,在某个时刻activity A因为系统回收资源的问题要被kill掉,A通过onSaveInstanceState保存状态。
[注释]:onSaveInstanceState()的调用遵循一个重要原则,即当系统存在“未经你许可”时销毁了我们的Activity,则onSaveInstanceState()会被系统调用,这是系统的职责,因为它必须要提供一个机会让用户保存数据。

4.Activity的启动流程

1.根Activity的启动流程
(1)点击桌面APP图标,Launcher进程采用Binder IPC的方式向system_server进程的AMS(ActivityManagerService)发起startActivity的请求。
(2)system_server进程接收到请求后,采用Socket IPC向Zygote进程发出创建APP进程的请求;
Zygote进程fork出新的进程,即APP进程;
(3)APP进程通过Binder IPC向system_server进程发起attachApplication请求;
system_server进程在接收到请求后,进行一系列的准备工作后,再通过Binder IPC向APP进程发送scheduleLaunchActivity的请求
(4)APP进程接收到请求后,通过Handler向主线程发送LAUNCH_ACTIVITY消息,创建目标Activity,进入Activity的生命周期
ActivityManagerProxy是AMS的远程接口,ApplicationThreadProxy是ApplicationThread的远程接口。
【Android】基础问题—Activity_第2张图片

2.进程内启动Activity
(1)APP进程通过Binder IPC向system_server进程发起请求
(2)system_server在接收到请求后,进行一系列准备工作(解析Activity,处理启动参数),再通过Binder IPC向APP进程发送消息
(3)APP进程在接收到请求后,创建目标Activity,进入Activity的生命周期。
【Android】基础问题—Activity_第3张图片
Activity启动流程原文链接

5.Activity的启动模式和使用场景

1)标准模式(standard)
每启动一次Activity,就会创建一个新的Activity实例并置于栈顶。谁启动了这个Activity,那么这个Activity就运行在启动它的那个Activity所在的栈中。
[应用场景]:默认模式。

2)栈顶模式(singleTop)
如果栈顶存在该activity的实例,则复用,不存在新建放入栈顶。
[应用场景]:
a.点击通知跳详情;
b.新闻详情页,点击推荐新闻条目。

3)栈内模式(singleTask)
如果栈内存在该activity的实例,会将该实例上边的activity全部出栈,将该实例置于栈顶,如果不存在,则创建。
[应用场景]:
a.APP的home页面,如果跳转到其他页面后又要跳回来;
b.浏览器的主页

4)单例模式(singleInstance)
新开一个任务栈,该栈内只存放当前实例。
[应用场景]:
项目中语音通话功能,来电话显示页面。

6.Activity之间传递数据的方式Intent是否有大小限制,如果传递的数据量偏大,有哪些方案

Binder事务缓冲区有一个限定大小,通常是1Mb,并且这是该进程中所有正在进行中的传输对象所公用的。所以我们能传输的数据大小实际上应该比1M要小。
传递数据量偏大的替代方案:
1.通过Application
2.使用单例
3.静态成员变量。(可以考虑 WeakReferences)
4.持久化(sqlite、share preference、file等)
Activity之间传递数据的方式原文链接
[注意事项]:可以使用bundle.putBinder()方法完成大数据传递。

//创建一个类继承自Binder
class BigBinder(val data:ByteArray):Binder()

//传递数据
val intent = Intent(this, TestActivity::class.java)
val data= ByteArray( 1024 * 1024)
val bundle = Bundle()
val bigData = BigBinder(data)
bundle.putBinder("bigData",bigData)
intent.putExtra("bundle",bundle)
startActivity(intent)
7.Activity的onNewIntent()方法什么时候会执行

当我们在activity的启动模式中设置为栈内唯一时,也就是android:launchMode=”singleTask”或android:launchMode=”signleTop”时,会用到这个方法。

比如说在一个应用中A activity 跳转至 B activity 在跳转至 C activity 然后C做了一定的操作之后再返回A 界面。这样在A activity的启动模式设置为singleTask后。C界面跳转至A界面时,就会去判断栈内是否有改Activity实例,如果有就直接执行A界面的onNewIntent()方法,我们就可以把逻辑处理放在该生命周期方法中,如果没有就会走Activity的oncrate方法去创建实例。

在比如说我们做了一个应用。每个界面都有一个返回至主界面操作的按钮。这样的话我们就给主界面的启动模式设置为android:launchMode=”singleTask”。当用户在任何界面点击返回至主界面的按钮时,就正常的使用Intent去跳转。只不过在栈内存在主界面的实例时,不会执行onCrate()方法而是执行的onNewIntent()方法。这时我们就把操作逻辑放在此处。

需要注意的是,在onCrate()方法中最好也写一份操作逻辑,因为当系统内存不足时,我们的主界面实例已经被系统回收了,还是会去执行onCrate()方法的。
Activity的onNewIntent()方法原文链接

8.scheme使用场景,协议格式,如何使用

1.什么是scheme
简单的说就是android中的一种页面内跳转协议,方便app页面的内的跳转。

2.scheme协议格式

zymobi://3g2win:9999/macthDetail?macthId=222&time=10001
名称 含义 示例
scheme 代表该Schema 协议名称 zymobi
host 代表Schema作用于哪个地址域 3g2win
port 代表该路径的端口号 9999
path 代表Schema指定的页面 /macthDetail
代表传递的参数 ?macthId=222&time=10001

3.scheme的使用
a.在app中使用
在AndroidManifest.xml中对activity标签增加intent-filter设置Schema

	<activity android:name=".SecondActivity">
		<intent-filter>
			<action android:name="android.intent.action.VIEW"/>
			<category android:name="android.intent.category.DEFAULT"/>
			<category android:name="android.intent.category.BROWSABLE"/>
			<data android:scheme="zymobi"
				android:host="3g2win"
				android:port="9999"
				android:path="/macthDetail"/>
		intent-filter>
	activity>

b.在在html中调用

<a href="zymobi://3g2win:9999/macthDetail?macthId=222&time=10001">打开源生应用指定的页面a>

c.在源生应用中调用

Intent intent = new Intent(Intent.ACTION_VIEW,Uri.parse("zymobi://3g2win:9999/macthDetail?macthId=222&time=10001"));
startActivity(intent); 

scheme原文链接

9.ANR 的四种场景

1.什么是ANR
ANR全称Application Not Responding即应用程序无响应。在Android中如果应用程序有一段时间无法响应用户操作,系统会弹出弹窗,让用户选择是继续等待还是强制关闭程序。一款良好应用APP是不应该出现这个弹窗的。

2.ANR的产生原因
1)KeyDispatchTimeout
Activity在5秒钟之内无法响应屏幕触摸事件或键盘输入事件就会产生ANR。
Reason:Input event dispatching timed out

2)BroadcastTimeout
BroadcastReceiver在10秒钟之内还未执行完成就会产生ANR。
Reason:Timeout of broadcast BroadcastRecord

3)ServiceTimeout
Service各个生命周期在20秒钟之内没有执行完成就会产生ANR。
Reason:Timeout executing service

4)ContentProviderTimeout
ContentProvider在10秒钟之内没有执行完成就会产生ANR。
Reason:timeout publishing content providers

10.onCreate和onRestoreInstance方法中恢复数据时的区别

1.onRestoreInstance不一定会被调用。所以onCreate()里的Bundle参数可能为空,如果使用onCreate()来恢复数据,一定要做非空判断。而onRestoreInstanceState的Bundle参数一定不会是空值,因为它只有在上次activity被回收了才会调用。
2.onRestoreInstanceState是在onStart()之后被调用的。有时候我们需要onCreate()中做的一些初始化完成之后再恢复数据,用onRestoreInstanceState会比较方便。
onCreate和onRestoreInstance恢复数据的区别原文链接

11.跨App启动Activity的方式,注意事项

方法一:
1.在App2(被调用的APP)的AndroidManifest.xml文件中,对需要被调用的Activity进行如下配置

  <activity 
   android:name=".SingleIntanceActicvity"
   android:launchMode="singleInstance" >
            <intent-filter >
                <action android:name="android.intent.action.SingleIntanceActivity"/>
                <category android:name="android.intent.category.DEFAULT"/>
                <category android:name="com.test.helloworld.SINGLEINTANCE"/>
            intent-filter>
  activity>

2.在App1(当前使用的APP)需要实现的功能的Activity中书写如下逻辑代码

//写法一:
Intent intent = new Intent("android.intent.action.SingleIntanceActivity");
startActivity(intent);

//写法二:
Intent intent=new Intent();
intent.setAction("android.intent.action.SingleIntanceActivity"); 
intent.addCategory("com.test.helloworld.SINGLEINTANCE");
startActivity(intent);

方法二:
在APP1中,通过intent.setClassName()来启动,代码如下

Intent intent=new Intent(Intent.ACTION_VIEW);
String packageName = "com.test.helloworld";//APP2的SingleIntanceActivity包名
String className = "com.test.helloworld.SingleIntanceActicvity";//全路径名
intent.setClassName(packageName, className);
startActivity(intent);

[注释]:方法二中是否需要在APP2中进行相关配置并未验证,若直接使用方法二无效,可按方法一第一条进行相关配置。
android跨应用启动Activity原文链接

12.其他了解性内容

Activity任务栈
Activity常用的Flags标记位
Activity数据的存储与恢复

你可能感兴趣的:(Android,activity,知识学习,android,面试,学习)