前阵子花了好多力气找来找去找不到Smartphone上的Money软件。主要是找不到免费的——要钱的还是有那么两三家的,也不贵,十几、二十几美元的样子。但从国外买太麻烦,而Microsoft Money从2003到最近的2005 Beta,都不带Smartphone上的客户端。所以早就下决心自己写一个。决心下了很久,这两天终于动手写了一个出来:

功能是非常简单的,就是记记帐,主要的用例包括:
1. 添加/删除Account
2. 添加/删除/查看Transaction
3. 在Account之间转账
4. 将Transaction记录归档为csv文件
其他一些Better to have但是我没有做的功能包括:
1. 编辑Expense/Income Categories
2. 编辑Account,包括Rename,修改Initial Balance等
3. 编辑Transaction
4. 实现一个ActiveSync的Provider,通过ActiveSync同步Transaction记录
5. 在手机上直接看Expense/Income report
6. ...
不做这些功能是因为实在是精力和时间有限,从开始想到写完,总共才花了十几个钟头,只能在确保实用的前提下砍掉一些功能。
下面说说我写这个程序时的一些主要设计思路:
a. 存储的问题
这是最先想清楚的一件事情。本着以最快的速度开发出来的想法,我用DataSet作为In memory的database,主要优点是两个:1) 在DataSet、DataTable、DataRow上面操作数据还是满方便的;2) DataSet本身提供了ReadXML()和WriteXML()函数,用来做序列化/持久化很方便,基本不用自己操心。没有用SQL CE的原因是部署起来太复杂。现在用户只需要xcopy就可以了,如果用了SQL CE,用户就必须安装SQL CE,这不可接受(而且我还不确定Smartphone 2003是不是支持SQL CE,汗颜)。没有用Flat file和自定义数据类型的原因是开发效率。直接操作Flat file虽然速度比ReadXML()/WriteXML()快很多,但是编程太麻烦,容易出错,不好调试。所以,两害取其轻,我选择了用DataSet。由此带来的Performance问题会在c.里面讲到。
b. 与PC同步数据的问题
可以选择的方法很多,比如可以用实现一个ActiveSync的Provider来同步,比如可以用SQL CE的Replicate来同步,当然也可以用Web Services。但这些都太麻烦,而且存在PC端程序的部署问题。仍然本着寻求最快的开发速度的考虑,我只在phone上面实现了一个archive到csv文件的功能。用的时候可以在资源管理器里面把archive的csv文件手工拷贝到PC上,然后就可以在Excel里面为所欲为。因为毕竟同步数据和做支出分类报表并不是经常发生的事情,所以在时间有限的情况下做简化处理了。
c. Performance的问题
用了DataSet作为In memory的数据库以后,在程序启动的时候会从文件系统里面的一个moneydb.xml读入数据,程序退出的时候用DataSet.WriteXML()把数据保存在moneydb.xml中。但是在程序的整个运行过程中也需要不断的把DataSet的更改及时写入Xml文件中,一方面防止手机意外死机,另一方面Smartphone的应用程序很少有“退出”的概念。
一种做法是增加一个“Save”菜单,但这明显不符合用户的思维习惯。另一种做法是每次做了修改(例如新建/删除Transaction等)以后都用WriteXML()把DataSet整个重新写到Xml文件里面。但这样做,当Transaction记录数量稍有增加,保存整个DataSet的速度就会很慢(只能说Smartphone的计算能力还太差),使得用户每做一个新增/修改/删除操作都会等待很久。最后我采用的做法是每次新增/修改/删除操作都只Set一个Flag,然后每隔几分钟检查这个Flag,如果true,再把DataSet整个保存到Xml文件里面。这样user experience会明显好很多。当然,为了保证把DataSet写入文件时内容不被其他代码修改,用上了很多lock,天知道会不会有问题,我还没仔细dog food过。
d. UI的问题
在VS.NET 2003里面编Smartphone 2003的程序,应该说已经算是很方便的了,但不完美的地方还是有的,比如ListView属性编辑里面没有设定Font的地方,只能手工敲代码设Font。还有一些小小的Bug,比如,如果SubItem的数量超过了ListView的实际栏数,那些没有被现实出来的column的ListView.Items[i].SubItem[j].Text是取不到——就算前面设了后面也取不到。很不爽,Workaround是有,比如可以自己单独维护一个Array,就是编程麻烦了一点。也就是因为这个原因,可以看到在我的程序里面,Transaction列表里面放了一栏“ID”,这就是不得已而放上去的。
另外,Main Menu左边的那个按钮(正式的名称是Soft Key)只能是单个menu item,不能有子菜单。否则就会报一个NotSupportedException。我还遇到的一个区别是在.NET和.NET CF里面,System.Data.DataSet的ReadXML和WriteXML函数的参数定义是不一样的。
e. 部署的问题
因为在a.和b.里面都考虑到了部署方便,所以到了部署这一步就变得很容易了,直接xcopy就可以了。copy的时候除了执行文件外,还有一个moneydb.xml,这就是a.里面提到的DataSet序列化出来的,就把它当作数据库了。
另外,安装在Smartphone 2003上的话是不需要安装.NET Compact Framework的,因为Smartphone 2003的ROM里面就是带了.NET CF的,不单单Dopod 515带,其他的SP2003都带的——今天后来看到一片MSDN上的文章,证实了这点。
--
源代码和可以直接拷贝安装的文件可以到这里下载(注:不得不放到一个论坛上,因为找不到其他什么好地方可以上传Zip文件),里面有readme.txt讲怎么安装,使用的话应该看着界面就会了,再不行就留言讨论。说明一点,我写这个东西为了两个目的:其一,纯粹想自己图个方便;其二,从来没写过Smartphone程序,写一个玩玩。所以,没打算深究,除非以后工作中会用到。如果大家做了Code Review以后觉得哪里不堪入目或者设计愚蠢的,请多多谅解,毕竟时间有限。我正在自己的Dopod 515上面dog food,要是没什么performance、死锁或者crash的问题,就不高兴改了。
打印 | 张贴于 2004-08-04 02:13:00 | Tag:Mobile

