作者起初完全是个ophone菜鸟,从未开发过任何ophone应用,但经过一次锻炼,感觉ophone还是蛮容易入门的,因为应用开发的几个前提条件比如集成开发工具,开发文档和API等等方面Ophone均做得很不错,在本篇文章里作者分享了他的ophone应用之路,从菜鸟的角度见证了这个事实。

第一步,ophone应用开发工具和环境

什么是ophone应用开发和环境呢?有三篇文章对这个问题有很好的回答,那就是

1. 安装OPhone SDK

2. 安装Eclipse Plugin (ODT)

3. 安装Eclipse Plugin (WDT)

安装步骤这里就不再赘述,读者可以参考上述三篇文章,然后亲自动手实验的,这里仅说说作者读做后感和两个细节

  • 安装SDK是必须的,否则任何ophone应用都无何谈起,这就是文章1要回答的问题,任何ophone菜鸟一定要读;
  • 虽然无需eclipse,ODT和WDT,也能开发ophone应用,但如果有更好的和效率更高的工具,为什么不用呢?这就是文章2和3要回答的问题;
    ODT帮助我们开发native应用,在下面即将提到的twenty4就是一个native应用;WDT帮助我们开发widget应用,OPhone上的轻量级小工具Widget开发介绍对什么是widget应用以及如何开发widget应用有很好的回答;

动手安装时注意两个细节:

  • eclipse不是版本越新越好
    作者在用eclipse Galileo(3.5 SR1)版本时,安装ODT和WDT均有问题;正确的答案是使用eclipse Ganymede(3.4.2)版本,可以到这个link下载,选classic即可。
  • 安装WDT时,需要先安装Web Developer Tools,读者可以参考我的wdt总是安装不上怎么办

总的来说,走完上面这些路,菜鸟们可以得到以下收获

  • eclipse的Window->Preferences菜单弹出的对话框里新添了两项“Ophone”和“Widget”
    clip_image002
  • eclipse的File->New->Project菜单弹出的对话框里新添了两项“Ophone Project”和“Widget Project”
    clip_image004
  • Ophone模拟器
    有了模拟器,我们开发的ophone应用,就可以在模拟器中被部署和测试,菜鸟们不需要自己去买个真实的ophone手机就能看见自己的劳动成果了哦。
    clip_image006

第二步,开发自己的Ophone应用

在体验过ophone开发工具和环境后,接下来的事情当然就是更有意思和挑战性的啦,那就是写一个自己的Ophone应用;前面提过ophone应用开发有两种,native和widget,作者这里选用的是一个叫做twenty4的native应用。它提供什么功能呢?

应用外部功能描述:

  • 用户随意输入四个数字,该应用计算他们和加减乘除的可能组合,如果结果等于24,那么返回所有符合条件的表达式
    举个例子,有4个数字,4,4,7,7,那么7×(4-4/7)满足要求
  • UI界面主体循环
    clip_image008

实际项目中所有的工作均围绕这两个重点而进行。

对于功能一,可以事先编写好求解函数,这里就不再详细描述其实现方法,仅列出主接口函数的声明。

void construct_infixexpr_list(Integer n, Integer m, String[] opset, String[] dlist, Stack<Integer> selectedset)

通过调用这个函数construct_infixexpr_list,就可以取得求解的全部表达式,表达式作为一个字符串存放在外部变量infixexpr中,传给该函数的参数如下所示

  • dlist是图一中传过来的数字list
  • n是dlist.lenght*2-1,
  • m是dlist.length
  • opset是一个string数组,定义了4个运算符号,+-*/
  • selectedset是个初始值为空的整数栈

我们再来详细看看功能二是如何实现的,功能二其实是描绘了一个界面循环。

  • 在图一的界面中,用户随意输入四个数字,然后点击求解按钮
  • 然后用户进入图二,即程序进入求解状态
    如果有一个解被找到,它就会被列出来;只要程序还在求解,标题“答案求解中”后的小数点就会循环运动
  • 当所有解被找到时,标题就会被更新为图三形式,才是标题变为“共?组解;花了?秒”
    如果用户点击关闭按钮,又会返回图一

大家也许注意到了,图二和图三的差别仅在于标题不同;没错!图二和图三其实就是同一个对象Activity。利用Ophone SDK提供的Activity类,就可以轻松地实现功能二的UI界面循环。如何直观的理解Activity呢?可以把Activity和函数做个简单类比,见下表

 

Activity

函数

能否可以相互调用

是否都被栈来管理

能否返回到上一级

能否支持参数传递

