移动开发多平台代码共享

简介:   做移动开发快一年了,有幸接触了WM、Symbian、Android、iPhone等多个平台的开发。往往一个软件需要实现多个平台的版本,对于不同平台进行重新编码是一件很费劲的事情,其实我们可以通过代码共用技术,实现对一些代码的重用。
+关注继续查看

  做移动开发快一年了,有幸接触了WM、Symbian、Android、iPhone等多个平台的开发。往往一个软件需要实现多个平台的版本,对于不同平台进行重新编码是一件很费劲的事情,其实我们可以通过代码共用技术,实现对一些代码的重用。

  这一技术的应用,可用带来不少的好处:

  1. 代码重用:节约开发和维护的时间

  2. 核心代码的保护:将核心代码编译成库,只将库而不是源代码提供给上层开发人员使用。

  3. 。。。。。。

  本文将实现一个支持这几个平台的天气信息查询软件,软件采用C语言去实现调用WebService接口获取天气信息的功能,并将其编译成各种平台能够调用的库,而UI则采用各个平台各自的语言去实现,最终实现底层代码的共用。

先来看看最终的效果图:

  一、底层代码的实现

  我们要调用到WebService接口,需要使用网络

  而对于不同的平台socket的使用上有细微差异,我通过条件编译的方式,实现对不同平台的兼容。

  下面是实现代码:


//对于VC的DLL,需要导出函数,而其他的则不需要
头文件Common.h
#ifdef _MSC_VER
#define DLLFLAG _declspec(dllexport)
#
else
#define DLLFLAG
""
#endif
//通过WebService接口获取天气信息
DLLFLAG char* getWeather(const char *cityName);
源文件Common.c
#include
<string.h>
#include
<Common.h>
#include
<stdlib.h>
//根据系统加载不同的网络库
#ifdef _MSC_VER
#include
<winsock2.h>
#pragma comment(lib,
"winsock.lib")
#
else
#include
<sys/socket.h>
#include
<netinet/in.h>
#include
<arpa/inet.h>
#include
<netdb.h>
#endif
#define BUFSIZ
4096
DLLFLAG
char* getWeather(const char *pCityName)
{
//对于VC需要初始化socket版本
#ifdef _MSC_VER
WSADATA wsaData;
int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );
#endif
int sockfd = 0;
struct sockaddr_in addr;
char text[BUFSIZ] = "";
char header[BUFSIZ] = "";
char *content = (char*)malloc(BUFSIZ);
sockfd
= socket(AF_INET, SOCK_STREAM, 0);
addr.sin_family
= AF_INET;
//不同平台填充地址字段的方式不同
#ifdef _MSC_VER
addr.sin_addr.S_un.S_addr
=inet_addr("222.73.218.218");
#
else
inet_aton(
"222.73.218.218",&addr.sin_addr);
#endif
addr.sin_port
= htons(80);
memset(header,
0, sizeof(header));
strcat(header,
"GET /Service.asmx/getWeatherbyCityName?theCityName=");
strcat(header, pCityName);
strcat(header,
"&theDayFlag=Today HTTP/1.1rn");
strcat(header,
"Host: www.ayandy.comrnrn");
connect(sockfd,(struct sockaddr
*)&addr,sizeof(struct sockaddr_in));
send(sockfd, header, strlen(header),
0);
memset(text,
0, BUFSIZ);
memset(content,
0, BUFSIZ);
recv(sockfd, text, BUFSIZ,
0);
strcat(content, text);
//while ( recv(sockfd, text, BUFSIZ, 0) > 0)
//{
// strcat(content, text);
// memset(text, 0, BUFSIZ);
//}
//不同平台关闭socket的方法不同
#ifdef _MSC_VER
closesocket(sockfd);
WSACleanup();
#
else
shutdown(sockfd, SHUT_RDWR);
#endif
return content;
}

  二、Windows Mobile 平台

  对于WM平台,为了与底层库相区别,我们就不用VC去实现UI,而使用C#来实现UI。

  1. 编译dll

  Visual C++  – 智能设备 – 由于没有好的dll模板,我们就建一个“MFC智能设备DLL”,

  取名ShareLib,然后在生成的项目中删除掉没用的文件(比如预编译啥的),添加我们的底层代码文件Common.h和 Common.c,最终文件结构如图:

  然后编译,最终会生成ShareLib.dll文件。

  2. 实现主界面

  新建一个C#的智能设备项目,取名ShareLibTest。

  在Form1.cs文件中,添加对于dll的引用:


