列出android四个组件,Android四大组件之Activity

Android里边有四大组件的概念:即Activity、Service、Broadcast Receiver、Content Provider,而这四大组件中相对于iOS来讲 类似于Activity 对应Controller、 Broadcast Receiver 类似于 NSNotificationCenter,另两个Service 和 Content Provider 在iOS并没有可以与之对应的组件,平台的差异性由此可以体现出来。

本文记录Activity的相关知识以及与iOS的某些方面的异同:

一 生命周期:

ecd24771b8b7

官方文档.png

onCreate函数 ():函数是你进行初始化的地方,这个也是执行setContentView(View)函数的地方,setContentView(View)函数可以传入一个由XML编制的UI界面,可以使UI和具体实现完全分离。

onStart函数:该方法在 onCreate() 方法之后被调用, 当Activity被显示到屏幕上的时候调用此方法.

onResume()函数:在 Activity 从 Pause 状态转换到 Active 状态时被调用,,也就是能够获得用户的焦点之前调用此方法.

onRestart()函数:当Activity被停止后又被再次启动之前调用此方法.接着将调用onStart()方法.

onPause()函数:当第一个Activity通过Intent启动第二个Activity的时候,将调用第一个Activity的onPause()方法.然后调用第二个Activity的onCreate(),onStart(),onResume()方法,接着调用第一个Activity的onStop()方法.如果Activity重新获得焦点,则将调用onResume()方法;如果此Activity进入用户不可见状态,那么将调用onStop()方法.

onStop()函数:当第一个Activity被第二个Activity完全覆盖,或者被销毁的时候会调用此方法.如果此Activity还会与用户进行交互,将调用onRestart方法();如果此Activity将被销毁,那么将调用onDestroy()方法.

onDestroy()函数:Activity被销毁之前调用此方法.或者是调用finish()方法结束Activity的时候调用此方法.可以在此方法中进行收尾工作,比如释放资源等.

注意:重写某个Activity的这些回调方法的时候需要首先在第一行调用基类Activity的相应的回调方法.比如super.onCreate(),super.onStart()等等.

而iOS的生命周期如下,基本是一样的:

alloc: 创建对象,分配空间

init (initWithNibName): 初始化对象,初始化数据

loadView: 从nib载入视图 ,通常这一步不需要去干涉。除非你没有使用xib文件创建视图

viewDidLoad: 载入完成,可以进行自定义数据以及动态创建其他控件

viewWillAppear: 视图将出现在屏幕之前,马上这个视图就会被展现在屏幕上了

viewDidAppear 视图已在屏幕上渲染完成

当一个视图被移除屏幕并且销毁的时候的执行顺序,这个顺序差不多和上面的相反

viewWillDisappear 视图将被从屏幕上移除之前执行

viewDidDisappear 视图已经被从屏幕上移除,用户看不到这个视图了

dealloc 视图被销毁,此处需要对你在init和viewDidLoad中创建的对象进行释放

可以看出 其实Android和iOS的生命周期可以说是一一对应的

二 通信

通信的方式有很多种,例如:Intent、静态变量、SharedPreference等,此处暂时只讲Intent的方式通信,类比iOS 的

Android中的Activity依靠Intent的通信通信方式如下:

Intent是Android四大组件(Activity、Service、BroadcastReceiver、ContentProvider)之间通信的纽带,在Intent中携带数据也是四大组件之间数据通信最常用、最普通的方式。常规写法如下:

//创建用于封装数据的Bundle对象

Bundle bundle = new Bundle();

bundle.putString("name", "奥卡姆");

bundle.putInt("age", 25);

Intent intent = new Intent(MainActivity.this, SecondActivity.class);

//将Bundle对象嵌入Intent中

intent.putExtras(bundle);

下边的为比较简洁的方式

//创建Intent对象

Intent intent = new Intent(MainActivity.this, SecondActivity.class);

//程序自动创建Bundle,然后将对Intent添加的数据装载在Bundle中,对用户透明

intent.putExtra("name", "奥卡姆");

intent.putExtra("age", 25);

startActivity(intent);

然后再第二个Activity中获取数据:

//intent要用this的getIntent()获取

Intent intent = getIntent();

