一、废话
今天十分的忙,本来打算今天就不写了,可是想想既然决定要做某件事情了,那么就要坚持下去。做不做是一个态度问题!
二、正文
1、Activity
在一个Android应用程序中,Activity是为用户操作而展示的可视化界面。比如你要打电话,这个时候的拨号界面就是一个Activity,你要发短信给你的女朋友,这个短信窗口就是一个Activity。Activity在创建之初只是一个没有任何内容的页面,如果要做出用户体验非常棒的应用程序,还需要在Activity中添加控件(如按钮,文字,图片)以显示和响应用户操作。
2、在Android中,多个Activity之间如何切换?
在Android 系统中,之所以一个Activiyt运行过程中可以运行另外的Activity,是因为Android在遇到这种情况后,会自动创建一个任务堆栈,并把这些关联的Activity压入堆栈中。在这个任务堆栈栈顶的Activity就是当前用户一直操作的Activity,而当一个新的Activity启动时,这个Activity就必须位于栈顶,而当前的Activity就会被压入栈的下一个位置。当系统发现内存不够用时,会默认清理一些长时间没有被使用的Activity存放栈。
打个比方,你在看微博,现在收到一条女朋友发来的微信,这个时候你打开微信,Android就会将微信的Activity压入栈并放在栈顶,使微信的Activity被激活,而把本来在栈顶的微博Activity压入栈中下一个位置。这样一来,当你按Back键时,微信Activity就会弹出栈,新浪Activity位于栈顶于是被激活。但是当你按下HOME键后,这些Activity都将转到后台运行,你使用Back是不能再次激活他们的,此时你必须点击应用程序才能再次激活它。
那么为什么微信Activity激活时,再按Back微博Activity能够再次激活?这就要从Activity的生命周期讲起了。
3、Activity的生命周期
一个Activity主要有三个状态:
- 激活状态(也就是用户操作的Activity)
- 暂停状态(有一个弹出窗口且没有完全挡住这个Activity)
- 停止状态(完全被其他的Activity挡住)
后两种情况都有可能在系统内存紧张时被系统Kill以释放内存。
当一个activity从创建到完全销毁要顺序完成下列七个方法:
- void onCreate(Bundle savedInstanceState)
- void onStart()
- void onRestart()
- void onResume()
- void onPause()
- void onStop()
- void onDestroy()
实现这些方法可以帮助你监察三个嵌套的生命周期循环:
- 一个activity 完整的生命周期 自第一次调用 onCreate()开始,直至调用onDestroy()为止。activity在onCreate()中设置所有“全局”状态以完成初始化,而在onDestroy()中释放所有系统资源。比如说,如果activity有一个线程在后台运行以从网络上下载数据,它会以 onCreate()创建那个线程,而以 onDestroy()销毁那个线程。
- 一个activity的 可视生命周期 自 onStart() 调用开始直到相应的 onStop()调用。在此期间,用户可以在屏幕上看到此activity,尽管它也许并不是位于前台或者正在与用户做交互。在这两个方法中,你可以管控用来向用户显示这个activity的资源。比如说,你可以在onStart() 中注册一个BroadcastReceiver 来监控会影响到你UI的改变,而在onStop() 中来取消注册,这时用户是无法看到你的程序显示的内容的。onStart() 和 onStop() 方法可以随着应用程序是否为用户可见而被多次调用。
- 一个activity的 前台生命周期 自 onResume() 调用起,至相应的 onPause()调用为止。在此期间,activity位于前台最上面并与用户进行交互。activity会经常在暂停和恢复之间进行状态转换──比如说当设备转入休眠状态或有新的activity启动时,将调用onPause() 方法。当activity获得结果或者接收到新的intent的时候会调用onResume() 方法。因此,在这两个方法中的代码应当是轻量级的。
在下图中你将能非常清晰的看到Activity的一个完整的生命周期以及在每个步骤中能够做什么。着色的椭圆是activity可以经历的主要状态。矩形框代表了当activity在状态间发生改变的时候,你进行操作所要实现的回调方法。
(摘自官网)
现在我们来回答下为什么Back键能够返回到上一个Activity。当一个新的Activity new遮盖(完全或者部分)了当前的Activity old后,当前Activity old会调用onStop()(完全遮盖)或者onPause()(部分遮盖),当点击Back键后,系统会将Activity new弹出栈,并调用Activity old 的onRestart()(完全遮盖)或者onResume()(部分遮盖)激活它。
4、Intent的概念及作用
Intent——意图,它可以带有数据,在Android设备上的任何应用程序组件间相互作用,将不同组件连在一起的桥梁。
Intent作用:
- Intent最常用在启动新的Activity,不管是显式的(通过指定类来加载)还是隐式的(通过请求在一块数据上执行的动作)。
- Intent还可以用来广播消息,然后使用Broadcast Receiver来监听并响应这些Intent。
- 使用Intent来传播动作,比如通过我们的程序中打电话。
5、Intent-filter的概念机作用
Intent-filter用来注册Activity、Service、Broadcast Receiver具有在某种数据上处理一个动作的能力。
当一个应用程序为了向Android说明它有为某种数据或者其他应用程序组件提供处理动作的能力时,它需要在manifest中注册为一个Intent处理者。
1 xml version="1.0" encoding="utf-8"?>
2 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
3 package="LiB.PickContacts" android:versionCode="1" android:versionName="1.0">
4 <uses-sdk android:minSdkVersion="9" />
5 <uses-permission android:name="android.permission.CALL_PHONE" />
6 <uses-permission android:name="android.permission.WRITE_CONTACTS" />
7 <uses-permission android:name="android.permission.READ_CONTACTS" />
8
9
10 <application android:icon="@drawable/icon" android:label="@string/app_name">
11 <activity android:name=".Android_PickContactsActivity"
12 android:label="@string/app_name">
13
14 <intent-filter>
15 <action android:name="android.intent.action.MAIN" />
16 <category android:name="android.intent.category.LAUNCHER" />
17 intent-filter>
18 activity>
19 <activity android:name=".ChileActivity" android:label="@string/app_name">
20
21 <intent-filter>
22 <action android:name="Action_picks" />
23 <category android:name="android.intent.category.DEFAULT" />
24
25 intent-filter>
26 activity>
27 application>
28 manifest>
❑ action
使用android:name特性来指定对响应的动作名。动作名必须是独一无二的字符串,所以,一个好的习惯是使用基于Java包的命名方式的命名系统。
❑ category
使用android:category属性用来指定在什么样的环境下动作才被响应。每个Intent Filter标签可以包含多个category标签。你可以指定自定义的种类或使用 Android提供的标准值,如下所示:
❑ ALTERNATIVE
你将在这章的后面所看到的,一个Intent Filter的用途是使用动作来帮忙填入上下文菜单。ALTERNATIVE种类指定,在某种数据类型的项目上可以替代 默认执行的动作。例如,一个联系人的默认动作时浏览它,替代的可能是去编辑或删除它。
❑ SELECTED_ALTERNATIVE
与ALTERNATIVE类似,但ALTERNATIVE总是使用下面所述的Intent解析来指向单一的动作。SELECTED_ALTERNATIVE在需要一个可能性列表时使用。
❑ BROWSABLE
指定在浏览器中的动作。当Intent在浏览器中被引发,都会被指定成BROWSABLE种类。
❑ DEFAULT
设置这个种类来让组件成为Intent Filter中定义的data的默认动作。这对使用显式Intent启动的Activity来说也是必要的。
❑ GADGET
通过设置GADGET种类,你可以指定这个Activity可以嵌入到其他的Activity来允许。
❑ HOME
HOME Activity是设备启动(登陆屏幕)时显示的第一个Activity。通过指定Intent Filter为HOME种类而不指定动作的话,你正在将其设为本地home画面的替代。
❑ LAUNCHER
使用这个种类来让一个Activity作为应用程序的启动项。
❑ data
data标签允许你指定组件能作用的数据的匹配;如果你的组件能处理多个的话,你可以包含多个条件。你可以使用下面属性的任意组合来指定组件支持的数据:
❑ android:host
指定一个有效的主机名(例如,com.google)。
❑ android:mimetype
允许你设定组件能处理的数据类型。例如,
❑ android:path
有效地URI路径值(例如,/transport/boats/)。
❑ android:port
特定主机上的有效端口。
❑ android:scheme
需要一个特殊的图示(例如,content或http)。
6、Intent显式激活Activity
所谓显式激活Activity,通常就是激活我们自己定义的Activity。这些Activity必须在manifest中定义。为了显式的启动一个Activity,必须要创建一个新的Intent,并指定当前应用程序的上下文和要启动的Activity类。然后使用startActivity(Intent intent)方法来启动。
1 //新建一个Intent
2 Intent intent=new Intent();
3 //为Intent附件一个数据
4 intent.putExtra("param",param);
5 //传入当前上下文和要启动的Activity
6 intent.setClass(Android03Activity.this, Android03_1.class);
7 //启动Activity——Android03_1
8 Android03Activity.this.startActivity(intent);
当在Android03_1这个Activity被激活后,如何取得我们在Android03Activity中为其传递的参数"param"?
1 Intent intent = getIntent();
2 String sum = intent.getStringExtra("param");
7、Intent隐式激活Activity
这种方式是一种不直接指明需要启动的应用程序组件(Activity),而是由系统根据Intent中所要执行的动作和所带的数据,通过Intent-filter来自动调用匹配最好的组件(Activity)。比如想让用户在我们的应用程序里打电话,就可以调用一个隐式的Intent来请求一个在某个电话号码上的打电话的动作。
1 String callData = "tel:"+"123456";
2 Uri callUri = Uri.parse(callData);
3 Intent callIntent = new Intent(Intent.ACTION_CALL, callUri);
4 startActivity(callIntent);
Android会解析这个Intent并启动一个能够提供打电话动作的Activity。
三、总结
今天总结了Activity和Intent,对于Android开发,最重要也是最基础的就是要理解Activity的布局以及Intent是如何在各个应用程序组件间传递消息的。笔记四种将开始介绍Activity中的一些常用组件。