如果说图一用activity1表示,图二用activity2表示,那么从图一进入到图二的过程,就是可以理解为activity1调用activity2的过程,正如函数func1可以去调用func2一样;同样,func2执行完毕后,会返回到func1继续执行,activity2执行完毕后,也会返回到activity1继续执行,当然这种返回的实现由Activity封装过了。Activity的实现过程,正是对这种动态过程在ophone手机上的一个非常精彩的模拟,当然,所有这些也都离不开栈,函数之间的调用形成了函数栈,Activity之间的调用给我们的感觉是屏幕栈。

如何创建一个native应用的具体步骤,请大家参考Hello, OPhone! ,假设大家都走完了该篇文章的所有步骤。实战中,俺也是照搬地创建twenty4和caltwenty4 Activity,twenty4是plugin帮忙创建的Main Activity,大家可以理解为图一;caltwenty4是自己创建的,大家可以理解为图二和图三;这里主要分享开发过程中的几个知识点。

  • 每个Activity都有一个与之关联的xml文件,在该xml文件里,我们描述了该Activity的UI界面;这种关联关系的建立一般是在该Activity的onCreate函数中建立的,请看
    clip_image010
    左边的package explorer红圈里是俺自己创建的showresult.xml,右边是caltweny4的onCreate函数,它使用setContentView(R.layout.showresult)来告诉caltwenty4 Activity来应用showresult.xml描述的UI;这个UI是一个LinearLayout,有三个孩子,TextView,ScrollView和Button;鉴于篇幅,就不在这里copy这个showresult.xml了。
  • twenty4是如何去调用caltwenty4的,请看

public class twenty4 extends Activity implements View.OnClickListener{
……
    @Override
    public void onClick(View view) {
    ……
        Intent intent=new Intent();    //call Activity,一般要先创建一个Intent对象
        intent.setClass(twenty4.this, caltwenty4.class); //指明这个call的源和目标Activity
        Bundle mBundle=new Bundle();   //Bundle对象可以理解为对参数的打包
        mBundle.putString("digitlist", str1+" "+str2+" "+str3+" "+str4);     //图一中的四个输入数字正是放在mBundle中,由digitlist字符串索引
        intent.putExtras(mBundle);
        startActivity(intent);            //转到caltweny4中执行
    }   
}
以上所列6行代码正是答案所在,理解请参考注释,更多内容请参考Android Intent机制实例详解

 

  • 将construct_infixexpr_list放在单独thread中运行
    由于construct_infixexpr_list求解需要耗费较长时间,如果将之放到caltwenty4的onCreate函数中(俺一开始也是这么干的),那么就会发现图二的界面半天出不来,这对使用者来说是非常不礼貌的;这其实是在开发手机应用时常碰到的问题,为了避免这种情况,解决方法是将该函数作为独立的线程来执行。请看
    public class caltwenty4 extends Activity implements View.OnClickListener, Runnable{
    ……

public void onCreate(Bundle savedInstanceState) {
……
//onCreate中启动计算线程
    Thread thread=new Thread(this);
    thread.start();
}  

public void run(){ //这是实现Runnable接口的run函数
Stack<Integer> selectedset=new Stack<Integer>();

construct_infixexpr_list(2*digitlist.length-1,digitlist.length,Operators,digitlist,selectedset);
handler.sendEmptyMessage(COMPLETE);
}
……

private Handler handler=new Handler(){
……
//定义caltwenty4的私有变量handler来接受计算线程的结果返回
    @Override
    public void handleMessage(Message msg){
        ……
    }
};

    }
    具体来说,思路是这样的:

    • 声明caltwenty4实现了Runnable接口,实际就是要在caltwenty4类中实现run函数,在这里去call construct_infixexpr_list
    • 然后在onCreate函数中new Thread并start,如此run就被调用,进一步的说construct_infixexpr_list就被新Thread调用
    • 新Thread要返回结果给主Thread caltwenty4,通过caltwenty4的私有成员变量handler来完成

   这是解决这类问题的常用招数,虽然有点繁琐,但行之有效;不过据说在Ophone1.5版本中引入了AsynTask来简化这些步骤,有兴趣的读者可以自己动手试试,具体请参考OPhone联网应用开发中的线程管理与界面更新。

 

  • 其余的问题,诸如显示对话框,定时更新标题等,鉴于篇幅就不一一详细描述了,有兴趣的读者可以来信相互探讨

结论

通过以上描述,大家可以看见,即使是个菜鸟,要开发Ophone应用也是蛮容易入门的,因为Ophone给我们提供了丰富的工具,优秀的开发环境和大量的API,尤其是诸如Activity这种大手笔的封装类,更是给开发者们省了不少代码和麻烦,让开发人员可以集中精力在应用本身。总之,在Ophone上开发应用是一件很享受的事情!

Advertisements