//用intent.getXXXExtra("key-name")或是intent.getXXXExtra("key-name", default-value)获取值

String name = intent.getStringExtra("key1");

int age = intent.getIntExtra("key2", 0);

iOS中的Controller(其实View也是类似)通信方式如下:

iOS的Controller中的通信方式就不依赖于另一个媒介了,可以实例化第二个Controller对象的时候,可以获取到属性直接赋值即可,非常方便。如下

// 实例化对象

let vc = SecondViewContoller()

// 给该对象的属性赋值

vc.str="second String"

// 跳转

self.navigationController?.pushViewController(vc, animated: true);

三 注册(Android特有)

所有的活动即activity必须要在AndroidManifest.xml中进行注册才能生效

在 application标签下声明添加

android:name=".MainActivity"

android:label="This is MainActivity" >

android:name=".SecondActivity"

android:label="This is SecondActivity" >

name:指定注册的活动,为com.exampleactivitytest.MainActivity的缩写,由于标签中已经通过package属性指明了程序的包名是com.example.activitytest,所以这里就简略写了.

label: 指定活动中标题栏的内容

在标签的内部的标签下的

和两句声明。

用于把该Activity作为本程序的主活动,即点击应用图标后首先打开的activity

若不是主活动,不需配置标签里的内容

若应用程序中没有声明任何一个活动作为主活动,该仍可正常安装的,只是无法在启动器中看到或者打开这个程序。一般都是作为第三方服务供其他的应用在内部进行调用的,类似某些应用快捷支付服务。

Q: 为什么Activity都必须要在AndroidManifest文件中注册呢

A: 官方回答:每个应用的根目录中都必须包含一个 AndroidManifest.xml 文件(且文件名精确无误)。 清单文件向 Android 系统提供应用的必要信息,系统必须具有这些信息方可运行应用的任何代码。此外,清单文件还可执行以下操作:

为应用的 Java 软件包命名。软件包名称充当应用的唯一标识符。

描述应用的各个组件,包括构成应用的 Activity、服务、广播接收器和内容提供程序。它还为实现每个组件的类命名并发布其功能,例如它们可以处理的 Intent 消息。这些声明向 Android 系统告知有关组件以及可以启动这些组件的条件的信息。

确定托管应用组件的进程。

声明应用必须具备哪些权限才能访问 API 中受保护的部分并与其他应用交互。还声明其他应用与该应用组件交互所需具备的权限

列出 Instrumentation 类,这些类可在应用运行时提供分析和其他信息。这些声明只会在应用处于开发阶段时出现在清单中,在应用发布之前将移除。

声明应用所需的最低 Android API 级别

列出应用必须链接到的库

四 Activity的任务栈

应用内的Activity是被任务栈Task来管理的,一个Task中的Activity可以来自不同的应用,同一个应用的Activity也可能不在同一个Task中。默认情况下,任务栈依据栈的后进先出原则管理Activity,但是Activity可以设置一些“特权”打破默认的规则,主要是通过在AndroidManifest文件中的属性android:launchMode或者通过Intent的flag来设置。

standard:默认的启动模式,该模式下会生成一个新的Activity,同时将该Activity实例压入到栈中(不管该Activity是否已经存在在Task栈中,都是采用new操作)。例如: 栈中顺序是A B C D ,此时D通过Intent跳转到A,那么栈中结构就变成 A B C D A,点击返回按钮的 显示顺序是 D C B A,依次摧毁。

singleTop:在singleTop模式下,如果当前Activity D位于栈顶,此时通过Intent跳转到它本身的Activity(即D),那么不会重新创建一个新的D实例(走onNewIntent()),所以栈中的结构依旧为A B C D,如果跳转到B,那么由于B不处于栈顶,所以会新建一个B实例并压入到栈中,结构就变成了A B C D B。应用实例:三条推送,点进去都是一个activity。

singleTask: 在singleTask模式下,Task栈中只能有一个对应Activity的实例。例如:现在栈的结构为A B C D,此时D通过Intent跳转到B(走onNewIntent()),则栈的结构变成了:A B。其中的C和D被栈弹出销毁了,也就是说位于B之上的实例都被销毁了。如果系统已经存在一个实例,系统就会将请求发送到这个实例上,但这个时候,系统就不会再调用通常情况下我们处理请求数据的onCreate方法,而是调用onNewIntent方法。通常应用于首页,首页肯定得在栈底部,也只能在栈底部。

