Activity 必知必会【Android 专题 4】

举报
坚果的博客 发表于 2021/12/14 08:08:34 2021/12/14
【摘要】 Activity 必知必会Activity是Android的四大组件之一,Activity是一种能够显示用户界面的组件,用户通过和Activity交互完成相关操作。一个应用中可以包含0个或多个 Activity,但不包含任何 Activity 的应用程序是无法被用户看见的。 Tips1. Activity用于显示用户界面,用户通过Activity交互完成相关操作2. 一个App允许有多个Ac...

Activity 必知必会

Activity是Android的四大组件之一,Activity是一种能够显示用户界面的组件,用户通过和Activity交互完成相关操作。

一个应用中可以包含0个或多个 Activity,但不包含任何 Activity 的应用程序是无法被用户看见的。


Tips


1. Activity用于显示用户界面,用户通过Activity交互完成相关操作

2. 一个App允许有多个Activity


Activity 生命周期

android_activity_lifecycle

Activity 的七个回调方法,覆盖了 Activity 生命周期的每一个环节,下面就来介绍一下这7个方法。

onCreate()

该方法会在 Activity 第一次创建时进行调用,在这个方法中通常会做 Activity 初始化相关的操作,例如:加载布局、绑定事件等。

onStart()

这个方法会在 Activity 由不可见变为可见的时候调用,但是还不能和用户进行交互。

onResume()

表示Activity已经启动完成,进入到了前台,可以同用户进行交互了。

onPause()

这个方法在系统准备去启动另一个 Activity 的时候调用。可以在这里释放系统资源,动画的停止,不宜在此做耗时操作。

onStop()

当Activity不可见的时候回调此方法。需要在这里释放全部用户使用不到的资源。可以做较重量级的工作,如对注册广播的解注册,对一些状态数据的存储。此时Activity还不会被销毁掉,而是保持在内存中,但随时都会被回收。通常发生在启动另一个Activity或切换到后台时

onDestroy()

Activity即将被销毁。此时必须主动释放掉所有占用的资源。

onRestart()

这个方法在 Activity 由停止状态变为运行状态之前调用,也就是 Activity 被重新启动了(APP切到后台会进入onStop(), 再切换到前台时会触发onRestart()方法)

Activity组件注册

四大组件需要在AndroidManifest文件中配置否则无法使用,类似Activity无法启动,

一般情况下: 在新建一个activity后,为了使intent可以调用此活动,我们要在androidManifest.xml文件中添加一个标签,标签的一般格式如下:

 <activity
            android:name=".MainActivity"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
  </activity>
  • android:name是对应Activity的类名称

  • android:label是Activity标题栏显示的内容. 现已不推荐使用

  • 是意图过滤器. 常用语隐式跳转

  • 是动作名称,是指intent要执行的动作

  • 是过滤器的类别 一般情况下,每个 中都要显示指定一个默认的类别名称,即<category android:name="android.intent.category.DEFAULT" />

但是上面的代码中没有指定默认类别名称,这是一个例外情况,因为其 中的是"android.intent.action.MAIN",意思是这个Activity是应用程序的入口点,这种情况下可以不加默认类别名称。

Activity启动与参数传递


Tips


在Android中我们可以通过下面两种方式来启动一个新的Activity,注意这里是怎么启动,分为显示启动和隐式启动!

1. 显式启动:通过包名来启动,写法如下:

最常见的:startActivity

①:常规跳转
val intent = Intent(MainActivity.this,SecondActivity.class)
startActivity(intent);
​
②:携带参数启动新Activity
val intent = Intent(MainActivity.this,SecondActivity.class)
intent.putExtra("extra_data", "extra_data")
intent.putExtra("extra_int_data", 100)
startActivity(intent);

期待从目标页获取数据:startActivityForResult---->比如启动相册获取图片

①假设从A--->B页面,以startActivityForResult方式启动
val intent = Intent(MainActivity.this,SecondActivity.class)
startActivityForResult(intent,100);
​
②如果B页面返回时,调用了 
setResult(Activity.RESULT_OK,resultIntent)
finish()
​
③则A页面会回调下面的方法,在该回调里可以拿到返回的数据data
onActivityResult(requestCode: Int, resultCode: Int, data: Intent?)

2. 隐式启动

隐式 Intent 要比显示 Intent 含蓄的多,他并不明确指定要启动哪个 Activity,而是通过指定 actioncategory 的信息,让系统去分析这个 Intent,并找出合适的 Activity 去启动。

 <activity android:name=".SecondActivity">
     <intent-filter>
         <action android:name="com.example.firstapp.action.SecondActivity" />
         <category android:name="com.example.firstapp.category.SecondActivity" />
         <category android:name="android.intent.category.DEFAULT" /> // 一定要有
     </intent-filter>
</activity>
val intent = Intent()
intent.setAction("com.example.firstapp.action.SecondActivity")
intent.setCategory("com.example.firstapp.category.SecondActivity")
​
intent.putExtra("extra_data", "extra_data")
intent.putExtra("extra_int_data", 100)
startActivity(intent);
​
startActivityForResult(intent,100);

系统给我们提供的一些常见的Activtiy

