1. 程式人生 > >android 架構之整合react native框架js混編APP

android 架構之整合react native框架js混編APP

本篇文章主要總結一下現在APP當中使用的js、webView混編架構和技術。

什麼是 js 混編?

js混編簡單說就是使用JavaScript開發APP程式。


android應用使用的是java,Kotlin 、c/c++ 為主的語言開發,ios使用的object-c 、 swift、c/c++ 為主語言開發,由於市場是基本都是android和ios手機,所以一般公司開發什麼專案android和ios的APP都必須開發。android和ios都提供一個庫webkit瀏覽器引擎的支援,android提供了一個元件webView用於顯示網頁,相當於一個內建瀏覽器,ios也有類似一個元件UIWebView;webView和UIWebView也都支援js bridge的模式,就是js與java或者object-c進行互動,那麼就產生一種開發模式就是hybrid APP開發模式。

hybrid 應用

hybrid APP開發模式由於可以使用HTML5 、css、js進行大量UI開發得到了飛速的發展,到後面這類開發也出現很多優秀的框架例如:cordova(phoneGap) ionic 等,他們基本架構都是使用瀏覽器元件(webView,UIWebView)渲染UI,使用js呼叫原生程式碼執行手機功能。那麼隨後發展中hybrid應用也暴露很多問題。

hybrid 應用缺點

  • UI渲染效能差,例如載入白屏,渲染卡頓
  • 記憶體消耗高,主要是沒有優秀的回收複用機制,例如原生recyclerView
  • 使用者互動差,使用者觸控反應遲鈍等
  • UI渲染失真

那麼為了解決hybrid APP中的雞肋痛點,那麼也產生除了很多記得新js 混編開發框架,例如react native(facebook 公司出品), Xamarin(微軟公司出品,c#陣營,乾的也是跨平臺這檔子事);這種框架已經不再是hybrid模式,應該叫做js native APP 開發模式。

js native 應用(react native ,Xamarin )

js native 應用克服了很hybrid的缺點,他是通過js開發使用自定義封裝UI控制元件進行開發,最終打包成原生應用。

1、優點

  • 原生級別的UI渲染
  • 沒有通過webView來進行橋接,減少記憶體消耗
  • 使用者體驗迅速,觸控流暢
  • 提供原生方法呼叫自定義介面,和自定義UI元件的封裝使用,可以無縫對接你現在應用
  • android和ios端高度UI一致性

其實缺點也是比較明顯,例如:

1、缺點

  • 一定的學習成本,相當於學習新的開發技術
  • 專案避免不了封裝自定義方法和UI控制元件,橋接程式碼多
  • 專案維護成變高了

常用混編框架對比表

專案 cordova(phoneGap) react native Xamarin ionic
是否使用webView互動
是否具備自有UI元件
開源
是否打包成原生
具備定製IDE工具
開發語言 js js c# js
推薦理由 前身phoneGap,歷史悠久 facebook大廠背景,使用react js開發,提供了良好的呼叫原生api和UI元件機制 強烈推薦,超級大廠微軟支援,mono是後臺,匯出平臺不止是android 、iOS, 還有windows桌面程式 具備獨立js UI,建立在cordova之上

總體而言優點還是跨平臺,如果選擇js混編框架還是推薦使用react native。


react native整合進入android應用 ,加入js開發模式

操作步驟:

配置好React Native依賴和專案結構。
建立js檔案,編寫React Native元件的js程式碼。
在應用中新增一個RCTRootView。這個RCTRootView正是用來承載你的React Native元件的容器。
啟動React Native的Packager服務,執行應用。
驗證這部分元件是否正常工作。

開始前我們必須使用react native腳手架搭建出一個可以執行的hello world 專案,本文介紹主要是整合react native框架進入現有應用重點不是環境搭建,所以你可以自行百度react native官網的初始化專案文章。

假設你現在已經有了環境了和一個可以執行hello world 專案了 那麼我們可以開始接入現有應用了。

hello world 專案專案目錄如圖:

在這裡插入圖片描述

複製node_modules目錄和package.json進入你android專案跟目錄如圖:

在這裡插入圖片描述

建立index.android.js 檔案放入android根目錄,寫入程式碼:

'use strict';
import React from 'react';
import {
    AppRegistry,
    StyleSheet,
    Text,
    View,
    TouchableOpacity,
    NativeModules,
    ToastAndroid,
    requireNativeComponent,
    DeviceEventEmitte,
    Alert
} from 'react-native';

class HelloWorld extends React.Component {

    constructor(props) {
        super(props);
    }

    componentWillMount() {
    }


    render() {
        return (
            <View style={styles.container}>
                <Text style={{alignItems:'flex-start', backgroundColor:'red', height:49, textAlign:'right'}}>
                    作者jason 李
                </Text>
            </View>
        )
    }

}

var styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'center',
        flexDirection: 'column',
    },
    hello: {
        fontSize: 20,
        textAlign: 'center',
        margin: 10,
    },
});

AppRegistry.registerComponent('HelloWorlds', () => HelloWorld);

接下是android部分了:

在入口gradle檔案加入程式碼:

allprojects {
    repositories {
        google()
        jcenter()
        maven {
            url "$rootDir/node_modules/react-native/android"  //加入這句
        }
    }
}

在專案gradle檔案中加入依賴:

compile "com.facebook.react:react-native:0.55.3"

建立Application程式:

public class MyApplication 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
    public ReactNativeHost getReactNativeHost() {
        return mReactNativeHost;
    }
}

建立react activity:

public class MyReactActivity extends Activity 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();
        // 注意這裡的MyReactNativeApp必須對應“index.js”中的
        // “AppRegistry.registerComponent()”的第一個引數
        mReactRootView.startReactApplication(mReactInstanceManager, "HelloWorlds", null);

        setContentView(mReactRootView);
    }

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

加入許可權:

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

至此所有的配置結束!!!

執行測試

在目錄開啟cmd:輸入

yarn start

然後用Android studio執行你的專案!!

在這裡插入圖片描述