[DllImport(@"ShareLib.dll",CharSet=CharSet.Unicode) ]
public static extern IntPtr getWeather(string cityName);

  然后进行界面的设计,最终界面如图:

  然后给按钮设置点击事件:


try
{
byte[] paraByte = Encoding.UTF8.GetBytes(txtLocation.Text);
IntPtr p
= getWeather(Encoding.Unicode.GetString(paraByte, 0, paraByte.Length));
string newWeather = Marshal.PtrToStringUni(p);
byte[] strByte = Encoding.Unicode.GetBytes(newWeather);
newWeather
= Encoding.UTF8.GetString(strByte, 0, strByte.Length);
int a = newWeather.IndexOf("/>");
int b = newWeather.IndexOf("http://");
int aLength = "/>".Length;
newWeather
= newWeather.Substring(a + aLength, b - a - aLength);
newWeather
= newWeather.Replace("", "").Replace("", "");
txtWeatherInfo.Text
= newWeather;
}
catch (System.Exception )
{
}

  代码中关键的一句就是使用Marshal完成从c的char* 转换为C#的string,还有,需要注意字符的编码,否则可能会导致获取的数据乱码。

  最终,运行程序就能看到效果了。

  三、Android平台

  1. 编译so

  对于Android平台,我们用Java实现UI。

  在java中,要调用C/C++,需要使用jni技术。

  我们先写一个java类JniTest.java。

  代码如下:


public class JniTest {
public native String getWeather(String cityNmae);
}

  然后打开命令提示符:


//输入:
javac JniTest.java
//然后输入:
javah -jni com.luzj.ShareLibTest.JniTest

  最终就会产生com_luzj_ShareLibTest_JniTest.h 文件,复制一份,将后者改为.c。

  打开com_luzj_ShareLibTest_JniTest.c文件,通过#include ”Common.h” 引入底层代码。

  然后去实现那个getWeather函数,在这个函数中主要完成对java的String和C的char*的相互转换工作,代码如下:


const char* name = (*env)->GetStringUTFChars(env, cityName, 0);
const char *cWeatherInfo = getWeather( name );
jstring weatherInfo
= (*env)->NewStringUTF(env, cWeatherInfo);
(
*env)->ReleaseStringUTFChars(env,cityName,name);
return weatherInfo;

  然后编写一个make文件Android.mk,代码如下:


LOCAL_PATH:= http://www.cnblogs.com/lib
include $(CLEAR_VARS)
LOCAL_MODULE :
= JniTest
LOCAL_SRC_FILES :
= com_luzj_ShareLibTest_JniTest.c Common.c
include $(BUILD_SHARED_LIBRARY)

  最后,使用NDK-build一下,就会生成Android可用的动态链接库.so文件了。

  2. 实现主界面

  没啥好说的,对于开发过Android的人都能做到。

  然后在Activity中通过代码加载动态链接库:


//加载c库
static {
System.loadLibrary(
"JniTest");
}

  最后在要获取天气数据的地方调用JniTest类的中的getWeather方法即可。

  四、iPhone平台

  在iPhone平台,对于UI,使用Obj-C来实现。

  在iPhone平台上,我们可以将公用代码编译成静态库然后给程序调用。

  1. 编译静态库

  首先,通过“Cocoa Touch Static Library”创建一个静态库的工程:

  将我们的底层库添加上去,编译一下,就会生成一个以“.a”为后缀的静态库了。

  2. 实现主界面

  拉个按钮到界面上去,给它添加事件。

  主要代码就下面两行,完成了NSString 与 char* 的相互转化,并调用了接口:


