在Android中窗体与窗体之间如何互相调用和交换数据?窗体(Activity)和后台的服务(Service)如何通信?基于Unix(Linux)的系统都有一个很优秀的传统,就是倡导非常轻便的进程间通信(IPC)机制;倡导进程通过IPC来互相协作;倡导功能单一,小巧而强壮的进程,而不是又大又复杂的“万金油”。同样,在Android中我们可以将我们的Activity和Service放在不同的进程中运行,我们可以在我们的Task 中加载其他进程的Activity,这些机制都鼓励我们“尽量利用已有的功能,利用IPC和包含这些已有功能的程序协作,来完成一个完整的应用”,例如在我们的程序中充分利用Google Map的相关窗体和服务。所有这些都建立在一套轻便好用的IPC机制上。
Android的组件和进程间通信都建立在一种基于称为Intent的消息基础之上。Intent就是一种消息,它包含了两个重要的内容:1. 消息的目的,即这个消息是发给哪个组件的?(消息的目的中不会包含“消息是发给哪个进程”这样的信息,这里Android有意淡化进程的概念,而只让我们关心组件,因为了解太多关于进程的具体信息会加大复杂度,而又如何做到进程间的消息传递呢?下文会说到一种Android中关于这点比较特别的设计方式,我认为是一种简捷有用又符合手机特点的设计);2. 消息所携带的数据内容,即需要传递给目标的数据。下面是一个简单的利用Intent来启动一个Service并向其传递数据的代码示例: Intent serviceIntent = new Intent(context, svrMain.class);serviceIntent.putExtra(“Network_Report”, networkStatus);context.startService(serviceIntent); 上面的代码首先构造了一个Intent对象,并在构造的时候指定了这个Intent的目的地,即“svrMain.class”,表示这个Intent是要传递给一个类名叫svrMain的Service。然后向这个Intent中放入了一个数据,数据的key为“Network_Report”,value为一个叫networkStatus的int类型变量,用来指明当前网络的状态。最后我们使用系统提供的上下文API,将这个Intent传递给指定的Service。 Intent的消息目的地分为两种模式,一种是显式的,一种是隐式的。我们上面的例子中看到的就是一个显式消息的例子。显式消息直接指定消息目的地组件的类元信息,例如上面例子中svrMain就是我们写的一个类名为svrMain的Service,class操作符就是获取其类元信息。这种模式的消息由于已经确切知道了消息目标的确切信息,所以只适用于同一进程内的不同组件之间通信,例如打开一个子窗体,和同一进程中的service通信等。对应的,隐式消息就一般用于跨进程的通信了,隐式消息没有确定的消息目的地,除了数据外,隐式消息只是包含了一些用于表征消息特征的描述字段。而一些需要收到某种特定特征消息的某个程序中的某个组件,需要通过在其所在程序的AndroidMainifest.xml中注册一种被称为intent-filter的消息特征筛选器,然后Android系统会按照一定的匹配规则来匹配发出的消息特征和所有拥有响应这种特征的intent-filter的组件(无论是同一进程内的组件还是不同程序中的组件),匹配到的组件就会接受到相应的消息。前面的描述多少有些拗口,我们举个实际的例子来说明,如果我们想开启一个子窗体(无论这个窗体来自同一进程还是不同进程),我们除了使用显式消息外,我们还可以使用隐式消息: Intent openSomeDiagIntent = new Intent();openSomeDiagIntent.setAction(“edwin.demo.fooActivity”);this.startActivity(openSomeDiagIntent); 上面的隐式消息不包含具体的目的地,而是仅包含一个名位“Action&r