Android Intent机制实例详解(1
 
Android中提供了Intent机制来协助应用间的交互与通讯,或者采用更准确的说法是,Intent不仅可用于应用程序之间,也可用于应用程序内部的Activity/Service之间的交互。Intent这个英语单词的本意是“目的、意向”等,对于较少从事于大型平台开发工作的程序员来说,这可能是一个不太容易理解的抽象概念,因为它与我们平常使用的简单函数/方法调用,或者上节中提到的通过库调用接口的方式不太一样。在Intent的使用中你看不到直接的函数调用,相对函数调用来说,Intent是更为抽象的概念,利用Intent所实现的软件复用的粒度是Activity/Service,比函数复用更高一些,另外耦合也更为松散。
Android中与Intent相关的还有Action/CategoryIntent Filter等,另外还有用于广播的Intent,这些元素掺杂在一起,导致初学者不太容易迅速掌握Intent的用法。在讲解这些名词之前,我们先来从下面的例子中感受一下Intent的一些基本用法,看看它能做些什么,之后再来思考这种机制背后的意义。
理解Intent的关键之一是理解清楚Intent的两种基本用法:一种是显式的Intent,即在构造Intent对象时就指定接收者,这种方式与普通的函数调用类似,只是复用的粒度有所差别;另一种是隐式的Intent,即Intent的发送者在构造Intent对象时,并不知道也不关心接收者是谁,这种方式与函数调用差别比较大,有利于降低发送者和接收者之间的耦合。另外Intent除了发送外,还可用于广播,这些都将在后文进行详细讲述。
下面的一小节我们来看看显式Intent的用法。
显式的Intent(Explicit Intent)
✧同一个应用程序中的Activity切换
我们在前面的章节已经讨论过Activity的概念,通常一个应用程序中需要多个UI屏幕,也就需要多个Activity类,并且在这些Activity之间进行切换,这种切换就是通过Intent机制来实现的。
在同一个应用程序中切换Activity时,我们通常都知道要启动的Activity具体是哪一个,因此常用显式的Intent来实现。下面的例子用来实现一个非常简单的应用程序SimpleIntentTest,它包括两个UI屏幕也就是两个Activity——SimpleIntentTest类和TestActivity类,SimpleIntentTest类有一个按钮用来启动TestActivity,程序运行的截图如图5.3源代码电影讲解所示
Android Intent机制实例详解二
 
程序的代码非常简单,SimpleIntentTest类的源代码如下:
package pe.samples.intent.simple;
import android.app.Activity;
import t.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class SimpleIntentTest extends Activity implements View.OnClickListener{
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        Button startBtn = (Button)findViewById(R.id.start_activity);
        startBtn.setOnClickListener(this);
    }
   
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.start_activity:
            Intent intent = new Intent(this, TestActivity.class);
            startActivity(intent);
            break;
        default:
            break;
        }
    } 
}
上面的代码中,主要是为“Start activity”按钮添加了OnClickListener使得按钮被点击时执行onClick()方法,onClick()方法中则利用了Intent机制,来启动TestActivity,关键的代码是下面这两行:
Intent intent = new Intent(this, TestActivity.class);
startActivity(intent);
这里定义Intent对象时所用到的是Intent的构造函数之一:
Intent(Context packageContext, Class<?> cls)
两个参数分别指定ContextClass,由于将Class设置为TestActivity.class,这样便显式的指定了TestActivity类作为Intent接收者,通过后面的startActivity()方法便可启动TestActivity
TestActivity的代码更为简单(定义TestActivity类需要新建TestActivity.java文件,如果你是一个初学者,你需要学会如何在Eclipse或其他开发环境下添加一个新的类,本书不作详述,请参考其他文档),如下所示:
package pe.samples.intent.simple;
import android.app.Activity;
import android.os.Bundle;
public class TestActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.test_activity);
    }
}
可见TestActivity仅仅是调用setContentView来显示l中的内容而已。对于l本例中所用到其他xml文件这里不作多余说明,读者练习时可自行参考本书所附光盘中的源代码。
如果我们仅仅是做上面的一些工作,还不能达到利用SimpleIntentTest启动TestActivity的目的。事实上,这样做会出现下面的Exception,导致程序退出。以下是利用logcat工具记录的log信息(省略了后半部分):
I/ActivityManager(  569): Displayed pe.samples/.SimpleIntentTest: 3018 ms
I/ActivityManager(  569): Starting activity: Intent { comp={pe.pe.samples.TestActivity} }
D/AndroidRuntime(  932): Shutting down VM
W/dalvikvm(  932): threadid=3: thread exiting with uncaught exception (group=0x4000fe70)
E/AndroidRuntime(  932): Uncaught handler: thread main exiting due to uncaught exception
E/AndroidRuntime(  932): t.ActivityNotFoundException: Unable to find explicit activity class {pe.pe.samples.TestActivity}; have you declared this activity in l?
E/AndroidRuntime(  932):        at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1480)
E/AndroidRuntime(  932):        at android.StartActivity(Instrumentation.java:1454)
E/AndroidRuntime(  932):        at android.app.Activity.startActivityForResult(Activity.java:2656)
E/AndroidRuntime(  932):        at android.app.Activity.startActivity(Activity.java:2700)
E/AndroidRuntime(  932):        pe.Click(SimpleIntentTest.java:24)
Android Intent机制实例详解
 
 
从这些log中我们可以看到点击按钮后startActivity的调用过程,主要的原因是:“t.ActivityNotFoundException: Unable to find explicit activity class {pe.pe.samples.TestActivity}; have you declared this activity in l?
从这些log我们可以看到原因是不到TestActivity这个Activity,并且log中还给出了提示:你是否在l中声明了这个Activity?解决问题的方法也就是按照提示在l中增加TestActivity的声明,如下所示,注意粗体字部分:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="schemas.android/apk/res/android"
      package="pe.samples"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".SimpleIntentTest"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
       <activity android:name=".TestActivity"/>
    </application>
    <uses-sdk android:minSdkVersion="3" />
</manifest>
完成这个修改后再重新运行该程序,就一切都正常了。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。