标签:
Activity:活动,是Android四大组件之一。在Android中,Activity代表手机屏幕的一屏,或是平板电脑中的一个窗口,它上面可以显示一些控件也可以监听并处理用户的事件做出响应。Activity之间通过Intent进行通信。
Activity是一个负责与用户交互的组件,Android程序的设计讲究逻辑和视图分离,可以通过setContentView(View)来显示指定视图。
如果是在 XML中引用一个 id,就使用@id/id_name这种语法,如果是在 XML中 定义一个 id,则要使用@+id/id_name 这种语法。
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.helloworld" android:versionCode="1" android:versionName="1.0" >
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="19" />
<application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <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> </application> </manifest> |
通过清单文件中的以上代码可知:
1)最外层的<manifest>标签中通过 package 属性指定了程序的包名com.example.helloworld,因此在注册活动时可以省略包名,直接使用.MainActivity.
2)android:label指定活动中标题栏的内容,标题栏是显示在活动最顶部的,注意的是,给主活动指定的 label不仅会成为标题栏中的内容,还会成为启动器(Launcher)中应用程序显示的名称。
3) intent-filter里的两行代码
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER"
表示 MainActivity是这个项目的主活动,在手机上点击应用图标,首先启动的就是这个活动。
方法一:在 onCreate()方法中添加如下代码:
requestWindowFeature(Window.FEATURE_NO_TITLE);
注意这句代码一定要在 setContentView()之前执行,不然会报错。
方法二:可以将整个应用设置成无标题栏
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@android:style/Theme.NoTitleBar" >
主要通过两个步骤完成:
1)onCreateOptionsMenu():在活动 中创建菜单
@Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); return true;//表示允许显示创建的菜单 } |
2)onOptionsItemSelected():定义菜单响应事件
Intent表示意图的意思,是Android各组件之间进行交互的一种重要方式,它不仅可以指明当前组件想要执行的动作,还可以在不同组件之间传递数据。Intent可被用于启动活动、启动服务、以及发送广播。Intent的用法大致可以分为两种,显式 Intent和隐式 Intent。
显示intent通过组件的ComponentName来指定目标组件。应用程序在自己内部跳转的时候,一般用显式意图。效率高。
Intent(ContextpackageContext,Class<?>cls)
这个构造函数接收两个参数,第一个参数 Context要求提供一个启动活动的上下文,第二个参数 Class则是指定想要启动的目标活动,通过这个构造函数就可以构建出 Intent的“意图”。
Intent intent = new Intent(FirstActivity.this, SecondActivity.class); startActivity(intent);
隐式intent不指定组件的名称。一般应用在跳转到其他应用中的某个界面,或者自己的应用界面想被其他应用打开。 效率低。
隐式 Intent它并不明确指出我们想要启动哪一个活动,而是指定了一系列更为抽象的action和category等信息,然后交由系统去分析这个Intent, 并帮我们找出合适的活动去启动。
通过在<activity>标签下配置<intent-filter>的内容,可以指定当前活动能够响应的 action 和 category,打开 AndroidManifest.xml,添加如下代码:
<activity android:name=".SecondActivity" > <intent-filter> <action android:name="com.example.activitytest.ACTION_START" />
<category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity> |
<action>标签
指明当前活动可以响应 com.example.activitytest.ACTION_ START这个 action,<category>标签
包含了一些附加信息,更精确地指明了当前的活动能够响应的 Intent中还可能带有的 category。
只有<action>和<category>中的内容同时能够匹配上 Intent中指定的 action和 category时,这个活动才能响应该 Intent。
如下,在FirstActivity中定义button1按钮的点击事件,代码如下所示:
button1.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent( "com.example.activitytest.ACTION_START"); startActivity(intent); } });
可以看到,我们使用了 Intent的另一个构造函数,直接将 action的字符串传了进去,表明要启动能够响应 com.example.activitytest.ACTION_START这个 action的活动。至于这里有指定 category是因为 android.intent.category.DEFAULT 是一种默认的 category,在调用 startActivity()方法的时候会自动将这个 category添加到 Intent中。
每个Intent中只能指定一个 action,但却能指定多个category。修改 FirstActivity中按钮的点击事件,代码如下所示:
button1.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Intentintent = newIntent("com.example.activitytest.ACTION_START"); // 默认的category 可以省略,所以这里实际指定了连个category // intent.addCategory("com.example.activitytest.MY_CATEGORY"); startActivity(intent); } });
如上,调用Intent中的 addCategory()方法来添加一个 category,这里指定了一个自定义的 category,值为com.example.activitytest.MY_CATEGORY。
接着在<intent-filter>中再添加一个 category的声明,如下所示:
<activity android:name=".SecondActivity" > <intent-filter> <action android:name="com.example.activitytest.ACTION_START" />
<category android:name="android.intent.category.DEFAULT" /> <category android:name="com.example.activitytest.MY_CATEGORY" /> </intent-filter> </activity> |
使用隐式 Intent不仅可以启动自己程序内的活动,还可以启动其他程序的活动。
1)启动系统的浏览器
Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData(Uri.parse("http://www.baidu.com")); startActivity(intent); |
这里首先指定了 Intent的 action是 Intent.ACTION_VIEW,这是一个 Android系统内置的动作,其常量值为 android.intent.action.VIEW。然后通过 Uri.parse()方法,将一个网址字符串解析成一个 Uri对象,再调用 Intent的 setData()方法将这个 Uri对象传递进去。
2)启动系统打电话的功能:
Intent intent = new Intent(Intent.ACTION_DIAL); intent.setData(Uri.parse("tel:10086")); |
方法介绍:
setData(data):
data: Uri对象,主要用于指定当前 Intent操作的数据,这些数据通常都是以字符串的形式传入到 Uri.parse()方法中解析产生的.
与此对应,我们还可以在<intent-filter>标签中再配置一个<data>标签,用于更精确地指 定当前活动能够响应什么类型的数据。
<data>标签中主要可以配置以下内容。
1. android:scheme 用于指定数据的协议部分,如上例中的 http部分。
2. android:host 用于指定数据的主机名部分,如上例中的 www.baidu.com部分。
3. android:port 用于指定数据的端口部分,一般紧随在主机名之后。
4. android:path 用于指定主机名和端口之后的部分,如一段网址中跟在域名之后的内容。
5. android:mimeType用于指定可以处理的数据类型,允许使用通配符的方式进行指定。
只有<data>标签中指定的内容和 Intent中携带的 Data完全一致时,当前活动才能够响应 该 Intent.
Intent中提供了一系列putExtra()方法的重载,可以把我们想要传递的数据暂存在Intent中,启动了另一个活动后,只需要把这些数据再从Intent中取出就可以了。
如下,把 FirstActivity 中的一个字符串传递到SecondActivity中:
button1.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { String data = "Hello SecondActivity"; Intent intent = new Intent(FirstActivity.this, SecondActivity.class); intent.putExtra("extra_data", data); startActivity(intent); } });
putExtra(key,value):
第一个参数是键,用于后面从 Intent 中取值
第二个参数才是真正要传递的数据。
然后我们在 SecondActivity中将传递的数据取出,代码如下所示:
public class SecondActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.second_layout); Intent intent = getIntent(); String data = intent.getStringExtra("extra_data"); } }
首先通过 getIntent()方法获取到用于启动SecondActivity 的Intent,然后调用getStringExtra()方法,传入相应的键值,就可以得到传递的数据了。如果传递的是字符串数据,则使用getStringExtra()方法来获取传递的数据,如果传递的是整型数据,则使用getIntExtra()方法,传递的是布尔型数据,则使用getBooleanExtra()方法,以此类推。
①使用Activity中的startActivityForResult() 方法,这个方法期望在活动销毁的时候能够返回一个结果给上一个活动。
startActivityForResult(intent, requestCode):
第一个参数还是 Intent,表示要启动的activity;
第二个参数是请求码,用于在之后的回调中判断数据的来源。
修改 FirstActivity中按钮的点击事件,代码如下所示:
button1.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(FirstActivity.this, SecondActivity.class); startActivityForResult(intent, 1); } });
这里我们使用了 startActivityForResult()方法来启动SecondActivity,请求码只要是一个唯一值就可以了,这里传入了1。
②设置返回结果
要返回信息给FirstActivity,需要通过setResult(resultCode, data)方法,
setResult(resultCode, data):
resultCode:用于向上一个活动返回处理结果,一般只使用RESULT_OK或RESULT_CANCELED这两个值。
data:把带有数据的 Intent传递回去。
接下来我们在 SecondActivity中给按钮注册点击事件,并在点击事件中添加返回数据的逻辑,代码如下所示:
class SecondActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.second_layout); Button button2 = (Button) findViewById(R.id.button_2); button2.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(); intent.putExtra("data_return", "Hello FirstActivity"); setResult(RESULT_OK, intent); finish(); } }); } }
通过代码可知了,构建一个 Intent把要传递的数据存放在 Intent中,然后调用了setResult() 方法,用于向上一个活动返回数据。
③处理返回结果—onActivityResult()
当在Activity中调用startActivityForResult()启动另一个Activity后,当从另一个Activity返回到当前Activity时,便会回调onActivityResult()方法来处理返回结果。
onActivityResult(int requestCode, int resultCode, Intent data):
requestCode,在启动活动时传入的请求码。
resultCode,在返回数据时传入的处理结果。
data,即携带着返回数据的Intent。
如下:使用startActivityForResult来启动SecondActivity,在SecondActivity被销毁之后会回调上一个活动的onActivityResult()方法,因此我们需要FirstActivity中重写这个方法来得到返回的数据,如下所示:
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case 1: if (resultCode == RESULT_OK) { String returnedData = data.getStringExtra("data_return"); } break; default: } }
在一个活动中有可能调用startActivityForResult()方法去启动很多不同的活动,每一个活动返回的数据都会回调到onActivityResult()这个方法中,因此我们首先要做的就是通过检查requestCode的值来判断数据来源。确定数据来源后,再通过resultCode 的值来判断处理结果是否成功。最后从data中取值出来,这样就完成了向上一个活动返回数据的工作。
如果直接按下back键,这样数据是无法返回到FirstActivity的。在这种情况下我们可以通过重写 onBackPressed()方法来解决这个问题,代码如下所示:
@Override public void onBackPressed() { Intent intent = new Intent(); intent.putExtra("data_return", "Hello FirstActivity"); setResult(RESULT_OK, intent); finish(); }
当用户按下 Back键,就会去执行 onBackPressed()方法中的代码,我们在这里添加返回数据的逻辑就行了。
Android是使用任务(Task)来管理活动的,一个任务就是一组存放在栈里的活动的集合,这个栈也被称作返回栈(BackStack)。栈是一种后进先出的数据结构(——队列是先进先出的数据结构),在默认情况 下,每当我们启动了一个新的activity,它会在返回栈中入栈,并处于栈顶的位置。而每当我们按下 Back键或调用 finish()方法去销毁一个activity时,处于栈顶的activity会出栈,这时前一个入 栈的activity就会重新处于栈顶的位置。系统总是会显示处于栈顶的activity给用户。
①活动状态:当前Activity位于返回栈的栈顶,在屏幕最前端,处于可见并可和用户交互的激活状态。
②暂停状态:当Activity被另一个透明或者Dialog 样式的Activity覆盖,但仍然可见。处于暂停状态的activity仍然是完全存活着的,只有在系统内存不足才时会杀死这个Activity。
③停止状态:该Activity被其他Activity完全覆盖,且完全不可见。但是它仍然保存所有的状态和信息。当内存低的情况下,它将要被系统killed(杀死)。
④销毁状态:该Activity从返回栈中移除,或Activity所在的Dalvik进程被结束。
1.onCreate():activity在第一次被创建的时候调用,完成初始化操作,比如加载布局、绑定事件等。
2.onStart() 这个方法在活动由不可见变为可见的时候调用。 (可见不可交互)
3.onResume() 这个方法在活动准备好和用户进行交互的时候调用。此时的活动一定位于返回栈的栈顶,并且处于运行状态。
4.onPause() 这个方法在系统准备去启动或者恢复另一个活动的时候调用。我们通常会在这个方 法中将一些消耗 CPU的资源释放掉,以及保存一些关键数据,但这个方法的执行速度 一定要快,不然会影响到新的栈顶活动的使用。(可见不可交互)
5.onStop()这个方法在活动完全不可见的时候调用。(最小化或者按了home键)
它和 onPause()方法的主要区别在于,如果启动的新活动是一个对话框式的活动,那么 onPause()方法会得到执行,而 onStop() 方法并不会执行。
6.onDestroy() 这个方法在活动被销毁之前调用,之后活动的状态将变为销毁状态。
7.onRestart() 这个方法在活动由停止状态变为运行状态之前调用,也就是活动被重新启动了。
1)完整的生命周期:
onCreate--onStart--- onResume---onPause--onStop---onDestory
如,如果Activity有一个线程在后台运行从网络下载数据,它会在onCreate()创建线程,而在 onDestroy()销毁线程。
2)可视生命周期
onStart--onResume--onPause--onStop
3)前台生命周期
onResume--onPause
为了更直观理解生命周期,提供生命周期图如下:
注意:将一个activity设置成dialog形式只需在清单文件做如下配置:
<activity android:name=".DialogActivity" android:theme="@android:style/Theme.Dialog" > </activity>
Activity的启动模式一共有四种,分别是standard、singleTop、singleTask 和singleInstanc,可以在AndroidManifest.xml 中通过给<activity>标签指定android:launchMode属性来选择启动模式。
standard模式是系统默认的启动模式,不需为<activity>配置android:launchMode属性。
特点是不管栈中是否存该activity,都生成新的实例,存放于栈结构的顶部。
在FirstActivity中,每点击一次按钮就会创建出一个新的FirstActivity实例。此时返回栈中也会存在三个FirstActivity的实例,因此你需要连按三Back键才能退出程序。
standard模式的原理示意图,如图:
单一顶部模式,如果发现有对于对应的activity存在于栈顶,则不创建新的实例,而是复用;如果发现有对应的activity但不是位于栈顶,则创建新的新的实例存放于栈顶顶。
应用场景:避免重复的打开和重复的激活。
singleTop模式的原理示意图,如图
单一任务模式。如果发现有对应的activity在任务栈里,那么它将清空它上面所有的activity,也会调用onNewIntent()。
应用场景:浏览器这样的耗内存资源的应用。
单例模式,全局唯一模式。系统为之分配一个新的task,且里面只能有其一个Activity,也会调用onNewIntent。
标签:
原文地址:http://blog.csdn.net/znouy/article/details/51316944