Android四大组件之Activity详解——创建和启动Activity
前面我们已经对Activity有过简单的介绍:
先来看一下最终结果
项目源码:
http://download.csdn.net/detail/ginodung/8328361
创建Activity:
接下来打开我们的IDE,创建一个名叫ActivityDemo的Android Application Project
工程默认已经为我们创建了一个Activity,现在我们手动添加一个名叫SecondActivity的类
点击finish完成SecondActivity类的创建。完了我们为这个Activity创建一个布局文件activity_second
点finish完成布局的创建。
下面是activity_second布局的代码
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:id="@+id/txtView" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Second Activity" android:textSize="20sp"/> </LinearLayout>
下面是SecondActivity的代码:
package com.example.activitydemo; import android.app.Activity; import android.os.Bundle; public class SecondActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); //绑定activity_second布局到SecondActivity setContentView(R.layout.activity_second); } }
Activity和布局activity_second都创建好,最后一步就是要在AndroidManifest文件中注册该Activity
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.activitydemo" 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="com.example.activitydemo.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> <!-- 注册SecondActivity开始 --> <activity android:name=".SecondActivity" android:label="Second Activity"> <intent-filter> <action android:name="com.example.activitydemo.mysecondactivity"/> <category android:name="android.intent.category.DEFAULT"/> </intent-filter> </activity> <!-- 注册SecondActivity结束 --> </application> </manifest>
注册SecondActivity的时候除了action标签要设置外,
<category android:name="android.intent.category.DEFAULT"/> 也是必须的,
否则系统会找不到你的Activity,启动的时候会抛出ActivityNotFoundException异常。
当然你也可以定义自己的category类别,这个后面再说。
准备工作都准备好后,我们就可以启动这个Activity。
下面是Button按钮的事件处理代码:
package com.example.activitydemo; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //查找我们在布局中创建的按钮 Button startSecondActivity = (Button)findViewById(R.id.btnStartSecondActivity); //为按钮绑定点击事件 startSecondActivity.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //隐式启动SecondActivity startActivity(new Intent("com.example.activitydemo.mysecondactivity")); //也可以显式启动Activity //startActivity(new Intent(getBaseContext(), SecondActivity.class)); } }); } }
解决Intent Filter冲突
我们不能启动一个不存在的Activity,否则程序会崩溃。
但是,如果系统中存在多个相同的Activity呢,结果又会怎样?
现在我们尝试一下,定义第三个Activity,名叫ThridActivity。这个Activity的action和SecondActivity的一样
ThirdActivity的Java程序文件不在这里列出。创建过程和SecondActivity一样。
下面是ThirdActivity在AndroidManifest文件中的注册信息:
<!-- 注册ThirdActivity开始 --> <activity android:name=".ThirdActivity" android:label="The Third Activity"> <intent-filter> <action android:name="com.example.activitydemo.mysecondactivity"/> <category android:name="android.intent.category.DEFAULT"/> </intent-filter> </activity> <!-- 注册ThirdActivity结束 -->
我们重新运行一下程序,看结果是什么
没错,系统会弹出一个选择框让我们决定打开的是哪一个Activity。
那么,当系统中有多个相同action的Activity存在的时候能不让这个选择框弹出来吗?
答案是有的,这个时候,就要用到category标签。
先来更新一下ThirdActivity在AndroidManifest文件中的注册信息
<!-- 注册ThirdActivity开始 --> <activity android:name=".ThirdActivity" android:label="The Third Activity"> <intent-filter> <action android:name="com.example.activitydemo.mysecondactivity"/> <!-- 自定义category --> <category android:name="com.example.activitydemo.mycategory"/> <category android:name="android.intent.category.DEFAULT"/> </intent-filter> </activity> <!-- 注册ThirdActivity结束 –>
我们自定义了一个category标签,那么这个标签有什么用呢。
接着看,这一次我们是更新那个按钮的响应事件
package com.example.activitydemo; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //查找我们在布局中创建的按钮 Button startSecondActivity = (Button)findViewById(R.id.btnStartSecondActivity); //为按钮绑定点击事件 startSecondActivity.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent("com.example.activitydemo.mysecondactivity"); intent.addCategory("com.example.activitydemo.mycategory"); startActivity(intent); } }); } }
我们这里使用了Intent的addCategory方法,这个方法可以让我们明确打开的是哪一个category下的Activity。
这样,我们就可以直接打开ThirdActivity
优化程序的用户体验
前面已经说过,启动不存在的Activity的时候,程序会崩溃,这是很不好的用户体验。
启动Activity之前先验证一下是否存在这个Activity非常必要。
具体方法:使用PackageManager的queryIntentActivities方法
//为按钮绑定点击事件 startSecondActivity.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //启动一个不存在的Activity Intent intent = new Intent("com.example.activitydemo.NoSuchActivity"); intent.addCategory("com.example.activitydemo.mycategory"); //创建PackageManager类 PackageManager packageManager = getPackageManager(); //获取包含能处理给定intent的activity列表 List<ResolveInfo> activities = packageManager.queryIntentActivities(intent, 0); if(activities.size() > 0) startActivity(intent); else Toast.makeText(getBaseContext(), "Activity not found", Toast.LENGTH_SHORT).show(); } });
现在,启动一个不存在的Activity试一下
创建应用程序选择器(App Chooser)
应用程序选择器的作用是允许我们可以每次都选择以哪一个程序处理数据。
那么跟上面所说的Activity选择框有什么不一样呢。
Activity选择框更多的是一种程序的替代,如浏览器,信息发送程序,图片浏览器等。
而App Chooser更适用于社交型的程序,如信息分享。
借用一下官方的图片,先看看App Chooser的真面目
创建App Chooser
//为按钮绑定点击事件 startSecondActivity.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //startActivity(new Intent("com.example.activitydemo.mysecondactivity")); Intent intent = new Intent("com.example.activitydemo.mysecondactivity"); //intent.addCategory("com.example.activitydemo.mycategory"); //创建App Chooser Intent chooser = Intent.createChooser(intent, "将信息分享到"); //创建PackageManager类 PackageManager packageManager = getPackageManager(); //获取包含能处理给定intent的activity列表 List<ResolveInfo> activities = packageManager.queryIntentActivities(intent, 0); if(activities.size() > 0) startActivity(chooser); //通过chooser启动Activity else Toast.makeText(getBaseContext(), "Activity not found", Toast.LENGTH_SHORT).show(); } });
运行结果: