精华内容
下载资源
问答
  • 移动跨平台开发一步到位

    万人学习 2015-04-15 15:24:28
    基于.NET的移动跨平台开发教程,现在!.NET 不一样了,让你一统三国! 通过Xamarin开发套件,你将可以用 Visual Studio 及 C# 开发各移动平台 (Windows/iOS/Android) 的 App,而且执行效能一样好!让使用 .NET 技术...
  • GUI跨平台开发

    千次阅读 2019-06-13 22:45:54
    GUI跨平台开发 本文全平台是指:台式电脑系统WINDOWS/LINUX/MAC OS;智能设备系统IOS和安卓。 名称//语言//支持平台//官网 3D游戏引擎:虚幻||C++||全平台+游戏机平台+VR 3D游戏引擎:unity||C#||全平台+游戏...

    GUI跨平台开发

    本文全平台是指:台式电脑系统WINDOWS/LINUX/MAC OS;智能设备系统IOS和安卓。

    名称(组件)//语言//支持平台//官网

     

    Visual Studio with [.Net core(3.x) | .NET 5(2020年底)]||VB.NET, C#,VC++||Windows, Linux, macOs||https://dotnet.microsoft.com/download

    (目前VS+.NET CORE3.X已可以开发跨平台窗体程序.但没有窗体设计器!!!你必须用各种奇技淫巧或者代码拖放组件到窗体.窗体设计器目前仅在VS预览版中可用,微软正在拿小白做实验.当然毫无质疑未来窗体设计器必然会做进去,现在没做到正式版(生产环境VS)中去是因为技术太难了 程序员正在赶工中...基本上2020年底可以开发跨平台窗体程序了)

    注:VS+.NET CORE跨平台窗体程序Windows要求至少win7SP1以上(不支持XP).Linux和macOS平台要求没注意,不过用这俩平台的用户,操作系统应该会更新的很新,不用考虑类似XP这样持久力巨大的旧操作系统.

     

    3D游戏引擎:虚幻||C++||全平台+游戏机平台+VR

     

    3D游戏引擎:unity||C#||全平台+游戏机平台+VR

     

    Qt||C++||全平台

     

    wxWidgets||C++,多语言||全平台||https://www.wxwidgets.org/

     

    GTK||c/c++、多语言||全平台

     

    MonoDevelop||C#||Linux,Windows,macOS||https://www.monodevelop.com/||注:需要MONO,GTK#,windows平台还需要.NET及.NET Core

     

    RAD STUDIO(含DELPHI和C++Builder)with FireMonkey框架||Object Pacal,C++||全平台||https://www.embarcadero.com/||支持平台列表http://docwiki.embarcadero.com/RADStudio/Rio/en/Supported_Target_Platforms

    Lazarus(高度兼容DELPHI)||Free Pacasl||全平台||https://www.lazarus-ide.org/

     

    其他:《推荐8个免费实用的C++ GUI库》https://www.csdn.net/article/2012-05-30/2806134

     

    PYTHON GUI跨平台:

    PyQt:它是Python编程语言和Qt库的成功融合。

    wxPython:wxPython是作为优秀的跨平台GUI库wxWidgets的Python封装和Python模块的方式提供给用户的。

    Tkinter: 是 Python内置的标准 Tk GUI 工具包的接口 .Tk 和 Tkinter 可以在大多数的 Unix 平台下使用,同样可以应用在 Windows 和 Macintosh 系统里。Tk8.0 的后续版本可以实现本地窗口风格,并良好地运行在绝大多数平台中。

     

    APP跨平台

    基于HTML5,JS的:

     

    展开全文
  • 跨平台开发之Qt开发

    千次阅读 2016-01-22 13:10:10
    跨平台开发经验


    任何一种开发工具编译都至少包含两个步骤:

    1、Build

    2、run

    看起来是不是很简单,但是实际上底层可能比我们想象的要复杂的多。这主要是因为开发工具在底层帮我们完成了一些工作,比如make是有依赖文件的,Unix系列平台主要是makefile这种脚本文件,Window上vs有它自带的vcxproj, sln文件。window上其他开发工具也有的用makefile。因为makefile是脚本语言,平台通用的。

    如果进行细分的话,应该包括以下步骤:

    1、 生成编译依赖文件,或者手写

    2、Build

    3、linker

    4、install

    反正就是make一定有一个依赖文件,他不会直接根据源文件来编译的,因为他不知道用什么编译器,gcc还是msvc,还是其他交叉工具链。另外他也不知道要编译哪些文件。他还不知道是编译成动态库静态库还是执行文件,当然他也不知道他依赖的外部库和头文件在哪里找。

    今天主要讲一下Qt的跨平台开发是怎么解决以上问题的。

    先回答一下Qt是怎么解决以上几个问题的。pro文件也不例外需要解决上面几个问题,那么是怎么解决的呢?

    1) 指定编译器,工具链。

    这个可以到Tools->Options->Build&Run,然后选择qmake,编译器,调试工具等!


    需要自己安装编译器,会自动出现在这里,如果没有可以自己添加。

    关于Android编译器在另外一篇里已经谈到。所以C++ 程序员在window上是可以直接用Qt开发Android的,同样像Qt一样的语法。

    2)编译哪些文件,下面有些东西可以很好管理代码这就是pro文件的功能了,用pro文件可以很好的管理代码。

    如果只习惯使用qt自动生成的pro,容易缺少代码管理的习惯。

    如果有子工程:可以

    SUBDIR += 子工程目录,里面一定也要用pro文件

    平台控制:

    windows平台可以写成:

    win32:!wince{ #任意}

    这样就可以与其他平台区分了。

    wince:可能在qmake里增加 CONFIG +=wince然后,

    wince{}

    Linux:unix{}

    Android:android{}

    当然,如果你想增加自己的控制,也可以在CONFIG +=来增加,比如CONFIG +=msc,那么就可以

    msc{}

    来控制。

    增加宏定义:DEFINES +=ANDROID

    这个宏定义是用于作为在代码里进行编译开关的。跟在代码里写的#define一样。但是不觉得写到pro里对代码的管理能力更强吗。

    其他的还有equal,contains等条件语句。具体可以到源码里找。

    外部库文件:

    LIBS +=-L路径

    在代码里有时候用 #include "dir1/dir2/dir3/lib.h"等可能比较长,我们可以这样做:

    INCLUDEPATH += dir1/dir2/dir3/

    然后在代码里可以写成:#include <lib.h>或#include “lib.h"

    下面两个就是你自己的代码了。

    源文件:

    SOURCES +=

    头文件:

    HEADERS += 

    Install 主要是编译和链接完成后,打包的过程。

    可以把依赖的库文件,配置文件通过Install打包到编译目录去。具体过程,

    比如pthread的dll文件:

    thread.path=$$PWD_PATH/bin

    //这个是目标目录

    thread.files +=后面写文件所在的目录/*.dll,可以多个。

    参考后面的例子当然实现Install需要在Projects里增加一个make

    步骤,如下:


    下面看一个例子。

    #-------------------------------------------------
    #
    # Project created by QtCreator 2015-05-05T16:04:10
    #
    #-------------------------------------------------
    QT       += core gui network
    greaterThan(QT_MAJOR_VERSION, 4): QT += widgets multimedia
    win32:QT += axcontainer
    
    #QT += multimediawidgets
    #DEFINES +=VIDEO_STREAM_WIDGET
    
    DEFINES += __STDINT_MACROS  #for ffmpeg
    #CONFIG  += wince  ##wince
    
    TARGET = AppLink_HMI
    TEMPLATE = app
    
    MOC_DIR=temp/moc
    RCC_DIR=temp/rcc
    UI_DIR=temp/ui
    OBJECTS_DIR=temp/obj
    DESTDIR=bin
    
    target.path=$$OUT_PWD/bin
    INSTALLS+=target
    
    #qtdll.path=$$OUT_PWD/bin
    #qtdll.files=$$QMAKE_LIBDIR/*.dll
    #INSTALLS +=qtdll
    
    
    
    SOURCES += \
        main.cpp \
        HMI_SDK/Connect/SDLConnector.cpp \
        HMI_SDK/Connect/Channel.cpp \
        Tools/json/json_writer.cpp \
        Tools/json/json_valueiterator.inl \
        Tools/json/json_value.cpp \
        Tools/json/json_reader.cpp \
        HMI_SDK/AppData/AppList.cpp \
        HMI_SDK/AppData/AppData.cpp \
        UI/Alert/AlertUI.cpp \
        UI/AudioPassThru/AudioPassThru.cpp \
        UI/Choiceset/ChoicesetVR.cpp \
        UI/Choiceset/Choiceset.cpp \
        UI/Command/Command.cpp \
        UI/Common/ScrollBar.cpp \
        UI/Common/Button.cpp \
        UI/Common/MainMenu.cpp \
        UI/Common/BaseWidght.cpp \
        UI/Common/AppBase.cpp \
        UI/Common/AppItemWidget.cpp \
        UI/Config/Config.cpp \
        UI/ScrollableMessage/ScrollMsg.cpp \
        UI/Show/Show.cpp \
        UI/UIManager.cpp \
        UI/Slider/Slider.cpp \  
        UI/Notify/Notify.cpp \
        UI/Common/Background.cpp \
        UI/VideoStream/VideoStream.cpp \
        UI/TextSpeech/textspeech.cpp \
        UI/AudioTrans/AudioInput.cpp \
        UI/AudioTrans/MspVRAudio.cpp \
        UI/TextSpeech/TextToSpeech.cpp \
        UI/AudioTrans/AudioOutput.cpp \
        AppManager.cpp \
        UI/Common/AppListWidget.cpp \
        UI/Common/MenuButton.cpp \
        UI/AppLinkMenu.cpp \
        UI/Common/CAppButton.cpp  \
        HMI_SDK/Connect/BasicCommunication.cpp \
        HMI_SDK/Connect/Buttons.cpp \
        HMI_SDK/Connect/Navigation.cpp \
        HMI_SDK/Connect/SocketsToSDL.cpp \
        HMI_SDK/Connect/TTS.cpp \
        HMI_SDK/Connect/UI.cpp \
        HMI_SDK/Connect/VehicleInfo.cpp \
        HMI_SDK/Connect/VR.cpp \
        UI/AppList/AppListUI.cpp
    
    
    
    
    INCLUDEPATH += $$PWD/   \
                  $$PWD/HMI_SDK \
                  $$PWD/Tools  \
                  $$PWD/UI
    
    HEADERS  += HMI_SDK/AppData/AppListInterface.h \
        HMI_SDK/AppData/AppDataInterface.h \
        HMI_SDK/AppData/AppData.h \
        HMI_SDK/AppData/AppList.h \
        HMI_SDK/Connect/SDLConnector.h \
        HMI_SDK/Connect/Channel.h \
        HMI_SDK/Connect/IMessageInterface.h \
        HMI_SDK/Connect/SDLConnector.h \
        HMI_SDK/Connect/ISocketManager.h \
        Tools/json/version.h.in \
        Tools/json/json_tool.h \
        Tools/json/writer.h \
        Tools/json/version.h \
        Tools/json/value.h \
        Tools/json/reader.h \
        Tools/json/json.h \
        Tools/json/forwards.h \
        Tools/json/features.h \
        Tools/json/config.h \
        Tools/json/autolink.h \
        Tools/json/assertions.h \
        UI/Common/MainMenu.h \
        UI/Common/BaseWidght.h \
        UI/Common/AppBase.h \
        UI/UIInterface.h \
        UI/UIManager.h \
        UI/Alert/AlertUI.h \
        UI/AudioPassThru/AudioPassThru.h \
        UI/Choiceset/ChoicesetVR.h \
        UI/Choiceset/Choiceset.h \
        UI/Command/Command.h \
        UI/Common/ScrollBar.h \
        UI/Common/Button.h \
        UI/Common/AppItemWidget.h \
        UI/Config/Config.h \
        UI/ScrollableMessage/ScrollMsg.h \
        UI/Show/Show.h \
        UI/Slider/Slider.h \
        UI/Notify/Notify.h \
        UI/Common/Background.h \
        UI/VideoStream/VideoStream.h \
        UI/TextSpeech/textspeech.h \
        UI/AudioTrans/AudioInput.h \
        UI/AudioTrans/MspVRAudio.h \
        UI/TextSpeech/TextToSpeech.h \
        UI/Common/MenuButton.h \
        UI/AppLinkMenu.h \
        UI/Common/CAppButton.h \
        UI/AudioTrans/AudioOutput.h \
        AppManager.h \
        HMI_SDK/AppData/AppCommon.h \
        HMI_SDK/Connect/BasicCommunication.h \
        HMI_SDK/Connect/Buttons.h \
        HMI_SDK/Connect/Navigation.h \
        HMI_SDK/Connect/SocketsToSDL.h \
        HMI_SDK/Connect/TTS.h \
        HMI_SDK/Connect/UI.h \
        HMI_SDK/Connect/VehicleInfo.h \
        HMI_SDK/Connect/VR.h \
        Include/ProtocolDefines.h \
        UI/Common/AppListWidget.h \
        UI/UIInclude.h \
        UI/AppList/AppListUI.h
    
    
    RESOURCES += \
        UI/images.qrc
    
    OTHER_FILES += \
        UI/LiberationSerif-Regular.ttf
    
    INCLUDEPATH +=  $$PWD/Include/ffmpeg \
                    $$PWD/Include/msp
    
    ###############################for windows
    win32:!wince{
    DEFINES +=WIN32
    INCLUDEPATH += $$PWD/Include/pthread \
                   $$PWD/Include
    LIBS +=  $$PWD/Library/win32/pthread/pthreadVC2.lib
    LIBS +=  $$PWD/Library/win32/pthread/pthreadVCE2.lib
    LIBS +=  $$PWD/Library/win32/pthread/pthreadVSE2.lib
    LIBS +=  $$PWD/Library/win32/pthread/WS2_32.Lib
    #LIBS += -L$$PWD/lib/win32/ffmpeg -lavcodec -lavfilter -lavformat -lavutil -lswscale
    #win32: LIBS += -L$$PWD/ffmpeg/lib/ -lavcodec
    LIBS += $$PWD/Library/win32/ffmpeg/libavcodec.a  \
    $$PWD/Library/win32/ffmpeg/libavfilter.a  \
    $$PWD/Library/win32/ffmpeg/libavformat.a  \
    $$PWD/Library/win32/ffmpeg/libavutil.a  \
    $$PWD/Library/win32/ffmpeg/libswscale.a
    
    pthread.path=$$OUT_PWD/bin
    pthread.files=$$PWD/Library/win32/*.dll
    ffmpeg.path=$$OUT_PWD/bin
    ffmpeg.files=$$PWD/Library/win32/ffmpeg/*.dll  \
    $$PWD/Library/win32/pthread/*.dll
    INSTALLS+=pthread
    INSTALLS+=ffmpeg
    qt_dll.path=$$DESTDIR
    qt_dll.files=$$(QT_DIR)/bin/*.dll
    INSTALLS +=qt_dll
    }
    
    
    ################################for linux
    unix:!android:LIBS += -L$$PWD/Library/linux/ffmpeg -lavcodec  -lavformat -lavutil -lswscale
    
    ################################for wince
    wince{
    HEADERS += \
        Include/global_first.h \
        Include/unistd.h \
        Include/stdint.h
    INCLUDEPATH += $$PWD/Include/pthread \
                   $$PWD/Include
    LIBS +=  $$PWD/Library/ce/pthread.lib
    LIBS += -L$$PWD/Library/ce/ffmpeg  -lavcodec-55  -lavdevice-55 -lavfilter-3 -lavformat-55 -lavutil-52 -lswresample-0 -lswscale-2
    pthread.path=$$OUT_PWD/bin
    pthread.files=$$PWD/Library/ce/*.dll
    ffmpeg.path=$$OUT_PWD/bin
    ffmpeg.files=$$PWD/Library/ce/ffmpeg/*.dll
    
    INSTALLS +=pthread
    INSTALLS+=ffmpeg
    }
    
    
    ################################for android
    android{
    
    #CONFIG += msc
    #CONFIG += pico
    CONFIG  += espeak
    INCLUDEPATH +=  $$PWD/Include/msp \
                    $$PWD/Include/msp/android
    
    DEFINES +=ANDROID \
              SDL_SUPPORT_LIB \
              SDL_SUPPORT_VR
    
    LIBS += -L$$PWD/Library/android/ffmpeg -lffmpeg
    LIBS += -L$$PWD/Library/android/sdl -lsmartDeviceLinkCore
    LIBS += -L$$PWD/Library/android/msp  -llib_msp_vr
    ANDROID_EXTRA_LIBS = \
            $$PWD/Library/android/ffmpeg/libffmpeg.so \
            $$PWD/Library/android/sdl/libsmartDeviceLinkCore.so
    msc{
    DEFINES += TTS_FLY_MSC
    LIBS += -L$$PWD/Library/android/msp  -lmsc
    #RESOURCES += Library/android/sdl/tts/msctts.qrc
    ANDROID_EXTRA_LIBS +=$$PWD/Library/android/msp/libmsc.so
    }
    pico{
    DEFINES +=TTS_ANDROID_SELF
    LIBS += -L$$PWD/Library/android/msp  -lttspico -lttscompat
    ANDROID_EXTRA_LIBS +=$$PWD/Library/android/msp/libttspico.so \
           $$PWD/Library/android/msp/libttscompat.so
    }
    espeak{
    DEFINES += TTS_ESPEAK
    LIBS += -L$$PWD/Library/android/msp -lttsespeak
    ANDROID_EXTRA_LIBS +=$$PWD/Library/android/msp/libttsespeak.so
    }
    
    RESOURCES += \
        Library/android/sdl/config/android.qrc \
        Config/config.qrc
    }
    
    
    !android{
    configfile.path=$$OUT_PWD/bin/Config
    configfile.files=$$PWD/Config/*
    INSTALLS +=configfile
    }
    
    
    
    #ANDROID_PACKAGE_SOURCE_DIR = $$PWD/Library/android/apk
    



    展开全文
  • C++跨平台开发技术指南.pdf

    热门讨论 2013-02-27 17:37:46
    《C++跨平台开发技术指南.pdf 》很实用的书籍。跨平台开发值得一看。
  • 移动跨平台开发深度解析

    千次阅读 2018-08-09 22:14:33
    注:本文为转载文章,部分内容参考移动端跨平台开发的深度解析,并做了精简和加工。 概述 移动跨平台开发一直是移动开发者和前端开发者追求的的话题,从早期的cordova、ionic,到如今的react native、weex、kotlin...

    注:本文为转载文章,部分内容参考移动端跨平台开发的深度解析,并做了精简和加工。

    概述

    移动跨平台开发一直是移动开发者和前端开发者追求的的话题,从早期的cordova、ionic,到如今的react native、weex、kotlin native和flutter等,可以说如今的跨平台框架可谓百花齐放,颇有一股推倒原生开发者的势头。

    如果要对目前的跨平台的方案进行一个总结,大致可以分为以下几个流派:
    JavaScript流派:这一流派中,最明显的特征是使用JavaScript作为编程语言,react native、weex均属于这一流派。和其他跨平台方案相比,JavaScript在跨平台开发中,使用者最多,大有“一统天下”的趋势。
    VM虚拟机:与其他方案不同,kotlin提供的kotlin-native技术拥有自己的VM,可以同时支持Android、iOS 和 Web 开发。
    Flutter:Futter是Google开源的移动跨平台UI框架,使用的是Google自己的Dart编程语言,由于是Google推出的产品,因而也受到很多开发者的喜爱。

    不过,综合对比开发现,目前最火的跨平台开发方案,特别是已经商用的跨平台开发框架中,react native无疑是老大,其次是Weex(毕竟是阿里的产品),最后可能是最近才火起来的Flutter。

    这里写图片描述

    React Native

    曾经,React Native的口号是“Learn once, write anywhere”,这句话代表了FaceBook对React Native设计的初衷:学习 react ,同时掌握 web 与 app 两种开发技能。

    借助FaceBook旗下的React的设计模式 , React Native使用的UI渲染、动画效果、网络请求等会转换成原生端的实现。也就是说,开发者编写的js代码,通过 react native 的中间层(JavaScriptCore)转化为原生控件和操作,这就最大程度的接近原生应用的用户体验,并提高了开发的效率。

    React Native的结构

    React Native的跨平台是实现主要由三层构成,其中 C++ 实现的动态连结库(.so),作为中间适配层桥接,实现了js端与原生端的双向通信交互。

    这里最主要是封装了 JavaScriptCore 执行js的解析,而 react native 运行在JavaScriptCore中,所以不存在浏览器兼容的问题。其结构如如下图:
    这里写图片描述

    原理

    React Native实现的原理其实就是利用JS 调用Native 端的组件,并使用Native的组件来绘制界面,从而达到媲美原生应用的效果。

    和前端开发不同,React Native 所使用的标签并不是真实的控件,React Native提供的组件会Dom 转换为Native的控件进行渲染。例如<Text> 标签会被转换为Android 中对应 TextView 控件。
    这里写图片描述

    需要说明的是,在React Native 中,JS端是运行在独立的线程中(称为JS Thread ),JS Thread 作为单线程逻辑,不可能处理耗时的操作。那么如 fetch 、图片加载 、 数据持久化等操作,在 Android 中实际对应的是 okhttp 、Fresco 、SharedPreferences等。而跨线程通信,也意味着 Js Thread 和原生之间交互与通讯是异步的。

    由此可以看出,跨平台的关键在于C++层,开发人员大部分时候,只专注于JS 端的代码实现即可,无线了解底层的实现细节。 而如果要实现和原生模块的交互,只需要在原生端提供的各种 Native Module 模块(如网络请求,ViewGroup控件)即可,然后通过 JS 端提供的各种 JS Module(如JS EventEmiter模块)来实现调用。并且这些调用都会在C++实现的so中保存起来,双方的通讯通过C++中的保存的映射,最终实现两端的交互,通信的数据和指令,在中间层会被转为String字符串传输,双向的调用流程如下图。
    这里写图片描述

    打包与发布

    在React Native混合项目中,JS代码会被打包成一个 bundle 文件,自动添加到 App 的资源目录下。react native 的打包脚本目录为/node_modules/react-native/local-cli,打包最后会通过 metro 模块压缩 bundle 文件。而bundle文件只会打包js代码,自然不会包含图片等静态资源,所以打包后的静态资源,其实是被拷贝到对应的平台资源文件夹中。

    举个例子,react native 项目会将图片存储在根目录下的 img/pic/logo.png 的资源,编译时,会被重命名后,根据大小 merged 到对应的是drawable目录下,修改名称为img_pic_logo.png。

    Weex

    Weex是阿里巴巴开源的一套移动跨平台开发框架,能够完美兼顾性能与动态性,让移动开发者通过简捷的前端语法写出Native级别的性能体验,并支持iOS、安卓、YunOS及Web等多端部署。目前,使用Weex框架的多半是阿里系的产品和一些创业的公司。

    Weex架构

    Weex的口号是“Write once, run everywhere”,Weex使用的耳熟能详的Vue,阿里的思维是:写个 vue 前端,顺便完成一个apk 和 ipa,但其实还是有差距的。Weex支持 web、android、ios 三端,原生端同样通过中间层转化,将控件和操作转化为原生逻辑来提高用户体验。。

    在 Weex的架构层次中,主要包括三大部分:JS Bridge、Render、Dom,分别对应WXBridgeManager、WXRenderManager、WXDomManager,三部分通过WXSDKManager统一管理。其中 JS Bridge 和 Dom 都运行在独立的 HandlerThread 中,而 Render 运行在 UI 线程。关于Weex架构分层的内容读者可以自行查看官方资料的介绍。

    其中,JS Bridge 主要用来和 JS 端实现进行双向通信,比如把 JS 端的 dom 结构传递给 Dom 线程。Dom 主要是用于负责 dom 的解析、映射、添加等等的操作,最后通知UI线程更新。而 Render 负责在UI线程中对 dom 实现渲染。
    这里写图片描述

    实现原理

    和 React Native一样,Weex 所有的标签也不是真实控件,Weex的标签只不过是JS 代码中所生成存的 dom,最后都是由 Native 端解析,再得到对应的Native控件渲染。如 Android 中 <text> 标签对应 WXTextView 控件。

    Weex 中文件默认为 .vue ,而 vue 文件是被无法直接运行的,所以 vue 会被编译成 .js 格式的文件,Weex SDK会负责加载渲染这个js文件。Weex可以做到跨三端的原理在于:在开发过程中,代码模式、编译过程、模板组件、数据绑定、生命周期等上层语法是一致的。

    不同的是,在 JS Framework 层的最后,web 平台和 Native 平台,对 Virtual DOM 执行的解析方法是有区别的,在渲染真实 UI 的时候调用的接口也不同的。
    这里写图片描述
    Weex 表面上是一个客户端技术,但实际上它串联起了从本地开发、云端部署到分发的整个链路。开发者首先可在本地像编写 web 页面一样编写一个 app 的界面,然后通过命令行工具将之编译成一段 JavaScript 代码,生成一个 Weex 的 JS bundle;同时,开发者可以将生成的 JS bundle 部署至云端,然后通过网络请求或预下发的方式加载至用户的移动应用客户端;在移动应用客户端里,Weex SDK 会准备好一个 JavaScript 执行环境,并且在用户打开一个 Weex 页面时在这个执行环境中执行相应的 JS bundle,并将执行过程中产生的各种命令发送到 native 端进行界面渲染、数据存储、网络通信、调用设备功能及用户交互响应等功能;同时,如果用户希望使用浏览器访问这个界面,那么他可以在浏览器里打开一个相同的 web 页面,这个页面和移动应用使用相同的页面源代码,但被编译成适合Web展示的JS Bundle,通过浏览器里的 JavaScript 引擎及 Weex SDK 运行起来的。

    这里写图片描述
    其中, Native 加载bundle 文件大致经历了以下阶段:

    • weex 接收到 js 文件以后,JS Framework 根据文件为 Vue 模式,会调用weex-vue-framework 中提供的createInstance方法创建实例。
    • createInstance 中会执行 Js Entry 代码里 new Vue() 创建一个组件,通过其 render 函数创建出 Virtual DOM 节点。
    • 由JS V8 引擎上解析 Virtual DOM ,得到 Json 数据发送至 Dom 线,这里输出 Json 也是方便跨端的数据传输。
    • Dom 线程解析 Json 数据,得到对应的 WxDomObject,然后创建对应的WxComponent 提交 Render 。
    • Render在原生端最终处理处理渲染任务,并回调里JS方法。

    相比React Native,Weex主要是在JS V8的引擎上多了 JS Framework 承当了重要的职责,使得上层具备统一性,可以支持跨三个平台。总的来说它主要负责是:管理Weex的生命周期,解析JS Bundle,转为Virtual DOM,再通过所在平台不同的API方法,构建页面;进行双向的数据交互和响应。

    打包与发布

    在打包方案上,Weex和React Native都通过 Webpack 来打包bundle 文件的。不过,React Native打包如果不做拆分,打出的包是很大的,因而会自己制定一些拆包的规则。而Weex 作为React Native之后出现的跨平台实现方案,自然可以站在前人的肩膀上优化问题,比如:Bundle文件过大问题。 Weex 选择使用JS Framework 集成到 WeexSDK的方式,一定程度减少了JS Bundle的体积,使得 bundle 里面只保留业务代码。

    打包时,weex 是通过 webpack 打包出 bundle 文件的。bundle 文件的打包和 entry.js 文件的配置数量有关,默认情况下之后一个 entry 文件,自然也就只有一个bundle文件。

    在 weex 项目的 webpack.common.conf.js 中可以看到,其实打包也是区分了 webConfig 和 weexConfig 的不同打包方式。

    Flutter

    Flutter是Google用以帮助开发者在Ios和Android两个平台开发高质量原生应用的全新移动UI框架。与 React Native 和 Weex 框架使用的Javascript 技术不同,Flutter 使用的是全新的编程语言Drat,所以执行时并不需要 Javascript 引擎,但实际效果最终也通过原生渲染。

    Flutter框架

    Flutter框架主要分为 Framework 和 Engine两层,我们基于Framework 开发App主要运行在 Engine 上。Engine 是 Flutter 的独立虚拟机,由它适配和提供跨平台支持,目前猜测 Flutter 应用程序在 Android 上,是直接运行 Engine 上 所以在是不需要Dalvik虚拟机。其架构图如下图所示:
    这里写图片描述

    得益于 Engine 层,Flutter 甚至不使用移动平台的原生控件, 而是使用自己 Engine 来绘制 Widget (Flutter的显示单元),而 Dart 代码都是通过 AOT 编译为平台的原生代码,所以 Flutter 可以 直接与平台通信,不需要JS引擎的桥接。
    这里写图片描述

    而Flutter唯一要求系统提供的是canvas,用以实现UI的绘制。不过,Flutter 上 Android 自带了 Skia,Skia是一个 2D的绘图引擎库,跨平台,所以可以被嵌入到 Flutter的 iOS SDK中,也使得 Flutter Android SDK要比 iOS SDK小很多。

    对比

    下面对上面介绍的几大框架进行一个简单的对比,以方便读者进行对比学习。

    对比类型 React Native Weex Flutter
    实现技术 JavaScript JavaScript 原生编码,无桥接
    引擎 JS V8 JSCore Flutter engine
    使用语言 React Vue Dart
    bundle文件大小 默认单一、较大 较小、多页面可多文件 不需要
    上手难度 稍高大 容易 简单
    框架难度 较重 较轻
    支持对象 Android、IOS Android、IOS、Web Android、IOS

    包大小对比

    上面Apk大小是通过 react-native init、weex create 和 flutter 创建出的工程后,直接不添加任何代码,打包出来的 release 签名 apk 大小。从下图可以看出,其中大比例都是在so库。

    这里写图片描述

    附:
    React Native中文网
    Weex官方文档
    Flutter中文社区

    展开全文
  • 跨平台开发实践之Flutter

    千次阅读 2019-08-23 20:18:44
    跨平台开发实践之Flutter 先说点废话。今天的主题关于跨平台开发技术的。跨平台开发大家应该都了解,无非就是写一套代码可以运行在两个甚至多个平台之上,而对于我们客户端/前端开发来说,跨平台一般就是跨现在主流...

    跨平台开发实践之Flutter

    先说点废话。今天的主题关于跨平台开发技术的。跨平台开发大家应该都了解,无非就是写一套代码可以运行在两个甚至多个平台之上,而对于我们客户端/前端开发来说,跨平台一般就是跨现在主流的Android和iOS两个移动端平台,再牛逼一点的可以加上Web浏览器。

    目前业内也有很多跨平台解决方案,例如Hybird、ReactNative、微信小程序、阿里的Weex、微软的Cordova、Xamarin等。其中一些方案甚至被叫嚣要取代原生开发,当然目前看来是不可能的。因为尽管前面说的几种跨平台方案可以做到多端复用,动态更新,但是都避不开老生常谈的问题,就是在高要求下的加载渲染效率和复杂动画交互的实现,它们做的都不如原生应用。

    然后再说今天和大家分享一个开发框架Flutter,它与其他跨平台方案都不同,一统天下可能很难,但是我觉得是目前最优的跨平台解决方案。

    Flutter是什么

    官方定义:
    Flutter是Google发布的一款UI开发工具集,开发语言是Dart。用它可以为移动端web浏览器PC桌面构建漂亮的,本机编译的应用程序,关键是用的同一套代码。

    在这里大家比较关注的点,应该是一套代码可以运行在不同的平台上。官方说明的手机平台只包含了Android和iOS系统,等后面大家了解完Flutter跨平台原理后就会发现,Flutter构建的应用应该可以运行在其他移动操作系统上,例如阿里的云OS,甚至是华为新推出的鸿蒙系统,甚至是Web和PC平台上。

    由于Web浏览器的特殊性(因为Web应用只能访问浏览器提供的API,而无法直接访问系统API),所以Flutter在Web浏览器上运行的机制和其他平台不一样,这里先简单说一下。
    我们都知道,在浏览器运行的web页面必须符合三大标准,即HTML、CSS和JavaScript,通过这三剑客来实现页面呈现和业务逻辑处理,其他的东西浏览器是不承认的。

    大家看一下这张图,Framework层就用Dart编写的,面向开发者的API,可以实现业务布局和业务逻辑,这一部分在不同的平台上是一样的。主要是看下面的dart:ui部分是如何实现。Flutter Web Engine是Flutter开发团队自己实现的一个Web引擎,简单来说就是把Dart编写的页面转换成浏览器认识的HTML、CSS和JavaScript。当然,这个转换过程并不是一对一映射((完整说明见https://medium.com/flutter/hummingbird-building-flutter-for-the-web-e687c2a023a8)),而是根据不同的内容选择不同的图片实现(HTML + CSS + Canvas )。
    Dart Code -> JS -> HTML + CSS + Canvas -> 浏览器渲染

    Flutter特性:

    • 高性能 媲美原生应用的界面渲染性能-60fps,但是Flutter的目标远不止如此。Flutter在发布之初号称可以达到120fps,这是可以达到游戏甚至VR应用的渲染效率的要求的。不过我们不能只听Google的一面之词,要自己亲测之后才踏实。不过到目前为止我还没有自己上手来对原生和Flutter的效率作对比。不过我们可以先参考一下其他公司的测试结果。2018年8月,美团用Flutter写一个全品类页面,在使用过程中根本察觉不出来区别,经过数据统计,渲染10000帧过程中,Android原生平均耗时10.21ms,Flutter平均耗时12.28ms。这是在没有对Flutter的页面做任何过度绘制、缓存优化的前提下的测试结果。
    • 漂亮的UI Flutter允许开发者控制屏幕上的每一个像素,从而达到在不同平台上拥有高度一致的外观表现,同时内置了Material和Cupertino风格的UI组件。
    • 快速开发 相对于原生应用的耗时开发流程(编辑、编译、安装、启动、显示),Flutter支持了在Web开发过程中才能体验到的热重载功能(编译、显示)
    • 开源 Flutter是一个基于BSD-style的开源项目,任何开发者都可以获取源码或贡献自己的代码。

    历史和现状:
    2014.10 Flutter的前身Sky在Github上开源

    2015.10 经过一年的开源,Sky正式改名为Flutter。在Dart开发者峰会上发布了第一个版本。

    2018.02 在世界移动大会(MWC)发布首个Beta版

    2018.06 在(GMTC)发布首个预览版

    2018.12 在Flutter Live2018上发布1.0稳定版。
    变更:
    全新iOS风格的widget
    接入约20种Firebase服务
    使用Dart 2.1,生成更小的代码和更快的速度

    2019.02 在世界移动大会(MWC)发布1.2
    变更:
    提升框架性能和质量
    视频播放、WebView、Maps等bug修复
    支持Android App Bundle
    基于Web的编程工具套件
    支持前端开发者使用HTML和CSS语法编写应用

    2019.05 在Google IO大会上发布1.7,也是目前最新版本。
    变更:
    支持Android X
    支持32位和64位的Android App Bundle和Apk
    更新小部件RangeSlider以及更复杂的排版
    支持游戏控制器

    趋势:

    [外链图片转存失败(img-vE5IEYDG-1566562914259)(media/15454717435900/3465086455-5d0cafa0245c7_articlex.jpeg)]

    从Github上的Star数来看,在Google刚推出Flutter时发展很缓慢,直到18年2月发布首个Beta版本后迎来了爆发性增长,12月发布第一个正式后增长更快。目前在Github上,Flutter项目的Star数为72895,要知道Facebook的react-native的Star数为80113.

    由于Flutter的诸多优势,我们熟悉的很多大厂都开始应用Flutter到自家的产品中。
    例如Google旗下的Google Ads、阿里旗下的闲鱼、腾讯旗下的NOW直播、头条的抖音等等。还有我司现在正在接入的Square公司的刷卡功能,Square都已经提供了Flutter版本的SDK。

    尽管许多大厂开始将Flutter应用到商业中,但并不代表Flutter已经非常完美和稳定了。比如一些非常关键的功能还仍处于预览状态,包括将Flutter和原生的混合开发;在Web浏览器中运行Flutter应用。

    Flutter怎么来的

    通过对Eric的访谈可以知道:

    Eric Seidel是Flutter团队的头头。Eric之前是做Web开发的,在Chrome团队工作,并且很擅长图像渲染这一领域。在某段时间,他们遇到了一些问题,他们想让Web中的一部分能够拥有更加平滑的体验,于是他们做了一个试验,考虑到不一定非要与Web兼容,于是开始删代码,删除那些为了兼容旧的访问方式的支持代码,把Web开发中不常用的内容全部删除。最后对精简后代码做了一次基准测试,发现效率提高了20倍。
    再之后研究就属于Flutter项目的范畴了。

    在2015年4月的Dart开发者会议上,Eric分享了Sky项目,也就是Flutter前身,并且现场用Android手机演示了用Dart写的应用程序,声称达到120fps的渲染效率。

    Flutter框架结构

    Flutter框架的整体架构也是分层的,貌似分层架构是解决复杂项目实现的不二法则。看到这张图让我想到了Android系统的框架结构、网络协议栈的结构、还有我们App的项目结构,呵呵。

    Flutter整体氛围三层:
    1、框架层,由Dart编写。
    2、引擎层,由C/C++编写。
    3、平台嵌入层,由平台对应语言实现。

    通过这张架构图可以看出,Flutter中平台相关的特性很少,所以当宿主系统升级时,Flutter不需要很多的适配开发工作。

    框架层

    Widgets是UI组件部分,其中Material和Cupertino是对Widgets的封装,方便开发者实现不同的风格的App,减少开发量。

    框架层的Rendering和引擎中的Rendering模块代表了Flutter对视图树的抽象、布局、绘制的逻辑,也就是说Flutter的UI框架的图像渲染是自己做的,既不依赖WebView,也不委托给原生。

    再往下的Animation、Painting、Gestures是Flutter提供的动画、绘图、手势处理的Api。

    Foundation 是一些Dart语言提供的一些常用的库,例如网络和IO。

    引擎层

    Platform Channels + Native Plugins实现了Dart语言和原生语言的通信机制。

    SystemEvents来处理系统事件,比如触摸、键盘输入、屏幕反转等。

    Service Protocol 扩展服务,例如性能检测、应用信息追踪、调试

    Composition 多个图层合并,提交渲染效率

    Dart VM Management,Dart虚拟机管理。

    Frame Scheduling和Frame Pipelining负责帧图像的调度和排序。

    TextLayout则专门负责文字排版

    嵌入层

    因为Flutter本身还是依附在一个原生的页面上的,比如Android中的Activity、iOS中的ViewController。而且系统的Api访问还是得通过原生环境桥接一下。
    所以不可避免的会对不同平台做对应的适配。
    Render Surface Setup,设置原生环境的渲染图层,例如Android中的SurfaceView。

    Packaging,打包成对应平台的安装包时,需要把上面两层东西一并打包。

    Thread Setup,其实Flutter的运行线程是由系统的线程策略实现的。

    Event Loop Interoperability,事件循环操作

    为什么选择Dart

    有很多说,没有选择JavaScript作为开发语言,会严重影响Flutter的推广。毕竟JavaScript如此普遍,相对于新学一门语言,开发人员转移到Flutter的学习成本会很低。

    我们想到的,人家Flutter团队不可能想不到。那为什么Flutter还是选择了Dart?想知道为什么,还得深挖一下Dart的历史。

    Dart历史:

    Dart是Google在2011推出了一款应用Web开发的语言,它的团队由Chrome浏览器V8引擎团队的Lars Bak主持,它的推出目的是取代JavaScript做前端开发,成为下一代结构化Web开发语言。Dart提供两种方式运行:一是运行在本地虚拟机上。二是将代码转换成JavaScript。
    然而由于Node.js的火爆将JavaScript推到了前后端通吃的地位,Dart也就慢慢退出了开发者的视野,直到改变思路应用于移动端开发后,焕发了第二春。

    那Flutter团队为什么没有选择开发者群体更多的JavaScript语音,或者使用C++语言来达到更简便的框架结构,因为用C++直接可以调用Skia,可以直接与原生代码通信(不再需要Dart桥接到C/C++,C/C++再JNI桥接到Java)。

    我觉得原因很简单:

    1. Flutter团队成员来源于Chrome团队,他们在萌生这个想法时都是以前端语言来测试的。
    2. JavaScript虽然开发者更熟悉,但弊端也在这里,就是想要改变或新增JavaScript的语言来适应移动开发太难了,需要标准委员会的层层把关和审核,而Dart就不需要,Dart团队就在隔壁,可以非常积极快速的配合Flutte做改动
    3. Dart是Google推出的语言,理所当然推广自家语言更合情合理。如果所有开发者都使用Dart做移动端,甚至前端和PC端开发,那么Google就可以一统大前端江湖。
    4. Dart也必须不负Flutter众望,必须有杀手锏来达到高效率的图像渲染。

    跨平台历史及技术区别

    纯Web时代

    Hybird(Html + JsBridge)Cordova

    完全利用Web标准,依赖WebView的渲染能力,完全能满足产品或设计对页面实现要求。
    为了能访问原生Api,需要原生配合开发一套桥接的接口,暴露出原生系统接口能力。

    缺点也很明白,WebView是一个重量级组件,并且Html/Js/css的加载、解析、渲染过程非常耗时。
    当然我们可以做成离线方式,将Html页面提前下载到本地,这样会提高加载的速度。但是由于WebView对Html页面的解析、渲染都是在一个线程中执行的,对于复杂的交互和页面动画实现上,效果差强人意。

    泛Web时代

    ReactNative Weex 小程序 快应用

    虽然还是使用JavaScript语言基于WebView开发,但是自定义一套控件标签,并一一映射到原生控件,将页面渲染委托给原生系统,所以渲染速度上会优于纯Web方式。而且单独使用js引擎自定义了js的解析,例如iOS的jscore、小程序用腾讯自己的X5浏览器内核,快应用用阿里的UC浏览器内核。

    映射到原生控件的方式显示比WebView渲染能力高一些,所以这些方案在发布的时候就标榜自己能达到原生应用的用户体验。但是这种方式有两个缺点:第一个还是构建复杂交互时要依赖映射方案中提供的接口,如果不满足还是要原生开发配合来一对一挖细节来实现,甚至直接由原生页面实现。第二个是系统升级后,会有新的原生组件出现,或者旧的组件弃用,所以系统适配的难度较大。

    方法包装时代

    Xamarin C#实现

    自绘引擎时代

    Flutter

    基于高效的2D渲染引擎Skia,完全独立的UI绘制渲染逻辑,不依赖WebView,也不依赖原生控件,能完全解决前面的跨平台方案的最大短板。
    当然,如果需要访问系统Api的话,还得额外需要插件开发,将Dart与原生语言建立通信渠道。这是每个跨平台方案都躲不过的一道坎,那么如果系统的UI开发框架就是Flutter呢?例如Fuchsia, 那就不需要插件开发了。

    那么Flutter就没有缺点了么?
    1、安装包体积过大。相对原生开发出来的安装包,Flutter应用安装包大很多,一个Demo示例都要10M左右的体积。因为要把Flutter运行环境、Skia绘图引擎、还有其他一些支持库打包进apk、ipa中。
    2、不能动态化部署,因为不像JavaScript是解释执行的,在正式发布时,Dart是完全编译成机器码的,并且不支持反射。
    3、调用系统Api时需要额外的通信,所以调用效率肯定比原生差一些
    4、目前的混合开发功能还处于预览状态,如果需要混合开发需要自己搞一套机制(原生页面与Flutter页面栈管理、多个Flutter环境的资源使用问题)出来,闲鱼团队已经做了一些努力。

    总结

    我们通过Flutter可以构建出媲美原生的跨平台应用,其基本原理就是重写UI绘制逻辑,通过高效的2D绘制引擎Skia实现页面的快速渲染。同时提供了开发友好的JIT模式,提高了开发效率。

    展开全文
  • 移动端跨平台开发分析与比较

    千次阅读 2019-05-15 14:06:07
    移动端跨平台开发前言移动端开发开发方式跨平台开发技术 跨平台开发已经不是什么新鲜的词了,现在再来整理这些有点为时过晚了,不过还是想把自己这两年在投入在移动端跨平台开发上的一些经验和一些踩的头破血流的...
  • 近年来,移动端上各种跨平台开发方案百花齐放,一方面是因为随着移动互联网的迅猛发展,纯原生开发无法满足业务快速增长的需求;另一方面,跨平台可以增加代码复用,降低开发成本。在移动终端设备的软硬件、操作系统...
  • deviceone 跨平台开发

    2017-03-09 16:07:58
    lz最近很忙 好久没更新blog了好久没搞android了 最近一直在学习js语言和跨平台开发 工具那么多 lz用的deviceone!说实话 真的很快速 官方封装的各种框架底层 用起来简单的不得了!简单直接 粗暴 有效果 也有各位大神...
  • Kotlin跨平台开发(一)

    千次阅读 2020-03-04 16:38:38
    Kotlin跨平台开发 今天我们来简单介绍一下使用kotlin进行跨平台开发,使得一处代码,多处运行。 一、简介 首先,我摘取了一些官方文档上的基本介绍。 kotlin语言在一开始设计的时候就有一个明确的目标,那就是...
  • App跨平台开发框架分析

    千次阅读 2017-09-11 20:52:39
    所谓的跨平台app开发就是一套代码写完以后可以多端发布运行到各个平台,比如:安卓、iOS、web。 原生开发是一对一的,安卓、... 目前移动端App有很多都已经采用跨平台开发技术。流行的技术有Html5混合开发和Reat Nativ
  • 近年来,伴随着大前端概念的提出和兴起,移动端和前端的边界变得越来越模糊,一大批移动跨平台开发框架和模式涌现出来。从早期的PhoneGap、Inoic 等Hybrid技术,到现在耳熟能详的React Native、WEEX和Flutter等跨...
  • App跨平台开发方案与取舍

    万次阅读 2016-03-15 16:53:08
    App跨平台开发方案与抉择内心强大才敢于承认错误,但是首先你要敢于去试错。现在做客户端开发的公司都会面临一个巨大的问题,那么就是跨平台。对于目前上市面上的移动设备来说。Android、IOS、WindowsPhone、...
  • JDFlutter 京东跨平台开发框架!

    千次阅读 2019-05-20 18:34:25
    JDFlutter 是商城共享技术部-多端融合技术部推出的新一代跨平台开发框架,可快速集成至现有 Android/iOS 工程,开发者可借助 JDFlutter 平台快速完成 Flutter 业务开发。JDFlutter 平台提供了大多数京东样式 UI ...
  • 推荐几款App跨平台开发工具

    千次阅读 2015-09-28 01:45:01
    不少跨平台开发工具便应运而生,选择一款适合自己的工具尤为重要,下面这几款跨平台开发工具或者框架可以帮你轻松完成App开发。1、RhoMobileRhoMobile提供了Rhodes,这是一种基于Ruby的开源框架。这个工具让开发人员...
  • 聊聊移动端跨平台开发的各种技术

    千次阅读 2018-02-28 21:00:24
    聊聊移动端跨平台开发的各种技术介绍最近出现的 React Native 再次让跨平台移动端开发这个话题火起来了,曾经大家以为在手机上可以像桌面那样通过 Web 技术来实现跨平台开发,却大多因为性能或功能问题而放弃,不得...
  • 大家好,目前正在做跨平台开发,需要用c++调第三方SDK(高德地图,jar包),请问有没有相关的知识或文档可供参考,如能告知,不胜感激!
  • 转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具、解决方案和服务,赋能开发者。 ... 多年来,跨平台移动开发已经获得了...这并不令人意外,因为采用跨平台开发技术使得软件工程师使用同一代码就能...
  • 跨平台开发学习笔记

    2014-12-30 11:22:59
    由于在公司做平台开发项目以及自己对这种突破的渴望,在这跨平台开发方面的知识补充了不少,也认识了不少。知道MSVC只是一个集成开发环境,它用的编译器是cl.exe,链接器是link.exe,项目管理工具MSBuild,*.vcxprj...
  • 跨平台开发框架 weex 上手

    千次阅读 2016-06-15 13:16:57
    跨平台开发框架 weex 上手 本机系统:deepin 15.2 weex官网传送门 无论什么跨平台框架,都是让你用一种语言间接的调用现有平台的功能,现在这一类框架层出不穷,weex是由阿里巴巴开源,从阿里巴巴一线技术中...
  • 现在看到好多跨平台开发工具,开发出来的效果比较好,比较流畅,作为一名android开发者,有些为前途担忧,你们觉得这些跨平台开发者会在一定程度上取代掉我们这些android和ios开发者吗。
  • Weex 阿里跨平台开发组件扩展库

    千次阅读 2018-06-11 10:10:33
    为解决目前移动开发频繁的迭代、开发周期长、人员成本高的问题,移动跨平台开发方案层出不穷。 WeexPlus则是一款基于阿里weex跨平台方案(android/ios/h5)开发的weex端与android native交互的组件扩展库,提供页面...
  • 跨平台开发框架也是不断的演变,从早期的Cordova到现在的React Native、Flutter等,经过多年的沉淀,各项技术也在逐步完善,那我们可以结合以下优缺点分析,再考虑是否选择跨平台开发。 先说优点: (1)操作简单...
  • ASP.NET Core跨平台开发实战

    万人学习 2019-08-04 20:08:47
  • Qt跨平台开发环境搭建

    千次阅读 2015-10-25 16:00:54
    Qt跨平台开发环境搭建   1. 背景介绍 Qt是一个跨平台的C++图形用户界面应用程序框架。它提供给应用程序开发者丰富的图形用户界面所需的所有功能。而且,Qt很容易扩展,并且允许真正地组件编程。基本上,Qt 同...
  • 移动应用跨平台开发技术方向对比

    千次阅读 2014-09-02 14:34:13
    我们盘点一下近几年移动跨平台开发工具。随着ios、android的成熟,移动应用开发需求剧增。国内外出现大量的移动应用跨平台开发工具。 跨平台开发工具从技术上大体分为三类,一、脚本解析型。 二、web模式。三、翻译...
  • 刚接触Qt,ESRI针对Qt推出的SDK也不太了解,二者结合进行跨平台开发,现在连helloword都编译失败,求大神指点。
  • Visual Stdio实现云+端跨平台开发优势(csdn会议总结):

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 39,549
精华内容 15,819
关键字:

跨平台开发