char* strWeatherInfo = getWeather([txtLocation.text UTF8String]);
NSString
*weatherInfo = [NSString stringWithUTF8String:strWeatherInfo];

  最后将数据显示到界面上即可。

  五、Symbian平台

  我始终对这个平台没啥好感,况且这个平台的开发本身就是使用C、C++,实现代码共用很容易的,在此我就不浪费笔墨了,有兴趣的自己试试。

  六、总结

  这一技术还是很有使用前景的,比如游戏开发者,可用通过代码共用,用Open GL 实现一个底层的游戏引擎给各个平台使用。

  由于时间的关系,代码中对于异常的处理和一些条件的判断都没有去做,有兴趣的同学自己完善!

  文章中的Demo已经打包,需要的可以自行下载。

  下载地址:http://u.115.com/file/dn69hko2

  在我的独立博客还有一些好文章,有兴趣的可以去看看:http://luzj.me/share-lib-test-mobil.html

目录
相关文章
|
10月前
|
移动开发 小程序 前端开发
YonBuilder移动开发平台功能大盘点
 YonBuilder是面向企业组织和个人开发者的低代码开发平台,实现无代码、低代码、专业代码开发三种模式。提供元数据驱动和画布构建两种开发方式,通过点击拖拽+自动化代码生成和移动多端编译的技术
138 0
YonBuilder移动开发平台功能大盘点
|
11月前
|
移动开发 缓存 安全
如何提升App用户隐私合规性?以YonBuilder移动开发平台APICloud为例
在移动应用开发领域,如果企业的应用程序未采用动态权限方式获取用户的隐私权限,将无法上架Google Play及国内的各大应用市场。对于一款标准的移动端商业app,动态权限功能已经成为必不可少的标配功能。 本文主要介绍如何使用YonBuilder移动开发技术,实现移动端的动态权限功能。
103 0
|
11月前
|
存储 XML 缓存
如何用App实现巡检业务数字化?以YonBuilder移动开发平台APICloud为例
一款消防检查app可以有效减少繁复工作、提升巡检效率。本文将详细介绍如何使用YonBuilder移动开发平台开发消防检查助手app。
251 0
|
存储 移动开发 数据可视化
YonBuilder移动开发平台(APICloud)6月SDK发版重点回顾!
APICloud6月发版重点 可视化更新 1. 新增:实时预览可独立窗口显示:实时预览面板支持独立窗口显示,节省可视化空间,并可以自由拖动位置显示,便于开发者进行合理的开发与调试 2. 新增:可视化页面新增组件大纲结构,开发者可以清晰查看当前可视化页面组件的层级结构
191 0
|
移动开发 运维 监控
移动化置地:移动开发平台EMAS内外兼修,助力流量聚合与效能变革
随着移动互联网的发展以及5G时代的到来,移动化数字化已经是各行业信息化建设的发展趋势。提升业务移动覆盖度,移动化是推动企业业务数字化的关键路径。华润置地“十三五”信息化规划,移动应用是重点建设内容之一。华润置地智能与信息化部积极推进移动化转型创新,与阿里云强强联合共建移动开发平台,旨在快速完成业务移动化的转型升级目标,助力业务开展和业绩达成。
移动化置地:移动开发平台EMAS内外兼修,助力流量聚合与效能变革
|
Web App开发 移动开发 运维
mPaaS:全新移动开发平台,只为打造性能更优越的App
基于移动开发现状与技术演进预判,提供移动开发强力解决方案,洞察 mPaaS 如何帮助企业有效降低技术门槛,减少研发成本,搭建更稳定、更流畅的移动 App。
1488 0
mPaaS:全新移动开发平台,只为打造性能更优越的App
|
移动开发 人工智能 开发框架
|
移动开发 开发框架 分布式计算
蚂蚁金服联合IDC发布《中国金融级移动应用开发平台白皮书》 金融机构加速执行移动优先战略
蚂蚁金服联合国际数据公司IDC在第二十七届中国国际金融展上发布[《移动金融科技助力新时代金融机构转型升级——中国金融级移动应用开发平台白皮书》
759 0
蚂蚁金服联合IDC发布《中国金融级移动应用开发平台白皮书》 金融机构加速执行移动优先战略
相关产品
云迁移中心
推荐文章
更多