拨打电话

给移动客服10086拨打电话

Uri uri = Uri.parse("tel:10086");
Intent intent = new Intent(Intent.ACTION_DIAL, uri);
startActivity(intent);

发送短信

给10086发送内容为“Hello”的短信

Uri uri = Uri.parse("smsto:10086");
Intent intent = new Intent(Intent.ACTION_SENDTO, uri);
intent.putExtra("sms_body", "Hello");
startActivity(intent);

打开浏览器:

打开baidu主页

Uri uri = Uri.parse("http://www.baidu.com");
Intent intent  = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);

多媒体播放:

Intent intent = new Intent(Intent.ACTION_VIEW);
Uri uri = Uri.parse("file:///sdcard/foo.mp3");
intent.setDataAndType(uri, "audio/mp3");
startActivity(intent);

打开摄像头拍照:

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
startActivityForResult(intent, 0);
​
>>> 在Activity的onActivityResult方法回调中取出照片数据
Bundle extras = intent.getExtras(); 
Bitmap bitmap = (Bitmap) extras.get("data");

从图库选图并剪切

// 获取并剪切图片
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
intent.putExtra("crop", "true"); // 开启剪切
intent.putExtra("aspectX", 1); // 剪切的宽高比为1:2
intent.putExtra("aspectY", 2);
intent.putExtra("outputX", 20); // 保存图片的宽和高
intent.putExtra("outputY", 40); 
intent.putExtra("output", Uri.fromFile(new File("/mnt/sdcard/temp"))); // 保存路径
intent.putExtra("outputFormat", "JPEG");// 返回格式
startActivityForResult(intent, 0);
​
>>>>  在Activity的onActivityResult方法中去读取保存的文件

剪切指定图片文件

Intent intent = new Intent("com.android.camera.action.CROP"); 
intent.setClassName("com.android.camera", "com.android.camera.CropImage"); 
intent.setData(Uri.fromFile(new File("/mnt/sdcard/temp"))); 
intent.putExtra("outputX", 1); // 剪切的宽高比为1:2
intent.putExtra("outputY", 2);
intent.putExtra("aspectX", 20); // 保存图片的宽和高
intent.putExtra("aspectY", 40);
intent.putExtra("scale", true);
intent.putExtra("noFaceDetection", true); 
intent.putExtra("output", Uri.parse("file:///mnt/sdcard/temp")); 
startActivityForResult(intent, 0);
​
>>>>  在Activity的onActivityResult方法中去读取保存的文件

进入手机的无线网络设置页面

// 进入无线网络设置界面(其它可以举一反三)  
Intent intent = new Intent(android.provider.Settings.ACTION_WIRELESS_SETTINGS);  
startActivityForResult(intent, 0);

Activity四种启动模式

standard

默认值,多实例模式。每启动一次,都会创建一个新的Activity实例。

启动的生命周期为:onCreate()->onStart()->onResume()

standard

singleTop

栈顶复用模式

如果任务栈顶已经存在需要启动的目标Activity,则直接启动,并会回调onNewIntent()方法,生命周期顺序为: onPause() ->onNewIntent()->onResume()

如果任务栈上顶没有需要启动的目标Activity,则创建新的实例,此时生命周期顺序为: onCreate()->onStart()->onResume()

两种情况如下图,从图中可以看出,此模式下还是会出现多实例,只要启动的目标Activity不在栈顶的话。

img

singleTask

栈内复用模式,一个任务栈只能有一个实例。

有几种情况:

  • 当启动的Activity目标任务栈不存在时,则以此启动Activity为根Activity创建目标任务栈,并切换到前面

  • D为singleTask模式

    img

  • 当启动的Activity存在时,则会直接切换到Activity所在的任务栈,并且任务栈中在Activity上面的所有其他Activity都出栈(调用destroy()),此时启动的Activity位于任务栈顶,并且会回调onNewIntent()方法。

    img

singleInstance

singleInstance名称是单例模式,即App运行时,该Activity只有一个实例。既然只有一个,那么也就说明很重要、很特殊,我们需要将其“保护起来”。单例模式的“保护措施”是将其单独放到一个任务栈中。。

img

Intent FLag设定启动模式

除了可以在manifest中设置Activity的启动模式,也可以通过设置Intent的flag标识来设定Activity的启动模式。

常用的有:FLAG_ACTIVITY_NEW_TASK,FLAG_ACTIVITY_SINGLE_TOP,FLAG_ACTIVITY_CLEAR_TOP

FLAG_ACTIVITY_NEW_TASK

启动Activity时,如果不存在Activity的实例,则会以此Activity为根Activity创建新的任务栈,如果存在的话则直接切换到对应的Activity实例,并回调onNewIntent()方法。相当于“singleTask”启动模式。

FLAG_ACTIVITY_SINGLE_TOP

相当于“singleTop”模式

FLAG_ACTIVITY_CLEAR_TOP

设置此标识的Activity在启动时,如果当前的任务栈内存在此Activity实例,则跳转到此实例,并清除掉在此实例上面的所有Activity实例,此时此Activity实例位于任务栈的栈顶

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

举报
请填写举报理由
0/200