singleInstance: singleInstance模式下会将打开的Activity压入一个新建的任务栈中。例如:Task栈1中结构为:A B C,C通过Intent跳转到了D(D的启动模式为singleInstance),那么则会新建一个Task 栈2,栈1中结构依旧为A B C,栈2中结构为D,此时屏幕中显示D,之后D通过Intent跳转到D,栈2中不会压入新的D,所以2个栈中的情况没发生改变。如果D跳转到了C,那么就会根据C对应的启动模式在栈1中进行对应的操作,C如果为standard,那么D跳转到C,栈1的结构为A B C C,此时点击返回按钮,还是在C,栈1的结构变为A B C,而不会回到D。

Intent Flag 启动模式

1、Intent.FLAG_ACTIVITY_NEW_TASK: 使用一个新的task来启动Activity,一般用在service中启动Activity的场景,因为service中并不存在Activity栈。

2、Intent.FLAG_ACTIVITY_SINGLE_TOP : 类似andoid:launchMode="singleTop"

3、Intent.FLAG_ACTIVITY_CLEAR_TOP :类似andoid:launchMode="singleTask"

4、Intent.FLAG_ACTIVITY_NO_HISTORY :使用这种模式启动Activity,当该Activity启动其他Activity后,该Activity就消失了,不会保留在task栈中。例如A B,在B中以这种模式启动C,C再启动D,则当前的task栈变成A B D。

清空任务栈

1、clearTaskOnLaunch: 每次返回该Activity时,都将该Activity之上的所有Activity都清除。通过这个属性可以让task每次在初始化的时候都只有这一个Activity。

2、finishOnTaskLaunch: clearTaskOnLaunch作用在别的Activity身上,而finishOnTaskLaunch作用在自己身上。通过这个属性,当离开这个Activity所在的task,那么当用户再返回时,该Activity就会被finish掉。

3、alwaysRetainTaskState:如果将Activity的这个属性设置为true,那么该Activity所在的task将不接受任何清理命令,一直保持当前task状态,相当于给了task一道”免死金牌”。

五 IntentFilter的匹配模式

(1) IntentFilter中的过滤信息有action、category、data;

为了匹配过滤列表,需要同时匹配过滤列表中的action、category、data信息,否则匹配失败。一个过滤列表中的action、category、data可以有多个,所有的action、category、data分别构成不同类别,同一类别的信息共同约束当前类别的匹配过程。只有一个Intent同时匹配action类别、category类别和data类别才算完全匹配,只有完全匹配才能成功启动目标Activity。此外,一个Activity中可以有多个intent-filter,一个Intent只要能匹配任何一组intenf-filter即可成功启动对应的Activity。

(2) action匹配规则

只要Intent中的action能够和过滤规则中的任何一个action相同即可匹配成功,action匹配区分大小写。

(3) category匹配规则

Intent 中如果有 category 那么所有的 category 都必须和过滤规则中的其中一个category相同,如果没有category的话那么就是默认的category,即android.intent.category.DEFAULT,所以为了Activity能够接收隐式调用,配置多个category的时候必须加上默认的category

(4) data匹配规则

data匹配规则:Intent中必须含有data数据,并且data数据能够完全匹配过滤规则中的某一个data。

如果要为Intent指定完整的data,必须要调用setDataAndType方法!

六 一些关于Activity的技巧

1、锁定Activity屏幕的运行方向

android:label="@string/app_name"

android:screenOrientation="portrait">// 竖屏 , 值为 landscape 时为横屏

2、全屏的Activity

// 设置全屏模式

getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,

WindowManager.LayoutParams.FLAG_FULLSCREEN);

// 去除标题栏

requestWindowFeature(Window.FEATURE_NO_TITLE);

3、在Activity的title中加入进度条

// 不明确进度条

requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);

setContentView(R.layout.main);

setProgressBarIndeterminateVisibility(true);

// 明确进度条

requestWindowFeature(Window.FEATURE_PROGRESS);

setContentView(R.layout.main);

setProgress(5000);

安卓相关文章阅读

参考:《Android开发艺术探索》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值