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。
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()
作用:onSaveInstanceState 这个方法会在activity 将要被kill之前被调用以保存每个实例的状态,以保证在将来的某个时刻回来时可以恢复到原来的状态。
调用情况:
1.用户主动按下home 键,系统不能确认activity 是否会被销毁,实际上此刻系统也无法预测将来的场景,比如说内存占用,应用运行情况等,所以系统会调用onSaveInstanceState保存activity状态 ;
2.activity位于前台,按下电源键,直接锁屏;
3.横竖屏切换;
4.activity B启动后位于activity A之前,在某个时刻activity A因为系统回收资源的问题要被kill掉,A通过onSaveInstanceState保存状态。
[注释]:onSaveInstanceState()的调用遵循一个重要原则,即当系统存在“未经你许可”时销毁了我们的Activity,则onSaveInstanceState()会被系统调用,这是系统的职责,因为它必须要提供一个机会让用户保存数据。
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的远程接口。
2.进程内启动Activity
(1)APP进程通过Binder IPC向system_server进程发起请求
(2)system_server在接收到请求后,进行一系列准备工作(解析Activity,处理启动参数),再通过Binder IPC向APP进程发送消息
(3)APP进程在接收到请求后,创建目标Activity,进入Activity的生命周期。
Activity启动流程原文链接
1)标准模式(standard)
每启动一次Activity,就会创建一个新的Activity实例并置于栈顶。谁启动了这个Activity,那么这个Activity就运行在启动它的那个Activity所在的栈中。
[应用场景]:默认模式。
2)栈顶模式(singleTop)
如果栈顶存在该activity的实例,则复用,不存在新建放入栈顶。
[应用场景]:
a.点击通知跳详情;
b.新闻详情页,点击推荐新闻条目。
3)栈内模式(singleTask)
如果栈内存在该activity的实例,会将该实例上边的activity全部出栈,将该实例置于栈顶,如果不存在,则创建。
[应用场景]:
a.APP的home页面,如果跳转到其他页面后又要跳回来;
b.浏览器的主页
4)单例模式(singleInstance)
新开一个任务栈,该栈内只存放当前实例。
[应用场景]:
项目中语音通话功能,来电话显示页面。
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)
当我们在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()方法原文链接
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原文链接
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
1.onRestoreInstance不一定会被调用。所以onCreate()里的Bundle参数可能为空,如果使用onCreate()来恢复数据,一定要做非空判断。而onRestoreInstanceState的Bundle参数一定不会是空值,因为它只有在上次activity被回收了才会调用。
2.onRestoreInstanceState是在onStart()之后被调用的。有时候我们需要onCreate()中做的一些初始化完成之后再恢复数据,用onRestoreInstanceState会比较方便。
onCreate和onRestoreInstance恢复数据的区别原文链接
方法一:
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原文链接
Activity任务栈
Activity常用的Flags标记位
Activity数据的存储与恢复