2025年4月1日 星期二 乙巳(蛇)年 正月初二 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > 安卓(android)开发

Android 中的 Activity 介绍和使用

时间:12-14来源:作者:点击数:2

一、 activity 的生命周期

正常生命周期
1.正常打开单个 Activity,然后退出应用:

这种情况是最普通的状况,Activity 的生命周期会按照上图从上到下的方式走。即:onCreate --> onStart --> onResume --> 运行--> 按返回键结束程序--> onPause-->onStop-->onDestory

2.打开一个 Activity A,然后再打开另一个 Activity B

对于A:onCreate --> onStart --> onResume --> A运行 --> A发出打开B的Intent --> onPause-->B可见-->onStop

此时,会打开B,B同样会经历一个完整的 Activity 生命周期。等B结束,A再度可见的时候,A会经历:onRestart-->onStart-->onResume

注意:B 这个 Activity 是在 A 的 onPause 执行后才变成可见状态的,所以为了不影响B的显示,最好不要在 onPause 里执行一些耗时操作,可以考虑将这些操作放到 onStop 里,这时 B 已经可见了。

异常情况生命周期
情况1:资源相关的系统配置发生改变

资源相关的系统配置发生改变,举个例子。当前 Activity 处于竖屏状态的时候突然转成横屏,系统配置发生了改变,Activity 就会销毁并且重建,其 onPause, onStop,  onDestory 均会被调用。因为实在异常情况下终止的,所以系统会调用 onSaveInstanceState 来保存当前 Activity 状态。这个方法是在 onStop 之前,与 onPause 没有固定的时序关系。当Activity重建的时候系统会把 onSaveInstanceState 所保存的 Bundle 作为对象传递给 onRestoreInstanceState 和 onCreate 方法。

情况2:资源内存不足导致低优先级 Activity 被杀死

Activity 优先级

前台 Activity ——正在和用户交互的 Activity,优先级最高

可见但非前台 Activity——Activity 中弹出的对话框导致 Activity 可见但无法交互

后台 Activity ——已经被暂停的 Activity,优先级最低

系统内存不足是,会按照以上顺序杀死 Activity,并通过 onSaveInstanceState 和 onRestoreInstanceState 这两个方法来存储和恢复数据。

onSaveInstanceState

onSaveInstanceState 在 onStop 之前调用,但不一定在 onPause 之前或者之后。onRestoreInstanceState 在 onStart 之后调用

需要注意的是,onSaveInstanceState 方法只会在 Activity 被异常终止,在 Activity 即将被销毁且有机会重新显示的情况下才会调用

可以总结有下面几种情况

1、当用户按下 HOME 键时。

这是显而易见的,系统不知道你按下HOME后要运行多少其他的程序,自然也不知道activity A是否会被销毁,故系统会调用onSaveInstanceState,让用户有机会保存某些非永久性的数据。以下几种情况的分析都遵循该原则

2、长按 HOME 键,选择运行其他的程序时。

3、按下电源按键(关闭屏幕显示)时。

4、从activity A中启动一个新的 activity 时。

5、屏幕方向切换时,例如从竖屏切换到横屏时。(如果不指定 configchange 属性) 在屏幕切换之前,系统会销毁 activity A,在屏幕切换之后系统又会自动地创建 activity A,所以 onSaveInstanceState 一定会被执行

总而言之,onSaveInstanceState 的调用遵循一个重要原则,即当系统 未经你许可 时销毁了你的 activity,则 onSaveInstanceState 会被系统调用,这是系统的责任,因为它必须要提供一个机会让你保存你的数据

二、activity 的启动模式

四种启动模式分别是 standard(标准模式)、singleTop(栈顶复用模式)、singleTask(栈内复用模式)、singleInstance(单实例模式 - 加强的 singleTask 模式)

standard
  • 系统默认启动模式
  • 不论存在与否,都会重新创建一个新的实例
  • 多实例实现,谁启动了这个 Activity、那么这个 Activity 就运行在启动它那个Activity所在栈
singleTop
  • 判断需要启动的 Activity 是否为任务栈栈顶 ,如果是,则不会重新创建,如果不是,则会重新创建
  • 不重新创建时候,该 Activity 的 onNewIntent(Intent intent) 方法会被回调,通过该方法的参数,可以取出当前请求的信息;
  • 系统可能会杀死该 Activity,杀死之后,启动情况与第一次启动相同,所以有必要在 onCreate 与 onNewIntent 方法中调用同一个处理数据的方法

运用场景:常运用于通知栏弹出 Notification,点击 Notification 跳转到指定的Activity,设置 singleTop 模式

