🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
我觉得Delphi最强大的的功能之一就是开发数据库三层应用的DataSnap,在Android上的实现,首先是完成服务器的设计: (1)利用向导完成DataSnap服务器的框架,如下图: [![image](http://ugc.qpic.cn/adapt/0/c79ff9a5-f395-bc40-64b4-d28d064c3408/800?pt=0&ek=1&kp=1&sce=0-12-12 "image")](https://yq.aliyun.com/go/articleRenderRedirect?url=http%3A%2F%2Fimages.cnitblog.com%2Fblog%2F124433%2F201310%2F17091156-8ee69d30df2d4f25b742dca7c161153d.png) 由于是实验,所以选择VCL程序,如果是实际应用,建议Service程序 [![image](http://ugc.qpic.cn/adapt/0/5bccc069-2353-76c4-4f6b-18d4cba6ac09/800?pt=0&ek=1&kp=1&sce=0-12-12 "image")](https://yq.aliyun.com/go/articleRenderRedirect?url=http%3A%2F%2Fimages.cnitblog.com%2Fblog%2F124433%2F201310%2F17091213-97481d6ebbaf42d3914e3bc5fd1d36dd.png) 我习惯使用TCP/IP作为通讯协议,简单且速度快,Sample Methods是演示和测试用 [![image](http://ugc.qpic.cn/adapt/0/944b89c2-6d5f-2b11-4113-40928d9abdb5/800?pt=0&ek=1&kp=1&sce=0-12-12 "image")](https://yq.aliyun.com/go/articleRenderRedirect?url=http%3A%2F%2Fimages.cnitblog.com%2Fblog%2F124433%2F201310%2F17091227-681e8837fa0b4051bb3377528ed6f28c.png) 缺省211端口 [![image](http://ugc.qpic.cn/adapt/0/50c236d7-4c3a-3dd7-9122-7ed85a63f607/800?pt=0&ek=1&kp=1&sce=0-12-12 "image")](https://yq.aliyun.com/go/articleRenderRedirect?url=http%3A%2F%2Fimages.cnitblog.com%2Fblog%2F124433%2F201310%2F17091256-bd5e1870cd084a26ba8c216e8fe52ef6.png) 使用TDSServerModule作为数据服务提供主体,非常方便变更为Service应用服务 [![image](http://ugc.qpic.cn/adapt/0/677329c3-2301-555f-9e23-311e6cff67b0/800?pt=0&ek=1&kp=1&sce=0-12-12 "image")](https://yq.aliyun.com/go/articleRenderRedirect?url=http%3A%2F%2Fimages.cnitblog.com%2Fblog%2F124433%2F201310%2F17091323-98e930031f2644c08e58758d9f5ca529.png) (2)设置服务器数据 在TDSServerModule中设置数据,为简便起见,采用BDE引擎的DBDEMOS下animals.dbf数据库,有文字也有图片,如下图: [![image](http://ugc.qpic.cn/adapt/0/0882ca84-9c44-a545-efae-c1fba9e7cd32/800?pt=0&ek=1&kp=1&sce=0-12-12 "image")](https://yq.aliyun.com/go/articleRenderRedirect?url=http%3A%2F%2Fimages.cnitblog.com%2Fblog%2F124433%2F201310%2F17091347-50092be9ed77408a8b8e7012180be194.png) 放置一个TDataSetProvider连接该数据源,如下图: [![image](http://ugc.qpic.cn/adapt/0/b6d8e790-2e4a-4437-842e-afc858c3fedd/800?pt=0&ek=1&kp=1&sce=0-12-12 "image")](https://yq.aliyun.com/go/articleRenderRedirect?url=http%3A%2F%2Fimages.cnitblog.com%2Fblog%2F124433%2F201310%2F17091410-8b943c80cc6c4127904551292d7af5b6.png) 服务器至此设计完成,没有编写一行代码,只是调整了部分控件和窗体的名称。手动启动该应用服务程序。 (3)新建Android客户端程序 新建一个android客户端程序,在工程中增加一个TDataModule模块,用于放置与应用服务器的连接和数据,在模块窗体上放置TSQLConnection、TDSPProviderConnection、TClientDataSet三个控件,如下图: [![image](http://ugc.qpic.cn/adapt/0/c94ebe0e-4c11-8e67-a4e8-d05f34c04831/800?pt=0&ek=1&kp=1&sce=0-12-12 "image")](https://yq.aliyun.com/go/articleRenderRedirect?url=http%3A%2F%2Fimages.cnitblog.com%2Fblog%2F124433%2F201310%2F17091425-90b280f0d0314ccb8cf48dc165034d85.png) 其中TSQLConnection的属性设置中LoginPrompt要设为False,TDSPProviderConnection的属性设置如下: [![image](http://ugc.qpic.cn/adapt/0/d150f0dd-8c9a-bbe2-79a3-f0e0c89ba4d1/800?pt=0&ek=1&kp=1&sce=0-12-12 "image")](https://yq.aliyun.com/go/articleRenderRedirect?url=http%3A%2F%2Fimages.cnitblog.com%2Fblog%2F124433%2F201310%2F17091433-cd55918928d24fa29e157660acf6e8e5.png) 其中ServerClassName是指应用服务器上作为数据服务提供主体的TDSServerModule的实例类名称,在这里我习惯性地重新命名了,缺省一般是TServerMethods1。TClientDataSet的设置如下图: [![image](http://images.cnitblog.com/blog/124433/201310/17091442-c02c6805990e487b86bd3e4cf62b8c1c.png?pt=5&ek=1&kp=1&sce=0-12-12 "image")](https://yq.aliyun.com/go/articleRenderRedirect?url=http%3A%2F%2Fimages.cnitblog.com%2Fblog%2F124433%2F201310%2F17091439-1507353250b04e15a51f3cb4315ca4bf.png) 为实现应用服务器上Sample Methods在客户端的调用,需要创建服务类在客户端的实现类,右键点击TSQLConnection选择生成,如下图: [![image](http://images.cnitblog.com/blog/124433/201310/17091451-f8b9ae73f0f04567ae1c4d2cf9351a63.png?pt=5&ek=1&kp=1&sce=0-12-12 "image")](https://yq.aliyun.com/go/articleRenderRedirect?url=http%3A%2F%2Fimages.cnitblog.com%2Fblog%2F124433%2F201310%2F17091447-954e94e6d60a472691fe9ec89ff58ec4.png) 新生成的类定义如下: [![image](http://images.cnitblog.com/blog/124433/201310/17091459-304c295f1c1f40379a71d633b3bf7faa.png?pt=5&ek=1&kp=1&sce=0-12-12 "image")](https://yq.aliyun.com/go/articleRenderRedirect?url=http%3A%2F%2Fimages.cnitblog.com%2Fblog%2F124433%2F201310%2F17091453-1a69541be686451e91fa5e6f4c246660.png) 以上过程完全同Windows下的DataSnap客户端开发。 (4)Android界面显示数据 Android下对数据的显示,与Windows下开发最大的区别是,无法使用TDBEdit一类的数据感应控件,取而代之的是标准控件,通过LiveBindings技术实现数据感应。要实现该过程,首先是在窗体上放置用于数据展示的标准控件,这里采用了TListBox和TGrid,通过TTabControl分开,如下图: [![image](http://images.cnitblog.com/blog/124433/201310/17091512-462c340db4354e2684dd7f419f726da5.png?pt=5&ek=1&kp=1&sce=0-12-12 "image")](https://yq.aliyun.com/go/articleRenderRedirect?url=http%3A%2F%2Fimages.cnitblog.com%2Fblog%2F124433%2F201310%2F17091506-d6c3017e75c44696b4dcae043a5e15ff.png) IP和Port输入框是为了更灵活地连接服务器,下面的按钮OnClick事件代码如下: procedure TfrmMain.Button1Click(Sender: TObject);  var    dm : TdmServerMethodsClient;  begin    try     //连接指定IP和Port的应用服务器      dmMain.SQLConn.Close;      dmMain.SQLConn.Params.Values\['HostName'\] := edtIP.Text;      dmMain.SQLConn.Params.Values\['Port'\] := edtPort.Text;      try        dmMain.SQLConn.Open;        try        //创建应用服务器上的Sample Methods在客户端的实现类          dm := TdmServerMethodsClient.Create(dmMain.SQLConn.DBXConnection);       //执行服务器上的方法          ShowMessage(dm.ReverseString(edtIP.Text));        finally          dm.Free;        end;       //开启客户端数据集        dmMain.cdsanimals.Close;        dmMain.cdsanimals.Open;      except        on E: Exception do          ShowMessage(E.Message);      end;    finally      dmMain.SQLConn.Close;    end;  end;  客户端界面与数据集之间采用LiveBindings方式,最好是打开LiveBindings设计页面,如下图: [![image](http://images.cnitblog.com/blog/124433/201310/17091517-8762a3e369224c079e4c40fda43329b8.png?pt=5&ek=1&kp=1&sce=0-12-12 "image")](https://yq.aliyun.com/go/articleRenderRedirect?url=http%3A%2F%2Fimages.cnitblog.com%2Fblog%2F124433%2F201310%2F17091515-17e8c8f7e841452f9a558ece3d806da0.png) [![image](http://images.cnitblog.com/blog/124433/201310/17091521-9f61f0a5631648ed94b922597e8d6bf3.png?pt=5&ek=1&kp=1&sce=0-12-12 "image")](https://yq.aliyun.com/go/articleRenderRedirect?url=http%3A%2F%2Fimages.cnitblog.com%2Fblog%2F124433%2F201310%2F17091518-d3e3cf21139e412cafa0f0bf41d1a490.png) 由于TListBox只能显示一个字段数据,所以用另外一个窗体单独显示某条记录的详细信息,如下图: [![image](http://images.cnitblog.com/blog/124433/201310/17091531-dfec9e3b931f4831a8b57d20099e78e5.png?pt=5&ek=1&kp=1&sce=0-12-12 "image")](https://yq.aliyun.com/go/articleRenderRedirect?url=http%3A%2F%2Fimages.cnitblog.com%2Fblog%2F124433%2F201310%2F17091524-51972918aac74acc9baf5fada657bc9a.png) 启动并运行,点击按钮执行服务器函数后界面如下图: [![image](http://images.cnitblog.com/blog/124433/201310/17091544-5c32a7805a424ff790a351666d836e19.png?pt=5&ek=1&kp=1&sce=0-12-12 "image")](https://yq.aliyun.com/go/articleRenderRedirect?url=http%3A%2F%2Fimages.cnitblog.com%2Fblog%2F124433%2F201310%2F17091540-7d82b1e818c64885a8d09feaad65274f.png) TGrid展示数据如下图: [![image](http://images.cnitblog.com/blog/124433/201310/17091601-5cf94c644e7547faa6386a4e0b73c733.png?pt=5&ek=1&kp=1&sce=0-12-12 "image")](https://yq.aliyun.com/go/articleRenderRedirect?url=http%3A%2F%2Fimages.cnitblog.com%2Fblog%2F124433%2F201310%2F17091552-c98eb813d0a840f99b52282a00962182.png) TlistBox展示数据如下图: [![image](http://images.cnitblog.com/blog/124433/201310/17091608-d5f007d0a7ee41a2abd88c7a9976e578.png?pt=5&ek=1&kp=1&sce=0-12-12 "image")](https://yq.aliyun.com/go/articleRenderRedirect?url=http%3A%2F%2Fimages.cnitblog.com%2Fblog%2F124433%2F201310%2F17091605-c5f35d214e20476c8b9f36f7e2672559.png) 点击某条记录后,显示明细窗体,如下图: [![image](http://images.cnitblog.com/blog/124433/201310/17091615-3958bf7a1d0d474887518c3d74fa514c.png?pt=5&ek=1&kp=1&sce=0-12-12 "image")](https://yq.aliyun.com/go/articleRenderRedirect?url=http%3A%2F%2Fimages.cnitblog.com%2Fblog%2F124433%2F201310%2F17091611-ab9bcc02116e4a119374ed36fa8457b6.png) 结论: (1)Android下开发DataSnap客户端,对数据的处理和服务函数调用与Windows下一致; (2)Android客户端展示不能使用数据感应控件,只能使用标准控件,通过LiveBindings技术来实现数据关联; (3)Windows下使用TClientDataSet需要用到Midas.dll,在Android下这个问题不存在了,也不需要单独部署Midas支持的相关文件,但是看材料iOS下好像还要部署,没试过