留言反馈
正在准备资源...
正在更新引用...
正在执行主编译...
生成完成 -- 0 个错误,0 个警告
正在生成附属程序集...
Visual Studio 已准备好部署SmartDeviceTest2
------ 已启动部署: 项目: SmartDeviceTest2, 配置: Release Smartphone ------
正在部署到 Smartphone 2003 Emulator (Virtual Radio)正在使用 模拟传输
已连接到在 X86 上运行的 Smartphone 2003 Emulator (Virtual Radio) (Smartphone)。
正在从“F:\SmartPhoneTest\SmartDeviceTest2\bin\Release”向“\Storage\Program Files\SmartDeviceTest2”复制文件
正在复制 SmartDeviceTest2.exe
正在复制 System_SR_ENU.phone.cab
正在启动“System_SR_ENU.phone.cab”的设备安装。请查看设备屏幕中的详细说明。...........
我的也会,怎么处理
我还有几个疑问:
1、能否把smartphone当作pc机?它在网络中是否有IP地址?
2、samrtphone是通过什么渠道上网的?移动的无线网络(gprs)?cdma?还是蓝牙技术借助于pc上网?
3、要开发一套c/s结构的程序,服务器应该部署在那里?
一般的pc机作服务器可以吗?数据库用sql server2000可以吗?
正在准备资源...
正在更新引用...
正在执行主编译...
生成完成 -- 0 个错误,0 个警告
正在生成附属程序集...
Visual Studio 已准备好部署SmartDeviceTest2
------ 已启动部署: 项目: SmartDeviceTest2, 配置: Release Smartphone ------
正在部署到 Smartphone 2003 Emulator (Virtual Radio)正在使用 模拟传输
已连接到在 X86 上运行的 Smartphone 2003 Emulator (Virtual Radio) (Smartphone)。
正在从“F:\SmartPhoneTest\SmartDeviceTest2\bin\Release”向“\Storage\Program Files\SmartDeviceTest2”复制文件
正在复制 SmartDeviceTest2.exe
正在复制 System_SR_ENU.phone.cab
正在启动“System_SR_ENU.phone.cab”的设备安装。请查看设备屏幕中的详细说明。...........
---------------------- 完成 ---------------------
生成: 1 已成功, 0 已失败, 0 已跳过
部署: 1 已成功, 0 已失败, 0 已跳过
正在启动应用程序
试图运行项目时出错: 无法启动调试。
无法启动程序“F:\SmartPhoneTest\SmartDeviceTest2\bin\Release\SmartDeviceTest2.exe”。
请问为什么会运行不了的?用vs.net和smartphone 2003 sdk
QQ101466577没找到你的QQ,希望能加我聊聊。
想自己写都不行,,,,不会啊。。。。。
羡慕用CE Phone的哥们。。。
musicland在我们团队中是负责研发的,等过了这段时间我们会写一些关于OpenNETCF方面的blogs,希望到时候大家捧场!:)
前者的性能在.NET CF 1.0下的确比较差,但.NET CF 1.0 SP2号称在几项数据读取指标上有显著提升。对于CSV,推荐使用OpenNETCF.org所提供的CSVDataAdapter,它的性能相对不错。
偶就只能在模拟器里玩玩。 :'(
其中一款是滑盖,另一款是直板,很像SonyEricsson T628的尺寸。但是屏幕则大的多。不好发照片出来,怕给人家泄密了:-P
还不知道什么时候上市。
你的问题我没有idea :(
方法1,google;方法二,看看博客堂有没有这方面的专家来回答;方法三,去newsgroup问;方法四,上case;.....
你这几天在哪儿?我准备劫道去了:P
多谢多谢,yousendit上次看到了,觉得很不错。不过只能7天。论坛应该可以放久一点点吧
to leighsword:
wm2003好像的确不支持evb了,不过需要确认一下。六月份的MDC上有一个slide讲到的,查一下去看看,不过我记得一点是无误的: 到了下一个版本的windows mobile,好像就只能用.net cf 2.0了。
我只所以用cf,是因为要快速开发。这点上.net优势明显。而且,记得上次有谁说了一句话:我现在只写java和c#了, cpp能不写就不写。我现在也有点这个味道,工作上不需要,就尽量不写cpp,人太懒
to sumtec:
我去看看xmlreader/writer。不过现在用了splash,呵呵,也算有一个遮羞布了
to jgtm2004:
过奖了,我这个倒真的属于典型的快速原型。
to 开心:
我原来那个是smartphone 2002,我为了写money,特地换成515的,515是smartphone 2003,支持.net cf。
another queastion:
EVB是CE3.0时代的事情了,现在MS是不是已经不支持EVB?
从做原型的角度看,老兄的方法真是得当的紧——实用、快速。我现在的项目也正在这个阶段,这两天每天都在头脑风暴最终用户场景与体验。不过接下来的产品架构设计可就比较复杂了,有机会还要向老兄讨教,也欢迎你随时来我这儿参观、指导和啃谈!:-)
BTW: 什么时候老兄想来创业了随时联系我!真想把你从MS挖来啊!哈哈……