整理之Activity
基础
生命周期
| 执行层次 | 进 | 退 |
|---|---|---|
| 创建与销毁 | onCreate() | onDestroy() |
| 是否可见 | onStart() | onStop() |
| 是否在前台(可交互) | onResume() | onPause() |
1.异常情况之配置改变
比如屏幕旋转后Activity会重建。常见操作的生命周期变化:
1.屏幕关闭/打开时:pause -> Save -> stop -> start -> resume,异常时save和pause顺序不确定
2.屏幕旋转时:pause -> save -> stop -> destroy -> start -> restore -> resume
3.弹出dialig:不产生变化
4.添加fragment:不产生变化
是否可以在发生配置变化后不重建Activity?可以的。
指定android:configChanges属性,比如希望屏幕旋转后配置不变。加入orientation|screenSize,其他常见属性还有:
| locale 设备的本地位置发生了改变,一般指切换了系统语言 | keyboard 键盘类型发生改变,比如外插键盘 |
|---|---|
| keyboardHidden 键盘的可访问性发生了改变,如调出了键盘 | fontScale 用户选择了一个新字号 |
| uiMode 用户界面模式发生了改变,比如是否开启了夜间模式 |
设置之后,旋转屏幕Activity并没有重建,也没吊用onSaveInstanceState和onRestoreInstanceState方法,取而代之的是onConfigurationChanged方法,在这个里面可以做一些处理。
2.异常情况之内存紧张导致Activity被杀死
被杀的优先级:空进程 > 后台Activity > 不可操作Activity > 前台进程
跳转
//简单跳转
startActivity(Intent(this, That::class.java).apply{
Bundle().apply{
putXXX()
}
})
//接收返回结果的跳转
A.startActivityForResult(intent, requestCode, options) //发送
A.onActivityResult(requestCode, resultCode, data: Intent) //接收返回结果
B.setResult(resultCode) //设置返回结果
B.finish() //退出
启动模式
1.standerd:每次启动都创建一个实例插入task中
2.singleTop:栈顶复用,即不允许多个相同Activity叠加
如果Activity在栈顶的时候,启动相同的Activity,不会创建新的实例,而会调用其onNewIntent方法。
生命周期顺序:onCreate ---> onStart ---> onResume --- onPause ---> onNewIntent ---> onResume
3.singleTask:栈内复用,即栈内只能有一个这A的实例。
在同一个应用程序中启动A的时候,若A不存在,则会在当前task创建一个新的实例,若存在,则会把task中在其之上的其它所有Activity destory掉并调用它的onNewIntent方法。
如果是在别的应用程序中启动它,则会新建一个task,并在该task中启动这个Activity,singleTask允许别的Activity与其在一个task中共存,也就是说,如果我在这个singleTask的实例中再打开新的Activity,这个新的Activity还是会在singleTask的实例的task中。
生命周期顺序:onCreate ---> onStart ---> onResume ---> 按下Home键 ---> onPause ---> onstop ---> onNewIntent---> onRestart ---> onstart ---> onResume
4.signleInstance:独占使用
任务站中只能有一个A,不能有其他的。生命周期顺序同singleTask
特别需要注意:
注意onNewIntent()中的陷阱:
有时候,我们在多次启动同一个栈唯一模式下的activity时,在onNewIntent()里面的getIntent()得到的intent感觉都是第一次的那个数据。对,这里就是这个陷阱。因为它就是会返回第一个intent的数据。就是这么坑。
原因就是我们没有在onNewIntent()里面设置setIntent(),将最新的intent设置给这个activity实例。
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);//设置新的intent
int data = getIntent().getIntExtra("tanksu", 0);//此时的到的数据就是正确的了
}
在这里,如果你没有调用setIntent()方法的话,则getIntent()获取的intent都只会是最初那个intent(Note that getIntent() still returns the original Intent. You can use setIntent(Intent) to update it to this new Intent.)
5.如何给Activity指定启动模式?
1.通过AndroidMenifest。android:launchMode="singleTask"
2.通过Intent中设置标志位来为Activity指定启动模式。
intent = new Intent(MainActivity.this,Handler_01.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
两者区别:
优先级:第二种方式的优先级要高于第一种;
限定范围:第一种方式无法直接为Activity设定FLAG_ACTIVITY_CLEAR_TOP标识,而第二种无法为Activity指定singleInstance模式。
常见操作
双击返回键退出Activity
思路:
设置两次点击之间的时间间隔k,临时变量b=true保存返回按键是否被点击过。
当按下返回键时,如果b=true,直接退出;否则设置b=true,并在k时间后设置b为false。
当两次点击时间间隔小鱼k时,b的状态被保存,会触发退出事件。否则b会被重置,无法退出。
private int isDoubleClickExit = 0; //是否双击退出App。0为不退出,大于0时为双击之间的时间间隔
protected void setDoubleClickExit(int ms) {
isDoubleClickExit = ms;
}
private boolean isBackButtonClicked = false;
@Override
public void onBackPressed() {
if (isDoubleClickExit != 0) {
if (isBackButtonClicked) {
exitApp();
return;
}
isBackButtonClicked = true;
toastShort(R.string.double_clikc_exit);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
isBackButtonClicked = false;
}
}, isDoubleClickExit);
} else {
super.onBackPressed();
}
}
滑动返回
private boolean mSlideBack = false;
private boolean isBackArrowShow = false;
private boolean isFirstShow = true;
public void setSlideBack(boolean slideBack){
mSlideBack = slideBack;
}
private float fx, fy; //手指按下的坐标
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
if (mSlideBack) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
fx = event.getX();
fy = event.getY();
//Log.d("MOTION", "按下" + event.getX() + " " + event.getY());
break;
case MotionEvent.ACTION_MOVE:
if (fx < 100) {
if (Math.abs(event.getY() - fy) < 900) {
showArrow();
} else {
removeArrow();
}
}
break;
case MotionEvent.ACTION_UP:
Log.d("MOTION", "松开" + event.getX() + " " + event.getY());
Log.d("MOTION", "距离" + Math.abs(event.getX() - fx ) + " " + Math.abs(event.getY() - fy));
if (isBackArrowShow) {
this.finish();
}
//手指松开,恢复原样
removeArrow();
isFirstShow = true;
break;
default:break;
}
}
return super.dispatchTouchEvent(event);
}
关闭所有Activity
1.BaseActivity中用一个栈记录所有打开的Activity
2.MainActivity设置启动模式为singleTask,重新调用MainActivity即可退出所有
3.本地广播通知所有Activity关闭
保存Activity状态
1.saveInstanceState
2.SharePreference
3.Jetpack ViewModel
class MyViewModel(var handle : SavedStateHandle) : ViewModel() {
init {
if (!handle.contains("NUMBER"))
handle.set("NUMBER", 0)
}
fun getNumber() : LiveData<Int> = handle.getLiveData("NUMBER")
fun add() {
val number : Int = handle.get("NUMBER")!!
handle.set("NUMBER", number + 1)
}
}
整理之Activity的更多相关文章
- Android学习整理之Activity生命周期篇
一.Activity生命周期说明 Activity的四种状态: ⒈活动状态(Active or Running):也称为运行状态,处于Activity栈顶,在用户界面中最上层,完全能被用户看到,能 ...
- Android学习整理之Activity篇
一.Activity概念介绍 activity属于android的四大组件之一(其他的三个: Content provider,Broadcast receiver,Service),它可以理解为一个 ...
- Android源代码学习之六——ActivityManager框架解析
ActivityManager在操作系统中有关键的数据,本文利用操作系统源代码,逐步理清ActivityManager的框架,并从静态类结构图和动态序列图两个角度分别进行剖析,从而帮助开发者加强对系统 ...
- View的三次measure,两次layout和一次draw
我在<Android视图结构>这篇文章中已经描述了Activity,Window和View在视图架构方面的关系.前天,我突然想到为什么在setContentView中能够调用findVie ...
- Android 插件化开发(四):插件化实现方案
在经过上面铺垫后,我们可以尝试整体实现一下插件化了.这里我们先介绍一下最简单的实现插件化的方案. 一.最简单的插件化实现方案 最简单的插件化实现方案,对四大组件都是适用的,技术面涉及如下: 1). 合 ...
- Android基础整理之四大组件Activity
最近准备系统的重新整理复习一下Android的各方面的知识,本着知识分享的原则,我就把梳理过程中一些东西给记录下来,权当一个学习笔记吧. 下面步入正题..... 什么是Activity Activit ...
- Android的Activity跳转动画各种效果整理
Android的Activity跳转就是很生硬的切换界面.其实Android的Activity跳转可以设置各种动画,本文整理了一些,还有很多动画效果,就要靠我们发挥自己的想象力 大家使用Android ...
- activity生命周期知识点整理
activity生命周期知识点整理 Activity: 是一个应用组件,用户可与其提供的屏幕进行交互.窗口通常会充满屏幕,但也可以小于屏幕并浮动在其他窗口之上. 一个activity的什么周期: 启动 ...
- Activity生命周期(待整理)
1. 定义 有一些方法共同定义生命周期,如下图示:(图片来自于官网文档) 2. onStart()——在Activity即将对用户可见之前调用 (1)Activity启动动画.二维动画在onStart ...
随机推荐
- 简单图解OSI七层网络模型
Open Systems Interconnection(OSI)定义了一个网络框架:其以层为单位实现了各种协议,同时会将控制权逐层传递. 目前OSI主要作为教学工具被使用,其在概念上将计算机网络结构 ...
- python读取数据写入excel的四种操作
Python对Excel的读写主要有:xlrd.xlwt.xlutils.openpyxl.xlsxwriter几种 xlutils结合xlrd: 操作的是以xls后缀的excel,读取文件保留原格式 ...
- ASP.NET Core下FreeSql的仓储事务
ASP.NET Core下FreeSql的仓储事务 第一步:配置 Startup.cs 注入 引入包 dotnet add package FreeSql dotnet add package Fre ...
- LAMP介绍以及Apache安装
一.LAMP架构介绍 1.1 LAMP概述 LAMP架构是目前成熟的企业网站应用模式之一,指的是协同工作的一整套系统和相关软件,能够提供动态Web站点服务及其应用开发环境.LAMP是一个缩写词,具体包 ...
- 【python与机器学习实战】感知机和支持向量机学习笔记(一)
对<Python与机器学习实战>一书阅读的记录,对于一些难以理解的地方查阅了资料辅以理解并补充和记录,重新梳理一下感知机和SVM的算法原理,加深记忆. 1.感知机 感知机的基本概念 感知机 ...
- jmeter正则表达式介绍
分三个层次介绍: 1. jmeter正则表达式有什么作用? 2. 正则表达式在哪? 3. 正则表达式怎么用? 1. jmeter正则表达式有什么作用? 答:提取请求中返回的数据, 然后获取的数据放入其 ...
- Android招聘市场技术要求越来越高,从事三年开发是否应该考虑转行?
这是在某论坛看到的一个网友的疑问,他说感觉现在Android 开发这条路越来越难走了.下面是他的分享: 本来已经做好了好几个月找不到工作的准备.不过这两周感觉面试机会还算可以.两周10个面试感觉刚刚好 ...
- 天梯赛 L1-058 6翻了
传送门:https://pintia.cn/problem-sets/994805046380707840/problems/1111914599408664577 这道字符串题,只是天梯赛L1的题, ...
- JVM内存调整
JVM内存调整 先试着调整一下idea的 找到软件安装位置/bin/idea64.exe.vmoptions 给他直接整个起飞的,改成 -Xms512m -Xmx1500m 找到Java安装的位置/j ...
- 【笔记】KNN之网格搜索与k近邻算法中更多超参数
网格搜索与k近邻算法中更多超参数 网格搜索与k近邻算法中更多超参数 网络搜索 前笔记中使用的for循环进行的网格搜索的方式,我们可以发现不同的超参数之间是存在一种依赖关系的,像是p这个超参数,只有在 ...