iOS和Android原生工程集成React Native

声明:作者声明此文章为原创,未经作者同意,请勿转载,若转载,务必注明本站出处,本平台保留追究侵权法律责任的权利。
全栈老韩
全栈工程师,擅长iOS App开发、前端(vue、react、nuxt、小程序&Taro)开发、Flutter、React Native、后端(midwayjs、golang、express、koa)开发、docker容器、seo优化等。

我早年记录的笔记,仅供参考哈。

一、iOS原生集成react-native

  1. mkdir ssa_manage_app
  2. cd ssa_manage_app
  3. mkdir ios
  4. cd ios
  5. 将iOS原生工程拖入iOS文件夹目录
  6. cd ..
  7. touch package.json 或者 npm init
  8. vim package.json,输入
    http://reactnative.cn/docs/0.42/integration-with-existing-apps.html#content
    的package.json的内容,要求:
    react-native : 0.42.0
    react : 15.4.1
  9. cd ios, 修改cocoapods的podfile,引入react和yoga,参照
    http://reactnative.cn/docs/0.42/integration-with-existing-apps.html#content
    的podfile的内容,保存,并 pod update
  10. cd ..  , 执行 npm install
    (如果没有安装react, npm install –g react@15.4.1,
    如果没有安装react-native, npm install –g react-native@0.42.0)
  11. react-native run-ios,如无异常,运行成功。

异常问题:

  1. jschelpers/JavaScriptCore.h file not found

解决方法:(链接:https://github.com/facebook/react-native/issues/13010)
Just in case this help anyone, my version of cocoapods was 1.1.1 and not 1.2.0, I had to uninstall cocoapods and reinstall it again:

sudo gem uninstall cocoapods
sudo gem install cocoapods
pod install
build and enjoy

二、Android原生集成react-native

  1. cd ssa_manage_app;
  2. mkdir android
  3. 拷贝原生安卓代码(根目录下所有代码)到android目录下面
  4. 参照
    (http://reactnative.cn/docs/0.42/integration-with-existing-apps.html#content)
    修改,在android/build.gradle中,加入
maven {
            // All of React Native (JS, Android binaries) is installed from npm
            url "$rootDir/../node_modules/react-native/android"
        }

在android/app/build.gradle中,加入依赖
compile "com.facebook.react:react-native:0.42.0" // From node_modules.
 
在AndroidManifest.xml中加入网络访问权限和dev配置
 
5. 修改android/app/build.gradle中的applicationId为”com.ymq.badminton”;
6. 使node.js脚本的启动和安装从原生工程的实际路径执行
修改node_modules/react-natvie/local_cli/ runAndroid/ runAndroid.js,
在function buildAndRun(args)中,加入applicationId变量获取,

onst applicationId = fs.readFileSync(
       'app/build.gradle',
       'utf8'
    ).match(/applicationId "(.+?)"/)[1];

然后修改runOnSpecificDevice(args, cmd, packageName, adbPath);
为runOnSpecificDevice(args, cmd, applicationId, adbPath);

修改runOnAllDevices(args, cmd, packageName, adbPath);
为runOnAllDevices(args, cmd, applicationId, adbPath);

function tryLaunchAppOnDevice(device, packageName, adbPath, mainActivity)
方法中,修改const adbArgs = ['-s', device, 'shell', 'am', 'start', '-n', packageName + '/. ' + mainActivity];
const adbArgs = ['-s', device, 'shell', 'am', 'start', '-n', packageName + '/.activity.' + mainActivity];

在function runOnAllDevices(args, cmd, packageName, adbPath)
方法中,修改
const fallbackAdbArgs = [           'shell', 'am', 'start', '-n', packageName + '/.MainActivity'         ];

const fallbackAdbArgs = [           'shell', 'am', 'start', '-n', packageName + '/.activity.MainActivity'         ];

  1. cd ssa_manage_app
  2. react-native run-android

异常问题:

  1. 检查android sdk的环境变量配置
    echo $ANDROID_HOME
    查看输出的对应路径下是否含有sdk

查看设备的连接情况
adb devices

Scanning 432 folders for symlinks in /Users/hanweixing/Desktop/ssa_manage_app_1/node_modules (5ms) Starting JS server... Building and installing the app on the device (cd android && ./gradlew installDebug)... Could not install the app on the device, read the error above for details. Make sure you have an Android emulator running or a device connected and have set up your Android development environment:

https://facebook.github.io/react-native/docs/android-setup.html
解决办法:(链接:https://github.com/facebook/react-native/issues/8868

you might check the permissions on android/gradlew
they should be 755 not 644
run chmod 755 android/gradlew inside your app root folder
then run react-native run-android
and it should work again.

在 android/app/ 目录下面执行 chmod 755 gradlew

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:transformClassesWithJarMergingForDebug'.
> com.android.build.api.transform.TransformException: java.util.zip.ZipException: duplicate entry: okhttp3/internal/ws/RealWebSocket$1.class
 
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
 
BUILD FAILED
 
Total time: 9.079 secs
Could not install the app on the device, read the error above for details.
Make sure you have an Android emulator running or a device connected and have
set up your Android development environment:

https://facebook.github.io/react-native/docs/android-setup.html
解决方案:
(https://github.com/facebook/react-native/issues/12646、
https://github.com/square/okhttp/issues/3040#issuecomment-271364687)

在android/app/build.gradle中,加入

configurations.all {     // OkHttp 3.5.0+ includes the websockets API, so we need this to prevent a conflict     exclude module: 'okhttp-ws' }

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:installDebug'.
> com.android.builder.testing.api.DeviceException: com.android.ddmlib.InstallException: Failed to finalize session : INSTALL_FAILED_CONFLICTING_PROVIDER: Package couldn't be installed in /data/app/com.ymq.min-1: Can't install because provider name com.ymq.min.AUTH_XGPUSH (in package com.ymq.min) is already used by com.ymq.badminton
 
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
 
BUILD FAILED
 
Total time: 1 mins 23.928 secs
Could not install the app on the device, read the error above for details.
Make sure you have an Android emulator running or a device connected and have
set up your Android development environment:
https://facebook.github.io/react-native/docs/android-setup.html

解决方法:
在app/build.gradle中,修改applicationId为com.ymq.badminton

BUILD SUCCESSFUL

Total time: 1 mins 9.594 secs
Running /Users/hanweixing/Library/android-sdk-macosx/platform-tools/adb -s emulator-5554 reverse tcp:8081 tcp:8081
Starting the app on emulator-5554 (/Users/hanweixing/Library/android-sdk-macosx/platform-tools/adb -s emulator-5554 shell am start -n com.ymq.min/.MainActivity)...
Starting: Intent { cmp=com.ymq.min/.MainActivity }
Error type 3
Error: Activity class {com.ymq.min/com.ymq.min.MainActivity} does not exist.

解决方法:
修改run-android.js,指定从applicationId来读取mainActivity
 (参考链接:https://github.com/facebook/react-native/issues/5546)

注意:
安卓中如果集成了react native界面,需要的配置还要有:
1.

<activity
android:name="com.ymq.badminton.activity.MainActivity"
             android:label="@string/app_name"
-            android:screenOrientation="portrait" />
+            android:screenOrientation="portrait" 
+            android:exported="true" />
  1. android/app/build.gradle
apply plugin: 'com.android.application'
apply plugin: 'android-apt'
+ apply from: "../../node_modules/react-native/react.gradle"
+ def enableSeparateBuildPerCPUArchitecture = false
+ def enableProguardInReleaseBuilds = false
android {
    signingConfigs {
        config_release {

 
         signingConfig signingConfigs.config_release
         multiDexEnabled true
-
+	ndk {
+            abiFilters "armeabi-v7a", "x86"
+        }
+	
+	packagingOptions {
+            exclude "lib/arm64-v8a/librealm-jni.so"
+        }
     }
+	
+    splits {
+         abi {//多平台支持
+             reset()
+             enable enableSeparateBuildPerCPUArchitecture
+             universalApk false  // If true, also generate a universal APK
+             include "armeabi-v7a", "x86"
+         }
+     }   
+    
     dexOptions {
         jumboMode true
     }

 
 dependencies {
 
-    compile "com.facebook.react:react-native:0.42.0" // From node_modules.
+    compile "com.facebook.react:react-native:+" // From node_modules.
 
-    compile fileTree(include: ['*.jar'], dir: 'libs')
+    compile fileTree(dir: "libs", include: ["*.jar"])
     //testCompile 'junit:junit:4.12'
 
     // custom alert
  1. android/app/gradle.properties
org.gradle.jvmargs=-Xmx2048m -XX\:MaxPermSize\=512m -XX\:+HeapDumpOnOutOfMemoryError -Dfile.encoding\=UTF-8
   org.gradle.daemon=true
   org.gradle.parallel=true
+ android.useDeprecatedNdk=true
   systemProp.http.proxyPort=8080
   versCode=158
   versName=1.2.7
   No newline at end of file
  1. android/app/src/main/AndroidManifest.xml
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
      <uses-permission android:name="android.permission.READ_LOGS" />
+    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
      <uses-permission android:name="android.permission.SYSTEM_OVERLAY_WINDOW" />
      <uses-permission android:name="android.permission.WAKE_LOCK" />
      <uses-permission android:name="android.permission.USE_CREDENTIALS" />
      <uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
  1. android/build.gradle
allprojects {
    repositories {
        mavenCentral()
+		mavenLocal()
        jcenter()
        maven {
            url "https://jitpack.io"
  1. android/app/build.gradle
}
 
 configurations.all {
-    // OkHttp 3.5.0+ includes the websockets API, so we need this to prevent a conflict
-    exclude module: 'okhttp-ws'
+    resolutionStrategy.force 'com.squareup.okhttp3:okhttp:3.4.1'
 }
  1. 其他的具体看工程配置。

暂无评论,快来发表第一条评论吧