singleTask
  • 判断Activity所需任务栈内是否已经存在,如果存在,就把该Activity切换到栈顶(会导致在它之上的都会出栈)
  • 如果所需任务栈都不存在,就会先创建任务栈再创建该Activity
  • 可以理解为 顶置Activity+singleTop 的模式

运用场景:可用来退出整个应用。主界面 activity 设为 singleTas 模式,要退出应用时转到主 activity,从而将主 activity 之上的 activity 都清除,然后重写主 activity 的 onNewIntent() 方法,在里面加上 finish(),即可退出所有 activity。这种模式还适用于做浏览器、微博之类的应用

singleInstance
  • 拥有 singleTask 的所有特性之外,此模式 Activity 只能单独地位于一个新的任务栈中
  • 也就是,Activity 启动之后,就会独自在一个新的任务栈中,下次肯定不会重新创建该Activity,除非被系统杀死

运用场景:这种模式常运用于需要与程序分离的界面,如在 SetupWizard(安装向导)中调用紧急呼叫就是适用这种模式

三、Intent 和 Intent-filter 的匹配规则

1、Intent 和 Intent Filter 的介绍

Intent 是抽象的数据结构,包含了一系列描述某个操作的数据,使得程序在运行时可以在程序中不同组件间通信或启动不同的应用程序。

可以通过startActivity(Intent)启动一个 Activity,sendBroadcast(Intent))发送广播发送给感兴趣的 BroadcastReceiver 组件,startService(android.content.Intent))启动 service,bindService() 绑定服务。

Intent Filter 顾名思义就是 Intent 的过滤器,组件通过定义Intent Filter可以决定哪些隐式Intent可以和该组件进行通讯

Intent分为隐式(implicit)Intent和显式(explicit)Intent。

显式Intent通常用于在程序内部组件间通信,已经明确的定义目标组件的信息,所以不需要系统决策哪个目标组件处理 Intent,如下

  • Intent intent =new Intent(CRListDemo.this, GoogleMapDemo.class);
  • startActivity(intent);

其中 CRListDemo 和 GoogleMapDemo 都是用户自定义的组件,隐式 Intent 不指明目标组件的 class,只定义希望的 Action 及 Data 等相关信息,由系统决定使用哪个目标组件。如发送短信

2.Intent 和 Intent-filter 的匹配规则

Android 系统通过对 Intent 和目标组件在 AndroidManifest 文件中定义的(也可以在程序中定义Intent Filter)进行匹配决定和哪个目标组件通讯。如果某组件未定义则只能通过显式的Intent进行通信。Intent 的三个属性用于对目标组件选取的决策,分别是Action、Data(Uri 和 Data Type)、Category。匹配规则如下

  • action 匹配规则:要求 intent 中的 action 存在 且 必须和过滤规则中的其中一个相同 区分大小写;
  • category 匹配规则:系统会默认加上一个 android.intent.category.DEAFAULT,所以intent中可以不存在 category,但如果存在就必须匹配其中一个;
  • data 匹配规则:data 由两部分组成,mimeType 和 URI,要求和 action 相似。如果没有指定URI,URI但默认值为 content 和 file(schema)
3.利用 Intent 调用其他常见程序

a. 发送短信

  • Uri uri = Uri.parse("smsto:15800000000");
  • Intent i=newIntent(Intent.ACTION_SENDTO, uri);
  • i.putExtra("sms_body", "The SMS text");
  • startActivity(i);

b. 打电话

  • Uri dial = Uri.parse("tel:15800000000");
  • Intent i=newIntent(Intent.ACTION_DIAL, dial);
  • startActivity(i);

c. 发送邮件

  • Uri email = Uri.parse("mailto:abc@126.com;def@126.com");
  • Intent i=newIntent(Intent.ACTION_SENDTO, email);
  • startActivity(i);

d. 拍照

  • Intent i =newIntent(MediaStore.ACTION_IMAGE_CAPTURE);
  • String folderPath= Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "AndroidDemo" +File.separator;
  • String filePath= folderPath + System.currentTimeMillis() + ".jpg";newFile(folderPath).mkdirs();
  • File camerFile=newFile(filePath);
  • i.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(camerFile));
  • startActivityForResult(i,1);

e. 浏览网页

  • Uri web = Uri.parse("http://www.google.com");
  • Intent i=newIntent(Intent.ACTION_VIEW, web);
  • startActivity(i);

f. 查看联系人

  • Intent i =newIntent();
  • i.setAction(Intent.ACTION_GET_CONTENT);
  • i.setType("vnd.android.cursor.item/phone");
  • startActivityForResult(i,1);
方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门
本栏推荐