精华内容
下载资源
问答
  • 所谓混合开发,指的是 App 的整体架构以原生技术栈为基础,将 Flutter 运行环境嵌入到原生 App 工程中,然后由原生开发人员为 Flutter 运行提供宿主容器及基础能力支撑,而 Flutter 开发人员则负责应用层业务及 App ...
  • 需要与原生进行混合开发的时候,前端应该怎么做? 1.先引入js unfile.js 下载unifile.js的链接 2.调用方法,在要使用原生技术的页面进行引入 import bridge from '../../common/unfile.js' 3.就可以使用了 //调用...
  • Go+Python双语言混合开发-盯紧技术先机抓紧高薪机遇,完整版53章,2021年新课。60小时加强训练,0基础入门Go,自研微服务框架、打造电商系统。Go+Python自研一个“微服务”框架:从0开始围绕grpc开发微服务 Go+...
  • 本篇文章主要给大家讲述了在用H5混合开发APP时,IOS项目中遇到的坑以及解决办法,需要的朋友参考一下吧。
  • 本篇文章主要介绍了H5混合开发app如何升级的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • 一、混合开发介绍 1.1、什么是混合开发? 1.2、混合开发优缺点 1.3、混合开发应用场景 1.4、了解混合开发的意义 二、混合开发的核心技术 2.1、混合开发核心技术——JSBridge 2.2、混合开发主流技术框架 2.3、...
  • vue开发h5项目特别是移动端的项目,很多都是打包后挂载在原生APP上的,这篇文章主要介绍了vue与原生app的对接交互的方法,非常具有实用价值,需要的朋友可以参考下
  • 现在很多的 APP中会嵌套HTML5的页面,这篇文章主要介绍了详解android与HTML混合开发总结的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • android原生组件与h5混合开发
  • 移动端app开发,原生开发与混合开发的区别

    万次阅读 多人点赞 2019-09-26 18:47:01
    目前市场上主流的APP分为三种:原生APP、Web APP(即HTML5)和混合APP三种,相对应的定制开发就是原生开发、H5开发和混合开发。那么这三种开发模式究竟有何不同呢?下面我们就分别从这三者各自的优劣势来区分比较吧...

    目前市场上主流的APP分为三种:原生APP、Web APP(即HTML5)和混合APP三种,相对应的定制开发就是原生开发、H5开发和混合开发。那么这三种开发模式究竟有何不同呢?下面我们就分别从这三者各自的优劣势来区分比较吧!
    一、APP原生开发
    原生开发(Native App开发),是在Android、IOS等移动平台上利用提供的开发语言、开发类库、开发工具进行App软件开发。比如Android是利用Java、Eclipse、Android studio;IOS是利用Objective-C 和Xcode进行开发。
    通俗点来讲,原生开发就像盖房子一样,先打地基然后浇地梁、房屋结构、一砖一瓦、钢筋水泥、电路走向等,都是经过精心的设计。原生APP也一样:通过代码从每个页面、每个功能、每个效果、每个逻辑、每个步骤全部用代码写出来,一层层,一段段全用代码写出来。
    优点:
    1、可访问手机所有功能(如GPS、摄像头等)、可实现功能齐全;
    2、运行速度快、性能高,绝佳的用户体验;
    3、支持大量图形和动画,不卡顿,反应快;
    4、兼容性高,每个代码都经过程序员精心设计,一般不会出现闪退的情况,还能防止病毒和漏洞的出现;
    5、比较快捷地使用设备端提供的接口,处理速度上有优势。
    缺点:
    1、开发时间长,快则3个月左右完成,慢则五个月左右;
    2、制作费用高昂,成本较高;
    3、可移植性比较差,一款原生的App,Android和IOS都要各自开发,同样的逻辑、界面要写两套;
    4、内容限制(App Store限制);
    5、获得新版本时需重新下载应用更新。
    二、Web APP (HTML5)开发
    HTML5应用开发,是利用Web技术进行的App开发。Web技术本身需要浏览器的支持才能进行展示和用户交互,因此主要用到的技术是HTML5、Javascript、CSS等。
    优点:
    1、支持设备范围广,可以跨平台,编写的代码可以同时在Android、IOS、Windows上运行;
    2、开发成本低、周期短;
    3、无内容限制;
    4、适合展示有大段文字(如新闻、攻略等),且格式比较丰富(如加粗,字体多样)的页面;
    5、用户可以直接使用新版本(自动更新,不需用户手动更新)。
    缺点:
    1、由于Web技术本身的限制,H5移动应用不能直接访问设备硬件和离线存储,所以在体验和性能上有很大的局限性;
    2、对联网要求高,离线不能做任何操作;
    3、功能有限;
    4、APP反应速度慢,页面切换流畅性较差;
    5、图片和动画支持性不高;
    6、用户体验感较差;
    7、无法调用手机硬件(摄像头、麦克风等)。
    三、混合APP开发(原生+H5)
    混合开发(Hybrid App开发),是指在开发一款App产品的时候,为了提高效率、节省成本而利用原生与H5的开发技术的混合应用。通俗点来说,这就是网页的模式,通常由“HTML5云网站+APP应用客户端”两部份构成。
    混合开发是一种取长补短的开发模式,原生代码部分利用Web View插件或者其它框架为H5提供容器,程序主要的业务实现、界面展示都是利用与H5相关的Web技术进行实现的。比如京东、淘宝、今日头条等APP都是利用混合开发模式而成的。
    优点:
    1、开发效率高,节约时间。同一套代码Android和IOS基本上都可使用;
    2、更新和部署比较方便,每次升级版本只需要在服务器端升级即可,不再需要上传到App Store进行审核;
    3、代码维护方便、版本更新快,节省产品成本;
    4、比web版实现功能多;
    5、可离线运行。
    缺点:
    1、功能/界面无法自定:所有内容都是固定的,不能换界面或增加功能;
    2、加载缓慢/网络要求高:混合APP数据需要全部从服务器调取,每个页面都需要重新下载,因此打开速度慢,网络占用高,缓冲时间长,容易让用户反感;
    3、安全性比较低:代码都是以前的老代码,不能很好地兼容新手机系统,且安全性较低,网络发展这么快,病毒这么多,如果不实时更新,定期检查,容易产生漏洞,造成直接经济损失;
    4、既懂原生开发又懂H5开发的高端人才难找。
    以上就是原生开发、H5开发和混合开发各自的优缺点。相比之下,由于现代人的个性化需求越来越明显,所以原生APP开发也越来越多,定制化的服务更能满足消费者的需求。若您也想要定制一款别开生面的APP,就来找我们吧!

    展开全文
  • 移动应用开发的方式,目前主要有三种:NativeApp:本地应用程序(原生App)WebApp:网页应用程序(移动web)HybridApp:混合应用程序(混合App)图1:三种移动应用开发方式如图1所示,三种移动应用开发方式具体
  • hybrid混合开发

    2017-11-28 19:42:32
    什么是混合开发混合开发中weex,react native ,ionic 的个性
  • 安卓混合开发

    2017-03-14 00:21:09
    安卓混合开发
  • Android混合开发的基本框架,JavaScript和java之间的桥梁
  • android + h5 混合开发 webview 版 小实例 + 数据交互 + 界面交互+ js调用java +java 调用js
  • 使用APICloud混合开发

    2017-07-28 10:46:32
    使用APICloud编写的一个测试项目
  • Android和ReactNative混合开发Demo,包含Android原生加载RN页面,Android原生调用RN函数,RN函数调用原生函数
  • 混合app开发工具类文件,包含离线打包需要的jar工具文件、文件说明、实例、配置信息等
  • 给大家分析一下在用MUI进行APP混合开发的时候,如何用代码实现下拉刷新和上拉加载这个普遍应用的功能。
  • Rexxar 是一个针对移动端的混合开发框架。现在支持 Android 和 iOS 平台。Rexxar-iOS 是 Rexxar 在 iOS 系统上的客户端实现。
  • React Native Android混合开发实用教程

    千次阅读 2018-08-28 23:01:18
    在React Native的应用场景中,有时候一个APP只有部分页面是由React Native实现的,比如:我们常用的携程App,它的首页下的很多模块都是由React Native实现的,这种开发模式被称为混合开发混合开发的一些其他应用...

    期待已久的新课上线啦!解锁React Native开发新姿势,一网打尽React Native最新与最热技术,点我Get!!!

    在React Native的应用场景中,有时候一个APP只有部分页面是由React Native实现的,比如:我们常用的携程App,它的首页下的很多模块都是由React Native实现的,这种开发模式被称为混合开发。

    混合开发的一些其他应用场景:

    在原有项目中加入RN页面,在RN项目中加入原生页面

    RNHybrid

    原生页面中嵌入RN模块

    Native-RN-page

    RN页面中嵌入原生模块

    RN-Native-page

    以上这些都属于React Native混合开发的范畴,那么如何进行React Native混合开发呢?

    在这篇文章中我将向大家介绍React Native混合开发的流程,需要掌握的技术,以及一些经验技巧,与该文章配套的还有React Native与Android 混合开发讲解的视频教程

    React Native混合开发的教程我们分为上下两篇,上篇主要介绍**如何在现有的Android应用上进行React Native混合开发,下篇主要介绍如何在现有的iOS应用上进行React Native混合开发**。

    将React Native集成到现有的Android应用中需要如下几个主要步骤:

    • 首先,你需要有一个React Native项目;
    • 为已存在的Android应用添加React Native所需要的依赖;
    • 创建index.js并添加你的React Native代码;
    • 创建一个Activity来承载React Native,在这个Activity中创建一个ReactRootView来作为React Native服务的容器;
    • 启动React Native的Packager服务,运行应用;
    • (可选)根据需要添加更多React Native的组件;
    • 运行、调试、打包、发布应用;
    • 升职加薪、迎娶白富美,走向人生巅峰!;

    1. 创建一个React Native项目

    在做混合开发之前我们首先需要创建一个没有Android和iOS模块的React Native项目。我们可以通过两种方式来创建一个这样的React Native项目:

    • 通过npm安装react-native的方式添加一个React Native项目;
    • 通过react-native init来初始化一个React Native项目;

    通过npm安装react-native的方式添加一个React Native项目

    第一步:创建一个名为RNHybridApp的目录,然后在该目录下添加一个包含如下信息的package.json

    {
      "name": "RNHybrid",
      "version": "0.0.1",
      "private": true,
      "scripts": {
        "start": "node node_modules/react-native/local-cli/cli.js start"
      }
    }
    

    第二步:在为package.json添加react-native

    在该目录下执行:

    npm install --save react-native
    

    执行完上述命令之后,你会看到如下警告:

    npm-install--save-react-native.png

    其中,有一条警告npm WARN react-native@0.55.4 requires a peer of react@16.3.1 but none is installed告诉我们需要安装react@16.3.1

    npm install --save react@16.3.1
    

    至此,一个不含Android和iOS模块的React Native项目便创建好了。此过程所遇到的更多问题可查阅:React Native与Android 混合开发讲解的视频教程

    提示:npm 会在你的目录下创建一个node_modulesnode_modules体积很大且是动态生成了,建议将其添加到.gitignore文件中;

    通过react-native init来初始化一个React Native项目

    除了上述方式之外,我们也可以通过react-native init命令来初始化一个React Native项目。

    react-native init RNHybrid
    

    上述命令会初始化一个完成的名为RNHybrid的React Native项目,然后我们将里面的androidios目录删除,替换成已存在Android和iOS项目。

    2. 添加React Native所需要的依赖

    在上文中我们已经创建了个一个React Native项目,接下来我们来看一下如何将这个React Native项目和我们已经存在的Native项目进行融合。

    在进行融合之前我们需要将已经存在的Native项目放到我们创建的RNHybrid下,比如:我有一个名为RNHybridAndroid的Android项目,将其放到RNHybrid目录下:

    RNHybrid
    ├── RNHybridAndroid
    ├── package.json
    ├── node_modules
    └── .gitignore
    

    第一步:配置maven

    接下来我们需要为已经存在的RNHybridAndroid项目添加 React Native依赖,在RNHybrid/RNHybridAndroid/app/build.gradle文件中添加如下代码:

    dependencies {
        compile 'com.android.support:appcompat-v7:23.0.1'
        ...
        compile "com.facebook.react:react-native:+" // From node_modules
    }
    

    app-build.gradle

    然后,我们为RNHybridAndroid项目配置使用的本地React Native maven目录,在RNHybrid/RNHybridAndroid/build.gradle文件中添加如下代码:

    allprojects {
        repositories {
            mavenLocal()
            maven {
                // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
                url "$rootDir/../node_modules/react-native/android"
            }
            ...
        }
        ...
    }
    

    maven-directory-to-build.gradle

    提示:为确保你配置的目录正确,可以通过在Android Studio中运行Gradle sync 看是否有 “Failed to resolve: com.facebook.react:react-native:0.x.x" 的错误出现,没有错误则说明配置正确,否则说明配置路由有问题。
    此过程所遇到的更多问题可查阅:React Native与Android 混合开发讲解的视频教程

    第二步:配置权限

    接下来我们为APP运行配置所需要的权限:检查你项目中的AndroidManifest.xml文件中看是否有如下权限:

    <uses-permission android:name="android.permission.INTERNET" />
    

    如果没有,则需要将上述权限添加到AndroidManifest.xml中。

    另外,如果你需要用到RN的Dev Settings功能:

    DevSettingsActivity

    则需要在AndroidManifest.xml文件中添加如下代码:

    <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
    

    提示:上述图片就是RN 开发调试弹框中的Dev Settings功能,打开该功能会弹出上图的一个界面,这个界面就是DevSettingsActivity。

    第三步:指定要ndk需要兼容的架构(重要)

    Android不能同时加载多种架构的so库,现在很多Android第三方sdks对abi的支持比较全,可能会包含armeabi, armeabi-v7a,x86, arm64-v8a,x86_64五种abi,如果不加限制直接引用会自动编译出支持5种abi的APK,而Android设备会从这些abi进行中优先选择某一个,比如:arm64-v8a,但如果其他sdk不支持这个架构的abi的话就会出现crash。如下图:

    libgnustl_shared.so"-is-32-bit-instead-of-64-bit

    怎么解决呢:

    app/gradle 文件中添加如下代码:

    defaultConfig {
    ....
        ndk {
            abiFilters "armeabi-v7a", "x86"
        }
    }
    

    上述代码的意思是,限制打包的so库只包含armeabi-v7ax86此过程所遇到的更多问题可查阅:React Native与Android 混合开发讲解的视频教程

    可参考:libgnustl_shared.so" is 32-bit instead of 64-bit

    3.创建index.js并添加你的React Native代码

    通过上述两步,我们已经为RNHybridAndroid项目添加了React Native依赖,接下来我们来开发一些JS代码。

    在RNHybrid目录下创建一个index.js文件并添加如下代码:

    import { AppRegistry } from 'react-native';
    import App from './App';
    
    AppRegistry.registerComponent('App1', () => App);
    

    上述代码,AppRegistry.registerComponent('App1', () => App);目的是向React Native注册一个名为App1的组件,然后我会在第四步给大家介绍如何在Android中加载并显示出这个组件。

    另外,在上述代码中我们引用了一个App.js文件:

    import React, { Component } from 'react';
    import {
      Platform,
      StyleSheet,
      Text,
      View
    } from 'react-native';
    
    type Props = {};
    export default class App extends Component<Props> {
      render() {
        return (
          <View style={styles.container}>
            <Text style={styles.welcome}>
              this is App
            </Text>
          </View>
        );
      }
    }
    
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#F5FCFF',
      },
      welcome: {
        fontSize: 20,
        textAlign: 'center',
        margin: 10,
      }
     });
    

    这个App.js文件代表了我们React Native的一个页面,在这个页面中显示了this is App的文本内容。

    以上就是为本次演示所添加的React Native代码,你也可以根据需要添加更多的React Native代码以及组件出来。

    4. 为React Native创建一个Activity来作为容器

    经过上述3、4步,我们已经为RNHybridAndroid项目添加了React Native依赖,并且创建一些React Native代码和注册了一个名为App1的组件,接下来我们来学习下如何在RNHybridAndroid项目中使用这个App1组件。

    创建RNPageActivity

    首先我们需要创建一个Activity来作为React Native的容器,

    public class RNPageActivity extends AppCompatActivity implements DefaultHardwareBackBtnHandler {
        private ReactRootView mReactRootView;
        private ReactInstanceManager mReactInstanceManager;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            mReactRootView = new ReactRootView(this);
            mReactInstanceManager = ReactInstanceManager.builder()
                .setApplication(getApplication())
                .setBundleAssetName("index.android.bundle")
                .setJSMainModulePath("index")
                .addPackage(new MainReactPackage())
                .setUseDeveloperSupport(BuildConfig.DEBUG)
                .setInitialLifecycleState(LifecycleState.RESUMED)
                .build();
            // 这个"App1"名字一定要和我们在index.js中注册的名字保持一致AppRegistry.registerComponent()
            mReactRootView.startReactApplication(mReactInstanceManager, "App1", null);
    
            setContentView(mReactRootView);
        }
    
        @Override
        public void invokeDefaultOnBackPressed() {
            super.onBackPressed();
        }
    }
    

    参数说明

    • setBundleAssetName:打包时放在assets目录下的JS bundle包的名字,App release之后会从该目录下加载JS bundle;
    • setJSMainModulePath:JS bundle中主入口的文件名,也就是我们上文中创建的那个index.js文件;
    • addPackage:向RN添加Native Moudle,在上述代码中我们添加了new MainReactPackage()这个是必须的,另外,如果我们创建一些其他的Native Moudle也需要通过addPackage的方式将其注册到RN中。需要指出的是RN除了这个方法外,也提供了一个addPackages方法用于批量向RN添加Native Moudle;
    • setUseDeveloperSupport:设置RN是否开启开发者模式(debugging,reload,dev memu),比如我们常用开发者弹框;
    • setInitialLifecycleState:通过这个方法来设置RN初始化时所处的生命周期状态,一般设置成LifecycleState.RESUMED就行,和下文讲的Activity容器的生命周期状态关联;
    • mReactRootView.startReactApplication:它的第一个参数是mReactInstanceManager,第二个参数是我们在index.js中注册的组件的名字,第三个参数接受一个Bundle来作为RN初始化时传递给JS的初始化数据,它的具体用法我会在**React Android 混合开发讲解的视频教程**中再具体的讲解;

    在中AndroidManifest.xml注册一个RNPageActivity

    Android系统要求,每一个要打开的Activity都要在AndroidManifest.xml中进行注册:

    <activity
        android:name=".RNPageActivity"
        android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
        android:windowSoftInputMode="adjustResize"
        android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
    

    上述代码中我们为RNPageActivity添加了一个@style/Theme.AppCompat.Light.NoActionBar类型的theme,这也是React Native UI组件所要求的主题。

    为ReactInstanceManager添加Activity的生命周期回调

    一个 ReactInstanceManager可以被多个activities或fragments共享,所以我们需要在Activity的生命周期中回调ReactInstanceManager的对于的方法。

     @Override
    protected void onPause() {
        super.onPause();
    
        if (mReactInstanceManager != null) {
            mReactInstanceManager.onHostPause(this);
        }
    }
    
    @Override
    protected void onResume() {
        super.onResume();
    
        if (mReactInstanceManager != null) {
            mReactInstanceManager.onHostResume(this, this);
        }
    }
    
    @Override
    public void onBackPressed() {
        if (mReactInstanceManager != null) {
            mReactInstanceManager.onBackPressed();
        } else {
            super.onBackPressed();
        }
    }
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
    
        if (mReactInstanceManager != null) {
            mReactInstanceManager.onHostDestroy(this);
        }
        if (mReactRootView != null) {
            mReactRootView.unmountReactApplication();
        }
    }
    

    从上述代码中你会发现有个不属于Activity生命周期中的方法onBackPressed,添加它的目的主要是为了当用户单击手机的返回键之后将事件传递给JS,如果JS消费了这个事件,Native就不再消费了,如果JS没有消费这个事件那么RN会回调invokeDefaultOnBackPressed代码。

    @Override
    public void invokeDefaultOnBackPressed() {
        super.onBackPressed();
    }
    

    此过程更细致的讲解可查阅:React Native与Android 混合开发讲解的视频教程

    添加开发者菜单

    在RN中有个很好用的工具开发者菜单,我们平时调试RN应用时对它的使用频率很高,接下来我们来为RNHybridAndroid添加开着菜单。

     public boolean onKeyUp(int keyCode, KeyEvent event) {
        if (getUseDeveloperSupport()) {
            if (keyCode == KeyEvent.KEYCODE_MENU) {//Ctrl + M 打开RN开发者菜单
                mReactInstanceManager.showDevOptionsDialog();
                return true;
            }
    	}
        return super.onKeyUp(keyCode, event);
    }
    

    通过上代码即可监听Ctrl + M来打开RN开发者菜单。

    ctrl+m-android

    另外,RN也提供了双击R来快速加载JS的功能,通过如下代码即可打开该功能:

    public boolean onKeyUp(int keyCode, KeyEvent event) {
        if (getUseDeveloperSupport()) {
            if (keyCode == KeyEvent.KEYCODE_MENU) {//Ctrl + M 打开RN开发者菜单
                mReactInstanceManager.showDevOptionsDialog();
                return true;
            }
            boolean didDoubleTapR = Assertions.assertNotNull(mDoubleTapReloadRecognizer).didDoubleTapR(keyCode, getCurrentFocus());
            if (didDoubleTapR) {//双击R 重新加载JS
                mReactInstanceManager.getDevSupportManager().handleReloadJS();
                return true;
            }
        }
        return super.onKeyUp(keyCode, event);
    }
    

    此过程更细致的讲解可查阅:React Native与Android 混合开发讲解的视频教程

    使用ReactActivity来作为RN容器

    在上述的代码中我们都是通过ReactInstanceManager来创建和加载JS的,然后重写了Activity的生命周期来对ReactInstanceManager进行回调,另外,重写了onKeyUp来启用开发者菜单等功能。

    另外,查看RN的源码你会发现在RN sdk中有个叫ReactActivity的Activity,该Activity是RN官方封装的一个RN容器。另外,在通过react-native init命令初始化的一个项目中你会发现有个MainActivity是继承ReactActivity的,接下来我们就来继承ReactActivity来封装一个RN容器。

    public class ReactPageActivity extends ReactActivity implements IJSBridge{
        /**
         * Returns the name of the main component registered from JavaScript.
         * This is used to schedule rendering of the component.
         */
        @Override
        protected String getMainComponentName() {
            return "App1";
        }
    }
    

    另外,我们需要实现一个MainApplication并添加如下代码:

    public class MainApplication extends Application implements ReactApplication {
    
      private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
        @Override
        public boolean getUseDeveloperSupport() {
          return BuildConfig.DEBUG;
        }
    
        @Override
        protected List<ReactPackage> getPackages() {
          return Arrays.<ReactPackage>asList(
              new MainReactPackage()
          );
        }
    
        @Override
        protected String getJSMainModuleName() {
          return "index";
        }
      };
    
      @Override
      public ReactNativeHost getReactNativeHost() {
        return mReactNativeHost;
      }
    
      @Override
      public void onCreate() {
        super.onCreate();
        SoLoader.init(this, /* native exopackage */ false);
      }
    }
    

    上述代码的主要作用是为ReactActivity提供ReactNativeHost,查看源码你会发现在ReactActivity中使用了ReactActivityDelegate,在ReactActivityDelegate中会用到MainApplication中提供的ReactNativeHost

     protected ReactNativeHost getReactNativeHost() {
        return ((ReactApplication) getPlainActivity().getApplication()).getReactNativeHost();
    }
    

    另外实现了MainApplication之后需要在AndroidManifest.xml中添加MainApplication

     <application
            android:name=".MainApplication"
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
            ...
    

    以上就是通过继承ReactActivity的方式来作为RN容器的。

    那么这两种方式各有什么特点:

    • 通过ReactInstanceManager的方式:灵活,可定制性强;
    • 通过继承ReactActivity的方式:简单,可定制性差;

    此过程更细致的讲解可查阅:React Native与Android 混合开发讲解的视频教程

    5. 运行React Native

    经过上述的步骤,我们已经完成了对一个现有Android项目RNHybridAndroid添加了RN,并且通过两种方式分别创建了一个RNPageActivityReactPageActivity的Activity来加载我们在JS中注册的名为App1的RN 组件。

    接下来我们来启动RN服务器,运行RNHybridAndroid项目打开RNPageActivityReactPageActivity来查看效果:

    npm start
    

    RNHybrid的根目录运行上述命令,来启动一个RN本地服务:

    npm-start

    然后我们打开AndroidStudio,点击运行按钮或者通过快捷键Ctrl+R来将RNHybridAndroid安装到模拟器上:

    this-is-app-android

    6. 添加更多React Native的组件

    我们可以根据需要添加更多的React Native的组件:

    import { AppRegistry } from 'react-native';
    import App from './App';
    import App2 from './App2';
    
    AppRegistry.registerComponent('App1', () => App);
    AppRegistry.registerComponent('App2', () => App);
    

    然后,在Native中根据需要加载指定名字的RN组件即可。

    7. 调试、打包、发布应用

    调试

    调试这种混合的RN应用和调试一个纯RN应用时一样的,都是通过上文中说讲到的RN 开发者菜单,另外搭建也可以通过学习React Native技术精讲与高质量上线APP开发课程来掌握更多RN调试的技巧。

    打包

    虽让,通过上述步骤,我们将RN和我们的RNHybridAndroid项目做了融合,但打包RNHybridAndroid你会发现里面并不包含JS部分的代码,如果要将JS代码打包进Android Apk包中,可以通过如下命令:

    react-native bundle --platform android --dev false --entry-file index.js --bundle-output RNHybridAndroid/app/src/main/assets/index.android.bundle --assets-dest RNHybridAndroid/app/src/main/res/
    

    参数说明

    • --platform android:代表打包导出的平台为Android;
    • --dev false:代表关闭JS的开发者模式;
    • -entry-file index.js:代表js的入口文件为index.js
    • --bundle-output:后面跟的是打包后将JS bundle包导出到的位置;
    • --assets-dest:后面跟的是打包后的一些资源文件导出到的位置;

    提示:JS bundle一定要正确放到你的Android言语的assets目录下这个和我们上文中配置的setBundleAssetName("index.android.bundle")进行对应。

    发布应用

    通过上述步骤我们完成了将RN代码打包并生成JS bundle,并放到了assets目录下,接下来我们就可以来通过Android Studio或者命令的方式来release我们的RN混合Android应用了。

    我在之前发表过React Native发布APP之签名打包APK的博文,
    需要的同学可以去看一下,在这篇文章中就不在重复了。

    更多React Native混合开发的实用技巧,可学习与此文章配套的视频课程:《React Native与Android 混合开发讲解》

    参考

    展开全文
  • 混合开发搭建教程

    2018-02-24 09:13:54
    cordova,混合开发,IOS 和Android 开发的混合,主要包括Cordova的搭建和第一个demo案例很实在的项目
  • 原生开发、H5开发与混合开发的区别

    千次阅读 2019-12-04 16:01:59
    目前市场上主流的APP分为三种:原生APP、Web APP(即HTML5)和混合APP三种,相对应的定制开发就是原生开发、H5开发和混合开发。那么这三种开发模式究竟有何不同呢?下面我们就分别从这三者各自的优劣势来区分比较吧...

    前言

    移动应用开发的方式,目前主要有三种:
    Native App: 本地应用程序(原生App)
    Web App:网页应用程序(移动web)
    Hybrid App:混合应用程序(混合App)

    相对应的定制开发就是原生开发、H5开发和混合开发

    在这里插入图片描述

    三种方式分别的优缺点

    原生开发

    原生开发(Native App开发),是在Android、IOS等移动平台上利用官方提供的开发语言、开发类库、开发工具进行App开发。比如Android是利用Java语言、Eclipse、Android studio等开发工具进行开发;IOS是利用Objective-C语言 和Xcode开发工具进行开发

    优点:
    1、可访问手机所有功能(如GPS、摄像头等)、可实现功能最齐全;
    2、运行速度快、性能高,绝佳的用户体验;
    3、支持大量图形和动画,不卡顿,反应快;
    4、兼容性高,每个代码都经过程序员精心设计,一般不会出现闪退的情况,还能防止病毒和漏洞的出现;
    5、比较快捷地使用设备端提供的接口,处理速度上有优势

    缺点:
    1、开发时间长,快则3个月左右完成,慢则五个月左右;
    2、制作费用高昂,成本较高;
    3、可移植性比较差,一款原生的App,Android和IOS都要各自开发,同样的逻辑、界面要写两套;
    4、内容限制(App Store限制);
    5、获得新版本时需重新下载应用更新

    Web APP (HTML5)开发

    HTML5应用开发,是利用Web技术进行的App开发。Web技术本身需要浏览器的支持才能进行展示和用户交互,因此主要用到的技术是HTML5、Java、CSS等

    优点:
    1、支持设备范围广,可以跨平台,编写的代码可以同时在Android、IOS、Windows上运行;
    2、开发成本低、周期短;
    3、无内容限制;
    4、适合展示有大段文字(如新闻、攻略等),且格式比较丰富(如加粗,字体多样)的页面;
    5、用户可以直接使用最新版本(自动更新,不需用户手动更新)

    缺点:
    1、由于Web技术本身的限制,H5移动应用不能直接访问设备硬件和离线存储,所以在体验和性能上有很大的局限性;
    2、对联网要求高,离线不能做任何操作;
    3、功能有限;
    4、APP反应速度慢,页面切换流畅性较差;
    5、图片和动画支持性不高;
    6、用户体验感较差;
    7、无法调用手机硬件(摄像头、麦克风等)

    混合(原生+H5)开发

    混合开发(Hybrid App开发),是指在开发一款App产品的时候,为了提高效率、节省成本而利用原生与H5的开发技术的混合应用。通俗点来说,这就是网页的模式,通常由“HTML5云网站+APP应用客户端”两部份构成

    混合开发是一种取长补短的开发模式,原生代码部分利用Web View插件或者其它框架为H5提供容器,程序主要的业务实现、界面展示都是利用与H5相关的Web技术进行实现的。比如京东、淘宝、今日头条等APP都是利用混合开发模式而成的

    优点:
    1、开发效率高,节约时间。同一套代码Android和IOS基本上都可使用;
    2、更新和部署比较方便,每次升级版本只需要在服务器端升级即可,不再需要上传到App Store进行审核;
    3、代码维护方便、版本更新快,节省产品成本;
    4、比web版实现功能多;
    5、可离线运行

    缺点:
    1、功能/界面无法自定:所有内容都是固定的,不能换界面或增加功能;
    2、加载缓慢/网络要求高:混合APP数据需要全部从服务器调取,每个页面都需要重新下载,因此打开速度慢,网络占用高,缓冲时间长,容易让用户反感;
    3、安全性比较低:代码都是以前的老代码,不能很好地兼容最新手机系统,且安全性较低,网络发展这么快,病毒这么多,如果不实时更新,定期检查,容易产生漏洞,造成直接经济损失;
    4、既懂原生开发又懂H5开发的高端人才难找

    以上就是原生开发、H5开发和混合开发各自的优缺点。相比之下,由于现代人的个性化需求越来越明显,所以原生APP开发也越来越多,定制化的服务更能满足消费者的需求

    三种方式对比

    在这里插入图片描述

    展开全文
  • 东西不多简单易懂、Swift语言如何使用UITableView、Swift与OC的混合开发、扩展(Extension)的简单使用、协议(protocol)
  • Android Hybrid混合开发

    千次阅读 2020-10-26 11:43:22
    关于混合开发常问道的问题: Android如何嵌套h5页面? h5一般调用哪些Android哪些接口功能? Android如何调用网页(js)功能? 问题1.ndroid如何嵌套h5页面答案: 当我们用vue开发完项目,执行nmp run build打包...

    关于混合开发常问道的问题:

    1. Android如何嵌套h5页面?
    2. h5页面如何调用Android接口?
    3. Android如何调用网页(js)方法?
    4. h5页面 判断 移动端是ios、或者Android

    问题1.android如何嵌套h5页面:

    1. 当我们用vue开发完项目,执行nmp run build打包生产dist目录,如何嵌套在Android框架中

    2. 创建网页存放文件夹,在Android工程res下面添加assets文件夹,把dist目录内容拷贝到assets下。(这里我把index.html改名为hybrid_test.html)

    3. 找到Android项目中.xml布局文件,添加webview组件及设置webview属性

        <WebView
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:id="@+id/wv_test"/>
    
    
    1. 在相应的.java文件中通过id获取webview组件,将Android方法存入一个对象,通过addJavascriptInterface()方法,暴露给html页面。
      //获取webview组件
      wv_test = findViewById(R.id.wv_test);
     // 通过addJavascriptInterface方法 将Android里面提供的方法对象集合JSObject暴露给页面,同时也将页面的提供的js方法注册给Android
     wv_test.addJavascriptInterface(new JSObject(this), JSOBJECT);
     // 加载网页,若非本地页面,则把下面的加载地址换在页面url
     wv_test.loadUrl("file:///android_asset/hybrid_test.html");
    
    

    问题2. h5页面如何调用Android接口或功能?

    1. 在java文件中创建一个供网页端调用的类,如JSObject,里面编写供网页调用的方法.
    2. 一般h5页面常要调用Android摄像头,相册,还有自定义方法。
    3. 在h5页面中,添加调用接口,在网页的javascript代码中使用上面安卓提供的MyJS.add()来调用(MyJS为Android端使用addJavascriptInterface方法时注入的调用本地方法类名称
      )。

    问题3. Android如何调用网页(js)方法?

    1. Android端直接使用webview的loadUrl(“javascript:”+网页方法名)就可以直接调用的
    2. 但是方法一多这样就比较容易乱,因此我们可以创建一个专门管理的。
      创建生成网页方法的类NativeObject。

    问题4. h5页面 判断 移动端是ios、或者Android

    1. 简称ua检测
    $(function(){
    var u = navigator.userAgent, app = navigator.appVersion; 
    var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Linux') > -1; //android终端或者uc浏览器 
    var isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端 
    alert('是否是Android:'+isAndroid); 
    alert('是否是iOS:'+isiOS);
    if(isAndroid){
    	$ ("#choose").attr('capture','camera');
    	}
    });
    

    本例demo下载地址:HybridDemo下载

    简介:
    混合开发(Hybrid)也有一段时间了,现在闲下来总结一下。
    说到混合开发,重要功能有2种,一是网页端调用安卓原生接口或功能,二是安卓原生调用网页功能。

    效果图:
    在这里插入图片描述

    Hybrid开发流程:
    1、Android端编写方法api,暴露给h5页面调用
    创建一个供网页端调用的类,如JSObject,里面编写供网页调用的方法,记得在方法上面添加@JavascriptInterface注释,否则在有些SDK版本上使用addJavascriptInterface方法(下面会用到)绑定JS对象时会报"they will not be visible in API 17"错误。

    package mhwang.com.hybriddemo;
    
    import android.content.Context;
    import android.webkit.JavascriptInterface;
    import android.widget.Toast;
    
    public class JSObject {
        private Context mContext;
        public JSObject(Context context) {
            mContext = context;
        }
    
        @JavascriptInterface
        public int add(int a, int b){
            return a + b;
        }
    
        @JavascriptInterface
        public void showToast(String msg){
            Toast.makeText(mContext, msg, Toast.LENGTH_SHORT).show();
        }
    }
    
    

    这里提供了2个方法给网页端调用,分别为add()方法和showToast()方法。

    2、网页端添加Android端调用接口
    创建html网页hybrid_test.html,并添加调用接口,在网页的javascript代码中使用上面安卓提供的MyJS.add()来调用。MyJS可以看成是JSObject类在网页中的别名,下面会使用webviewaddJavascriptInterface()方法将它们关联起来。

    <!DOCTYPE html>
    <html>
    <head>
       <meta charset="UTF-8">          <!--添加编码格式,否则安卓端调用时传递中文参数会可能乱码-->
       <title>Hybrid开发测试</title>
    </head>
    <body>
       <h1>网页端</h1>
       <br />
       <button id="btn_callNativeAdd" onclick="onAddClick(this)">调用本地加法运算并显示</button>
       <br />
       <div id="div_showTextFromNative"></div>
    
       <!--javascript代码-->
       <script type="text/javascript">
          // 调用android端提供的参数
          // MyJS为Android端使用addJavascriptInterface方法时注入的调用本地方法类名称
          function onAddClick(e){
             var result = MyJS.add(3, 5);
             MyJS.showToast('3 + 5 = '+result);
          };
          
    
          // 提供android端调用的造句方法
          function makeSentence(word1, word2){
             var div_showTextFromNative = document.getElementById("div_showTextFromNative");
             div_showTextFromNative.innerHTML = '你'+word1 + ',他'+word2;
          };
    
          // 提供android端相加的方法
          function add(a, b){
             var div_showTextFromNative = document.getElementById("div_showTextFromNative");
             var result = a + b;
             div_showTextFromNative.innerHTML = 'a + b = ' + result;
          }
       </script>
    </body>
    </html>
    
    

    3、Android端封装一个生成网页端方法url的类
    正常来说Android端直接使用webview的loadUrl(“javascript:”+网页方法名)就可以直接调用的,但是方法一多这样就比较容易乱,因此创建一个专门管理的类好点。
    创建生成网页方法的类NativeObject。

    package mhwang.com.hybriddemo;
    
    /** 用于封装拼接调用js方法的语句
    */
    public class NativeObject {
    
        /** 为了方便获取String 类型的字符串
         * @param s 加‘’号的参数
         * @return 加了‘’号的参数
         */
        private static String getJsStringParam(String s){
            return "'"+s+"'";
        }
    
        
        public static String makeSentence(String world1, String world2){
            return "javascript:makeSentence("+getJsStringParam(world1)+","+getJsStringParam(world2)+")";   // 这里要注意的是,若是传递的参数是字符串,那么在拼接调用的url的时候需要对参数加上‘’号。
        }
    
        public static String add(int a, int b){
            // 不是字符串的话不用加‘’号
            return "javascript:add("+a+","+b+")";
        }
    }
    
    

    这里生成的2个方法是跟上面网页javascript代码提供的2个方法对应的。然后在需要调用的地方使用就可以,如:

    wv_test.loadUrl(NativeObject.add(5, 10));
    
    

    如果系统版本大于4.4,可以使用evalute.Javascript()方法,该方法的好处是可以回调javascript的返回结果。并且这个方法比 loadUrl 方法更加方便简洁,比 loadUrl 效率更高,因为 loadUrl 的执行会造成页面刷新一次,这个方法不会,下面是这个方法的使用示例:

    final int version = Build.VERSION.SDK_INT;
    if (version < 18) {
    	wv_tests.loadUrl(jsStr);
    } else {
    	wv_test.evaluateJavascript(jsStr, new ValueCallback<String>() {
    @Override
    public void onReceiveValue(String value) {
    	//此处为 js 返回的结果
    	}
    });
    }
    

    4、创建网页存放文件夹(不使用本地网页的可以跳过)
    在Android工程res下面添加assets文件夹,用于存放本地网页文件hybrid_test.html。
    在这里插入图片描述
    5、添加webview组件及设置webview属性
    .xml布局文件

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context=".MainActivity">
    
        <WebView
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:id="@+id/wv_test"/>
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:orientation="vertical"
            android:background="@color/colorPrimary"
            android:layout_weight="1">
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Android端"
                android:textSize="30dp"/>
            <Button
                android:layout_gravity="center"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/btn_makeSentence"
                android:text="造句"/>
    
            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/btn_webAdd"
                android:layout_gravity="center"
                android:text="做加法"/>
        </LinearLayout>
    
    </LinearLayout>
    
    

    相应的.java文件

    public class MainActivity extends Activity {
        WebView wv_test;
        Button btn_makeSentence;
        Button btn_webAdd;
    
        private static final String JSOBJECT = "MyJS";
        @SuppressLint("SetJavaScriptEnabled")
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            wv_test = findViewById(R.id.wv_test);
            btn_makeSentence = findViewById(R.id.btn_makeSentence);
            btn_webAdd = findViewById(R.id.btn_webAdd);
    
            btn_makeSentence.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    wv_test.loadUrl(NativeObject.makeSentence("潇洒", "放荡"));
                }
            });
    
            btn_webAdd.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    wv_test.loadUrl(NativeObject.add(5, 10));
                }
            });
    
            // 设置webview属性
            WebSettings settings = wv_test.getSettings();
            settings.setJavaScriptEnabled(true);                                                            // 设置是否能使用javascript
            settings.setJavaScriptCanOpenWindowsAutomatically(true);
            wv_test.setWebChromeClient(new WebChromeClient());                           // 设置默认浏览器,否则不能弹窗
            // 这里需要注意,JSObject里面提供的方法需要添加@JavascriptInterface注释,
            // 否则会报"they will not be visible in API 17"错误
            wv_test.addJavascriptInterface(new JSObject(this), JSOBJECT);
            // 加载网页,若非本地页面,则把下面的加载地址换在页面url
            wv_test.loadUrl("file:///android_asset/hybrid_test.html");
        }
    }
    
    
    

    下面是一些webview常用设置项及说明(摘抄):

    WebSettings webSettings = webView.getSettings();
    //设置了这个属性后我们才能在 WebView 里与我们的 Js 代码进行交互,对于 WebApp 是非常重要的,默认是 false,
    //因此我们需要设置为 true,这个本身会有漏洞,具体的下面我会讲到
    webSettings.setJavaScriptEnabled(true);
    //设置 JS 是否可以打开 WebView 新窗口
    webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
    //WebView 是否支持多窗口,如果设置为 true,需要重写
    //WebChromeClient#onCreateWindow(WebView, boolean, boolean, Message) 函数,默认为 false
    webSettings.setSupportMultipleWindows(true);
    //这个属性用来设置 WebView 是否能够加载图片资源,需要注意的是,这个方法会控制所有图片,包括那些使用 data URI 协议嵌入
    //的图片。使用 setBlockNetworkImage(boolean) 方法来控制仅仅加载使用网络 URI 协议的图片。需要提到的一点是如果这
    //个设置从 false 变为 true 之后,所有被内容引用的正在显示的 WebView 图片资源都会自动加载,该标识默认值为 true。
    webSettings.setLoadsImagesAutomatically(false);
    //标识是否加载网络上的图片(使用 http 或者 https 域名的资源),需要注意的是如果 getLoadsImagesAutomatically()
    //不返回 true,这个标识将没有作用。这个标识和上面的标识会互相影响。
    webSettings.setBlockNetworkImage(true);
    //显示WebView提供的缩放控件
    webSettings.setDisplayZoomControls(true);
    webSettings.setBuiltInZoomControls(true);
    //设置是否启动 WebView API,默认值为 false
    webSettings.setDatabaseEnabled(true);
    //打开 WebView 的 storage 功能,这样 JS 的 localStorage,sessionStorage 对象才可以使用
    webSettings.setDomStorageEnabled(true);
    //打开 WebView 的 LBS 功能,这样 JS 的 geolocation 对象才可以使用
    webSettings.setGeolocationEnabled(true);
    webSettings.setGeolocationDatabasePath("");
    //设置是否打开 WebView 表单数据的保存功能
    webSettings.setSaveFormData(true);
    //设置 WebView 的默认 userAgent 字符串
    webSettings.setUserAgentString("");
    //设置是否 WebView 支持 “viewport” 的 HTML meta tag,这个标识是用来屏幕自适应的,当这个标识设置为 false 时,
    //页面布局的宽度被一直设置为 CSS 中控制的 WebView 的宽度;如果设置为 true 并且页面含有 viewport meta tag,那么
    //被这个 tag 声明的宽度将会被使用,如果页面没有这个 tag 或者没有提供一个宽度,那么一个宽型 viewport 将会被使用。
    webSettings.setUseWideViewPort(false);
    //设置 WebView 的字体,可以通过这个函数,改变 WebView 的字体,默认字体为 "sans-serif"
    webSettings.setStandardFontFamily("");
    //设置 WebView 字体的大小,默认大小为 16
    webSettings.setDefaultFontSize(20);
    //设置 WebView 支持的最小字体大小,默认为 8
    webSettings.setMinimumFontSize(12);
    //设置页面是否支持缩放
    webSettings.setSupportZoom(true);
    
    
    展开全文
  • 基于iOS系统的混合开发模式移动车险App.pdf
  • H5与原生体验的融合-蘑菇街混合开发平台的优化实践-王兴楠 混合开发平台介绍(Hybrid Development Platform) • HDP的优化实践: • 基于独立内核的体验优化,秒杀WebView • 动态跨平台框架的研发与应用,让H5的体验...
  • 混合开发几种IDE的技术介绍
  • Flutter混合开发详解

    2020-08-25 03:33:47
    主要介绍了Flutter混合开发详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 283,332
精华内容 113,332
关键字:

混合开发