By 高焕堂
ee ee
【思考Android技术】
請參考:Android从程序员到架构师之路课程(在线视频学习)
请进入:ADT架构师学苑
ee ee
Android的IBinder、Context和Servlet通用性接口的整合应用
1. 复习:通用性接口的基本结构
兹看看一个大家已经很熟悉的EIT造形[ 认识EIT造形 ] :
这个<E>可以提供一个接口,例如下图的IE接口:
<E>提供了IE接口给Client使用;于是Client透过IE接口而调用<E>的operation()函数,由于它是一个抽象函数,所以就直接执行了<T>的operation()函数的实现代码。这里的IE接口与<I>接口是一致的。这就是一个通用接口的设计模式(Pattern)了;它有一个更常见的变形:
其中的operation()函数将IE接口转换成为<I>接口;于是Client透过IE接口而调用<E>的operation()具象函数,然后调用onOperation()抽象函数,就执行了<T>的onOperation()函数的实现代码。这里的IE接口与<I>接口是不一样的。这通用接口的设计模式,非常接近GoF的TemplateMethod设计模式,如下图:
2. 此结构是由2个EIT造形所组成
2.1 通用性接口模式(Pattern)
其实,上述这是接口设计模式,是由两个EIT造形所组成的,所以我们称之为”模式”(Pattern),而不称为”造形”(Form)。
上面的EIT造形,是一个退化的EIT造形,没有限定它的<E>;也可以说,所有的Client都能扮演它的<E>角色,而是这个IE接口就成为”通用性接口”了。
2.2 善用(别人)既有的通用性接口
在本文里,将运用多个既有的通用性接口,联合应用来整合iPhone手机与Android TV。其中,包括了 Android的IBinder接口和Context接口;以及i-Jetty的Servlet接口。
透过这3个通用性接口的串接,就能顺利将iPhone手机与Android TV衔接起来,让用户能使用自己的手机,上网去开起大会议厅里的主灯和电视墙等。如下图:
3. 应用范例:手机与Android TV的多机整合
3.1 应用情境
其实,大家已经看过这个范例了。这是2012年9月21日于秦皇岛市举行的<智能电视软硬整合产业联盟会议>>开幕时,副市长以他自己的手机上网访问会议厅中Android TV里的i-Jetty网页,再透过Android App发出Zigbee信号,打开会议厅的主灯和电视墙。
3.2 介绍3个通用性接口:Servlet、Context和IBinder
在本节里,你将会看到多个通用性接口组合应用的壮丽情境。其中,包括了三个主要的通用性接口,如下图:
其实,而所谓”通用性”又分为不同等级。例如,从上图里,就能看到接口的”通用性”级别了。其中的Servlet、IBinder和Context都是最通用的接口,来自各方的Client都能使用它。而<doGet, doPost>就是属于GenericServlet类的专属接口;相对上,Servlet接口的通用等级,就比<doGet, doPost>接口来得高。同样地,IBinder接口的通用等级,就比<onTransact>接口来得高。
4. 范例架构设计:联合应用3个通用性接口
4.1 iPhone手机端的规划
在这个范例里,为了让各种移动终端皆能来访问Android TV,就不特别去开发iPhone客户端的App了。而是,直接采取通用的一般浏览器(Browser)做为这个案例的手机客户端软件了。如下图:
如上图所示,从手机上网联机之后,手机浏览器出现首页画面如下:
这首页的网页HTML代码如下:
//index.html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gbk">
<title>Insert title here</title>
</head>
<body>
<h1>智能家庭 – 移动互联网</h1>
<div >
<li>控制操作:</li>
<p>
<li ><center><a href="ZigbeeDemo?zigbeecmd=1"><img src="RED.jpg" border="0"></a></center></li>
<p>
<li><center><a href="ZigbeeDemo?zigbeecmd=0"><img src="BLUE.JPG" border="0"></a></center></li>
</div>
</body>
</html>
4.2 衔接iPhone手机端的(通用性)接口:Servlet
iPhone手机与Android TV是两个相互竞争的平台,也是各自发展的。那么,又如何将两个平台整合起来呢? 答案是:以EIT造形来实践<通用性接口>。如下图:
其中,<E>提供通用性接口来与手机端的浏览器对接;而<T>则与本地App来对接。然后<E>则透过<I>来与<T>衔接起来。
于是,我们找到现成的<E&I>平台,就是:i-Jetty框架。
这i-Jetty本身是以Android应用程序形式嵌入(运行)于Android平台里,它可以透过Android框架的API与其它应用程序沟通。因而,在i-Jetty里执行的Servlet程序也能透过该Android API而与其它应用程序沟通、分享数据。例如,在家庭的Android TV里,加入一个i-Jetty插件,来容纳HTML网页和Servlet程序。数千公里外的家庭成员,透过手机Browser解析HTML,与家里的TV沟通,形成大小屏互动、多机整合的架构设计了。
有了i-Jetty框架之后,我们只需要基于GenericServlet的<E&I>来撰写子类<T>就行了;如下图:
由i-Jetty提供Servlet通用性接口来与iPhone手机上的浏览器对接。在i_Jetty里,转换成为<doGet, doPost>接口,再经由<T>来使用Context通用性接口,调用它的startService()函数,来取得IBinder通用性接口,进而与ZigbeeAppActivity&硬件驱动互相通信。就完成两端整合的任务了。
这myTVServlet类的代码 ==》范例代码
当iPhone手机的浏览器上网,就出现首页画面如下:
浏览器就来就透过i-Jetty的Servlet通用性接口,调用到这个doGet()函数,再经由<T>来使用Context通用性接口,调用它的startService()函数,进而与ZigbeeAppActivity&硬件驱动互相通信。
4.3 App的Context接口与myTVServlet对接
在上一节的myTVServlet里,使用了Android的Context和IBinder两个通用性接口,来与Android的App来沟通:
public class myTVServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private String proofOfLife ;
private myProxy pProxy = null ;
public void init(ServletConfig config) throws ServletException {
super.init(config);
android.content.Context androidContext =
(android.content.Context)config.getServletContext().getAttribute
("org.mortbay.ijetty.context");
proofOfLife = androidContext.getApplicationInfo().packageName;
androidContext.startService (
new Intent("com.google.android.ZigbeeApp.REMOTE_SERVICE"));
androidContext.bindService (
new Intent("com.google.android.ZigbeeApp.REMOTE_SERVICE"),
mConnection, android.content.Context.BIND_AUTO_CREATE);
}
// …….
}
在上一节的myTVServlet里,也使用了Android的IBinder两个通用性接口,来与Android的App来沟通:
private class myProxy {
private IBinder ib ;
private String mStatus,mLedStatus ;
myProxy(IBinder ibinder) {
ib = ibinder ;
}
public void setLedStatus(int key){
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
try{ ib.transact(key, data, replay, 0);
}catch (Exception e) { e.printStackTrace(); }
}
}
我们使用Android框架提供的这两个通用性接口,来与i-Jetty框架里的myTVServlet沟通。
这 Context接口的详细内涵如下图:
加上IBinder通用性接口,其内涵如下图:
这个Context通用性接口,是Android框架里最具有权力地位的接口。例如,只要你能取得这个Context接口,就能调用极具权力象征的startActivity()函数。
从上图可以看到,除了startActivity()函数之外,还有startService()函数、bindService()函数等,都是Android平台上最常用的函数。
接下来,就撰写myService和myBinder两个类的代码 ==> 范例代码
这里的IBinder接口是协助IPC的通用性接口。其典型的调用流程,如下图:
4.4 Android本地App的设计
在Android TV里,首先规划一支App,来与底层的Zigbee驱动沟通,控制其发出Zigbee信号给会议大厅的主灯开关。那么,谁来调用这支App呢? 答案是:myBinder类。
class myBinder extends Binder {
private Context context ;
private myService srv ;
public myBinder(Context ctx, myService service){
context = ctx ; srv = service;
}
@Override public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws android.os.RemoteException
{
if (code == 0) {
Intent intent = new Intent("android.intent.action.MY_BROADCAST");
intent.putExtra("inta", 101) ;
sendBroadcast(intent); // 传送给Activity
}
return true;
}
}
myTVServlet先透过Context(通用性)接口来绑定启动和绑定Service。
绑定了Service之后,就能透过IBinder通用性接口,来与myBinder沟通,进而与ZigbeeAppActivity沟通了。
撰写一Activity应用类:ZigbeeAppActivity
兹设计一个Android的本地应用程序(App),其包含一个应用子类,就是:ZigbeeAppActivity.java。它衔接到底层的Zigbee驱动程序,发出Zigbee信号给会议大厅的主灯开关。如下图:
这个ZigbeeAppActivity应用子类,其幕后就继承了Context通用性接口,其架构就如下图:
ZigbeeAppActivity类继承Activity类,也继承了Context通用性接口。
这个ZigbeeAppActivity应用子类的代码==》 范例代码
6. 结语
综上所述,由i-Jetty提供Servlet接口来与iPhone手机上的浏览器对接。在i_Jetty里,转换成为<doGet, doPost>接口,再经由<T>来使用Context接口,调用它的startService()函数,来取得IBinder接口,进而透过IBinder接口与ZigbeeAppActivity&硬件驱动互相通信。藉由3个现成的通用性接口的联合应用,就完成了iPhone手机与Android TV两端的对接与整合任务了。◆
[Go Back]