By 高焕堂 2012/05/28
Android框架与App的互动
-- 使用状态机(State Machine)图表示
1. 状态机与Android的天作之合
1.1 Android 是状态机动力的来源
当Android应用程序执行时,Android会不断发出信息(表示事件发生)给我们所设计的状态机,持续推动状态机的运转。Android 成为状态机运转的动力来源。如图1所示。
1.2 画面布局(Layout)与状态的联想
如何从Android画面的变化中找出状态及其转移呢?这是大家最常提出的问题。其最容易的答案是:从Android的Layout联想到状态。一开始,不需要太完美的切入点,只要一个Layout对应到一个状态就行了。
1.3 状态机直接与Android亲密互动
请留意,有人常误解这里使用状态机的目的。一般而言,使用状态机(或UML的状态图)的目的有二:
1. 做为系统分析与设计的工具:以发掘用户的需求为主,先规划状态机,然后才思考如何在Android画面上实现该状态机之设计。
2. 做为创造高可靠度的工具:以严格控制系统为主,先完成画面Layout的设计(方法途径不拘),然后设计状态机来精确控制用户与系统的互动行为。
于此,我们是针对上述的第2项目的而使用状态机。
图1、Android推动状态机的运转
当用户按下<A>键,Linux操作系统侦测到此事件发生了,会传达信息给Android应用框架(Framwork),Android就发出OnKeyDown信息(或称为事件)给我们设计的状态机,就推动状态机的运转了。同样地,当用户画面上的CheckBox时,Android就发出OnCheckedChanged信息(或称为事件)给状态机,触发状态机的转移了。 [歡迎光臨 高煥堂 網頁: http://www.cnblogs.com/myEIT/ ]
1.4 以实例解说Android与状态机的互动
此范例含有一个3D绘图窗口,以及一个CheckBox按钮。预设情形是:CheckBox未打勾,而且3D窗口只绘出一个锥型体。当用户在CheckBox上打勾时,3D窗口除了绘出一个锥型体之外,还绘出一个正立方体。
1.4.1 Layout规划与呈现
此范例含有两个画面布局:layout_01和layout_02。其layout_01如下:
按下<A>键之后,就变换到layout_02。如下:
将CheckBox打勾,仍然是layout_02,如下:
然后,按下<A>键,又变换回到layout_01画面。如下图:
再按下<A>键之后,又变换到layout_02。如此,两个Layout来回变换。
1.4.2 设计状态机
上述的UI画面设计,含有两个Layout,基于上述联想模式,我们的状态机只需要两个上层状态就可以了。但是状态2内需要另一个并行状态来表示CheckBox所触发的事件。如下图2。
图2、 依据Layout画面而设计的状态机
此时,如果用户按下<A>键,Linux操作系统侦测到此事件发生了,会传达信息给Android应用框架(Framwork),Android就发出OnKeyDown信息(或称为事件)给我们设计的状态机,就推动状态机的运转了。同样地,当用户画面上的CheckBox时,Android就发出OnCheckedChanged信息(或称为事件)给状态机,触发状态机的转移了。
1.4.3 撰写Android程序代码
兹以Android程序来实现图2的设计,其原始程序代码如下:
==》原始程序码
从这个范例中,你可以看到,加上了状态机,只改变Activity类的结构,对于3D绘图的MySurfaceView类和MyCube类并无任何更动。如此的简单动作就能将系统与用户的互动行为之可靠度提升到极高境界,何乐而不为呢!
2. 演练:事件驱动观点
2.1 画面(UI)设计
兹撰写一个Android的Activity子类别,显示出下述的画面:
2.2 类图(Class Diagram)设计
这是一个简单的<基类/子类>继承结构,如下图:
2.3 实现代码
兹撰写ac01子类的实现代码,如下:
package com.misoo.ppxx;
import android.app.Activity;
import android.os.Bundle;
import android.widget.CompoundButton;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
public class ac01 extends Activity implements OnCheckedChangeListener {
private final int WC = LinearLayout.LayoutParams.WRAP_CONTENT;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout layout_01 = new LinearLayout(this);
layout_01.setOrientation(LinearLayout.VERTICAL);
RadioButton ra_btn = new RadioButton(this);
LinearLayout.LayoutParams param =
new LinearLayout.LayoutParams(WC, WC);
param.leftMargin = 10;
param.topMargin = 10;
ra_btn.setOnCheckedChangeListener(this);
layout_01.addView(ra_btn,param);
setContentView(layout_01);
}
@Override
public void onCheckedChanged(CompoundButton arg0, boolean arg1) {
finish();
}
}
2.4 事件驱动观点
现在,基于事件驱动(Event-Driven)观点来解析上述代码。首先,看看AP、框架和OS三者之间的互动,以及事件和信息的传递。如下图所示:
2.5 事件观点看AP(使用状态图)
接下来,以状态机来表示AP的动态行为,如下图:
2.6 调整代码结构
依据上图(状态机)来调整ac01类别的代码结构,如下:
package com.misoo.ppxx;
import android.app.Activity;
import android.os.Bundle;
import android.widget.CompoundButton;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
public class ac01 extends Activity implements OnCheckedChangeListener {
private final int WC = LinearLayout.LayoutParams.WRAP_CONTENT;
private int state_var_A = 0;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
goto_state_01();
}
private void goto_state_01(){
state_var_A = 1;
LinearLayout layout = prepare_Layout_01();
setContentView(layout);
}
private LinearLayout prepare_Layout_01(){
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
RadioButton ra_btn = new RadioButton(this);
LinearLayout.LayoutParams param =
new LinearLayout.LayoutParams(WC, WC);
param.leftMargin = 10;
param.topMargin = 10;
ra_btn.setOnCheckedChangeListener(this);
layout.addView(ra_btn,param);
return layout;
}
private void goto_state_02(){
state_var_A = 2;
finish();
}
@Override
public void onCheckedChanged(CompoundButton arg0, boolean arg1) {
if(state_var_A == 1)
goto_state_02();
}
}
2.7 以UML状态机图表示
兹以UML更精细地表达出ac01类的动态行为:
2.8 框架的驱动
那么,谁来驱动上图状态机的运行呢? 答案是:Android应用框架。两者互动如下图:
在Android里,一个Activity对象可管控多个画面Layout的呈现和变换。在架构师的观点下,Layout的变换可视为Activity对象状态(State)的转移(Transition)。因此,工程界所熟悉的状态机(State Machine)机制,就能做为Android UI( User Interface)幕后的控制架构了。而UML提供了状态图(Statechart),可用来绘制状态机的状态变换行为。于此,使用EA(Enterprise Architect)建模工具来绘制UML状态图,以表达Activity对象的Layout变换行为,让我们拥有极严谨的UI架构设计。◆
[Go Back]