您的位置:首页 > 移动开发 > Android开发

Android基础(四)——Activity的两种启动方式、Intent初探

2016-02-18 21:13 477 查看

一、启动Activity

一个activity跳转到另外一个activity中的最简单的方式就是使用下面的Activity方法:
public void startActivity(Intent intent);
可能会有人认为startActivity(...)方法是一个类方法,启动activity就是针对Activity子类调用该方法。实际并非如此,activity调用startActivity(...)方法时,调用请求实际发给了操作系统。
准确地说,该方法调用请求是发送给操作系统的ActivityManager。ActivityManager负责创建Activity实例并调用其onCreate(...)方法。那么,ActivityManager是如何知道该启动哪一个Activity呢?答案就在于传入startActivity(...)方法的Intent参数。
1、显式intent
如下模板代码:

public class MainActivity extends Activity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i(TAG, "onCreate called.");
setContentView(R.layout.activity_main);
Button btn = (Button) findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener(){

@Override
public void onClick(View v) {
Intent intent = new Intent(getApplicationContext(),SecondActivity.class);
startActivity(intent);
}
});
}
}

点击之后可以从MainActivity中跳转至SecondActivity。其中getApplicationContext()方法是用于获取当前上下文,在这里也可以用MainActivity.this替换。在启动activity以前,ActivityManager会检查确认指定的Class是否已在配置文件中声明。如果已经声明,则启动activity,应用正常运行。反之,则抛出ActivityNotFoundException异常。这就是我们必须在manifest配置文件中声明应用全部activity的原因所在。
通过制定Context与Class对象,然后调用intent的构造方法来创建Intent,这创建的属于显式Intent。同一应用中,我们使用显式Intent来启动activity。
一个应用的activity如需启动另一个应用中的activity,就可以通过隐式Intent来处理。
2、隐式Intent
在介绍隐式Intent之前,得先知晓Intent的两个属性:
Intent的Action、Category两个属性的值都是一个普通的字符串,其中Action代表该Intent所要完成的一个抽象“动作”,而Category则用于为Action增加额外的附加类别信息。通常Action属性会与Category属性结合使用。
Action要完成的只是一个抽象动作,这个动作具体由哪个组件(或许是Activity或许是BroadcastReceiver)来完成,Actioin这个字符串本身并不管。比如Android提供的标准Action:Intent.ACTION_VIEW,它只表示一个抽象的查看操作,但具体查看什么、启动哪个Activity来查看,Intent.ACTION_VIEW并不知道——这取决于Activity的<intent-filter.../>配置,只要某个Activity的<intent-filter.../>配置中包含了该ACTION_VIEW,该Activity就有可能被启动。
下面有一个简单示例,在MainActivity中设置一个按钮,点击按钮后会跳到SecondActivity,UI布局太过简单这里就不说了。
MainActivity的代码如下:
public class MainActivity extends Activity {
private final static String TAG = "MainActivity";
public final static String TEXT="com.intent.action.ONLYATEST";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn = (Button) findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View v) {
Intent intent = new Intent();//创建Intent对象
intent.setAction(MainActivity.TEXT);//为Intent设置Action属性(属性值就是一个普通字符串)
startActivity(intent);
}
});
}
}

在上述程序代码中,

Intent intent = new Intent();//创建Intent对象
intent.setAction(MainActivity.TEXT);//为Intent设置Action属性(属性值就是一个普通字符串)
startActivity(intent);

指定了根据Intent来自动Activity——至于启动哪个Activity,这取决于Activity配置中<intent-filter.../>元素的配置。
<intent-filter.../>元素是AndroidManifest.xml文件中<activity.../>元素的子元素,前面已经介绍过,<activity.../>元素用于为应用程序配置Activity,<activity.../>的<intent-filter.../>子元素则用于配置该Activity所能“响应”的Intent。
<intent-filter.../>元素里通常可包含如下子元素。
0~N个<action.../>子元素。
0~N个<category.../>子元素。
0~1个<data.../>子元素。
<intent-filter.../>元素也可以是<service.../>、<receiver.../>两个元素的子元素,用于表明它们可以响应的Intent。
<action.../>、<category.../>子元素的配置非常简单,它们都可指定android:name属性,该属性的值就是一个普通字符串。
当<activity.../>元素的<intent-filter.../>子元素里包含多个<action.../>子元素(相当于指定了多个字符串)时,就表明该Activity能响应Action属性值为其中任意一个字符串的Intent。
由于上面的程序制定启动Action属性为TEXT常量(常量值为com.intent.action.ONLYATEST)的Activity,也就要求被启动的Activity对应的配置元素的<intent-filter.../>元素里至少包括一个如下的<action.../>子元素:
<action android:name="com.intent.action.ONLYATEST"/>
需要注意的是,一个Intent对象最多只能包括一个Action属性,程序可调用Intent的setAction(String str)方法来设置Action属性值;但一个Intent对象可以包括多个Category属性,程序可调用Intent的addCategory(String str)方法来为Intent添加Category属性。当程序创建Intent时,该Intent默认启动Category属性值为android.intent.category.DEFAULT常量的组件。
因此,虽然上面程序中的粗体字代码并未指定目标Intent的Category属性,但该Intent已有一个值为android.intent.category.DEFAULT的Category属性值,因此被启动Activity对应的配置元素的<intent-filter.../>元素里至少还包括一个如下的<category.../>子元素:
<category android:name="android.intent.category.DEFAULT"/>
下面是完整的AndroidManifest.xml文件代码:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.z.activitydemo">

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".SecondActivity">
<intent-filter>
<!-- 指定该Activity能响应Action属性值为指定字符串的Intent -->
<action android:name="com.intent.action.ONLYATEST"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
</application>

</manifest>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: