By 高焕堂
ee ee
【思考Android技术】
請參考:Android从程序员到架构师之路课程(在线视频学习)
请进入:ADT架构师学苑
ee ee
如何设计”强势型”API呢?
1. 区别UI与API
使用者通常并不是软件专业人员或软件开发工在中文里,有人将Interface翻译为「接口」,也有人将它翻译为在「界面」。顾名思义,UI(User Interface)就是给使用者(或用户)使用的接口(或接口),其中,程师。所以UI是给一般人使用手机等设备时的操作画面或接口。
至于API(Application Programming Interface)则是提供给平台框架与应用软件之间互相调用的程序接口。其中,平台框架开发者通称为「强龙」;而应用软件开发者通称为「地头蛇」。无论是强龙或地头蛇,两者皆是软件专业人员,两者相互合作,结合平台框架与应用软件,再加上硬设备,就能实现UI给使用者操作了。所以API就是强龙所开发的「平台框架」与地头蛇所开发的「应用软件」之间互相调用的界面或接口。
2. 区别主动型与被动型API
所谓被动与主动,是从强龙的角度来看的。其中最主要区别点是在于:谁『调用(Call)』谁。例如,由地头蛇的应用软件调用强龙的平台框架的情形,强龙就处于被动的地位了。反之,如果由强龙的平台框架调用地头蛇的应用软件时,强龙就处于主动的地位了。人们通常会定义明确的接口(Interface)来规范两种软件之间互相调用,通常是由强龙来定义,并提供给地头蛇,让地头蛇在开发应用软件时可以使用之。所以长久以来,就通称为 API了。
于是,关于API这个名词,有3个动词与它密切相关连,就是:
- 定义(Define)
- 实现(Implement)
- 调用(Invoke or Call)
强龙通常根据这3个角度来将一个API区分为「主动型」与「被动型」两种API。其区分准则为(兹以第一人称「我」来称强龙):
现在,兹拿一个Android程序代码来举例说明之,透过实例让你能迅速体会出两种API的区别。一旦你能细腻地区别出主动型API了,你就能进而设计(即定义)主动型API,让地头蛇来实现之,然后由你调用之。于是你就成为「强龙」了。[歡迎光臨 高煥堂 網頁: http://www.cnblogs.com/myEIT/ ]
兹拿下述的Android程序代码(由Tom所撰写的应用类别)来做范例,Google是强龙,而Tom则是地头蛇。
// 由Tom所撰写的MySurfaceView应用类别
package com.misoo.pkmm;
import android.content.Context;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback,
OnPreparedListener, OnCompletionListener {
private final String FILE_NAME = "nice01.mp4";
private SurfaceHolder mHolder;
private String path;
private MThread mThread;
private MediaPlayer mMediaPlayer;
MySurfaceView(Context context) {
super(context);
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder) {
mThread = new MThread();
mThread.start();
}
public void onPrepared(MediaPlayer mediaplayer) {
mMediaPlayer.start();
}
public void onCompletion(MediaPlayer arg0) {
Log.d("Com", "onCompletion called");
}
public void surfaceDestroyed(SurfaceHolder holder) {
mMediaPlayer.stop();
}
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
// ----------------------------------------------------------------------
class MThread extends Thread {
MThread() {
super();
try {
path = "/data/data/com.misoo.pkmm/files/"+FILE_NAME;
// path = "/data/data/com.misoo.pkm/files/niceyy.mp4";
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setDataSource(path);
mMediaPlayer.setDisplay(mHolder);
int mVideoWidth = mMediaPlayer.getVideoWidth();
int mVideoHeight = mMediaPlayer.getVideoHeight();
if (mVideoWidth != 0 && mVideoHeight != 0)
mHolder.setFixedSize(mVideoWidth, mVideoHeight);
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mMediaPlayer.prepare();
} catch (Exception e) {
Log.e("error: ", e.getMessage());
}
}
@Override
public void run() {
mMediaPlayer.start();
}
public void requestExit() {
mMediaPlayer.stop();
}
}
}
其中,Google强龙做了:
1. 撰写SurfaceView基类。
2. 定义SurfaceHolder.Callback,OnPreparedListener和OnCompletionListener接口。
3. 撰写Thread基类(也定义API,其内涵run()等函数)。
4. 撰写MediaPlayer具体类别(也定义API,其内含start()、prepare()等函数)。
图1、强龙定义了两项主动型API,以及一项被动型API
基于上述的API,Tom地头强龙做了:
- 撰写MySurfaceView子类来实现强龙所定义的三个接口:
SurfaceHolder.Callback
OnPreparedListener
OnCompletionListener
- 撰写MThread子类来实现Thread抽象基类的接口,也就是实现Thread所定义的run()抽象函数。
- 使用MediaPlayer已经实现完毕的被动型API。
如下图:
图2、主动型API让强龙调用,被动型API让地头蛇调用
从图中可以看到Tom写了MThread应用子类,其程序代码:
@Override public void run() {
mMediaPlayer.start();
}
这@Override字眼意味着:这run()函数(是接口的内容)是用来实现(Implement)强龙定义于Thread基类的接口。具有两个特性:
- 强龙撰写Thread类别来定义run()函数(即API的内涵)。
- 地头蛇撰写MThread子类来实现run()函数。
依据Java语言的类别继承机制,run()函数的主要调用途径是:从基类Thread来调用MThread子类。又具有一个特性:
- 让强龙来调用此API的run()函数。
由于其共具备了上述3项特性,恰好满足「主动型API」的特性。
再看看上述run()函数里的指令:
mMediaPlayer.start();
这是从地头蛇的MThread子类调用强龙撰写的MediaPlayer具象类别。其特性是:
☆ 强龙撰写MediaPlayer类别来定义start()等函数(即API的内涵)。
☆ 强龙也自己实现此API里的各函数。
☆ 地头蛇撰写:mMedialayer.start()指令来调用此API的start()等函数。
由于其共具备了上述3项特性,恰好满足「被动型API」的特性。再来看看Tom撰写了MySurfaceView子类,其程序代码:
class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback,
OnPreparedListener, OnCompletionListener {
//………
public void surfaceCreated(SurfaceHolder holder) {
mThread = new MThread();
mThread.start();
}
public void onPrepared(MediaPlayer mediaplayer) {
mMediaPlayer.start();
}
public void onCompletion(MediaPlayer arg0) {
Log.d("Com", "onCompletion called");
}
//………
}
其中,SurfaceHolder.Callback接口是强龙定义的,而Tom撰写指令:
public void surfaceCreated(SurfaceHolder holder) {
mThread = new MThread();
mThread.start();
}
就是来实现此接口里的surfaceCreated()的函数,让Android框架来传送事件(Event)给地头蛇的MySurfaceView子类。共具有三个特性:
- 强龙定义API
- 地头蛇实现API
- 强龙调用地头蛇
恰好满足「主动型API」的特性。
同理,OnPreparedListener 和OnCompletionListener 两个接口也都属于主动型的API。
3. 结语
提供主动型API是当今云(Cloud)平台的主要特点。云平台的最大特性是开放给别人来撰写程序,并在云平台上执行,让广大的第三方开发者(即地头蛇)进来提供智能、发挥创意。所以全球各地的云平台(如美国的Facebook、大陆的支付宝等),都是积极提供主动型API(又称为开放型API)。所以,没有提供开放型API的平台,通常只是传统的因特网(即互联网)平台而已,并不是现代流行的「云」平台。如果在搭配上Android或iPhone手机,有只能称为「行动网络」或「移动互联网」平台,而不属于当今流行的云平台。
由于主动型API在云平台扮演着极为关键性的角色,所以本文拿Android的范例程序,来举例说明之,盼望您能准确分辨它、并进而发挥创意去「规划」或「设计」它,将会让您体会到强龙(或云主)的滋味。◆
[Go Back]