Android React Native植入原生應用小記
一、React Native教程介紹
二、植入流程:
0、準備工作及一些提示性:
本人系統為Win10系統,安裝了visual studio2015,node.js4.1版本,curl,ssl,python2.7,Android Studio2.1版本及buildTools。
本人從github上down下來react-native,不過因本機之前曾經裝過react-native-cli,所以報錯。
本人本來打算卸掉react-native-cli重新編譯react-native以作為全域性性的react-native,但未獲成功(可能中間哪步錯了)。
注意:一個相容性錯誤(react-native0.17.+和v7:23.2.+相沖突)
E/AndroidRuntime( 1530): Process: com.example.zhejiang.testapplication, PID: 1530
E/AndroidRuntime( 1530): java.lang.RuntimeException: An error occured while executing doInBackground()
E/AndroidRuntime( 1530): at android.os.AsyncTask$3.done(AsyncTask.java:300)
E/AndroidRuntime( 1530): at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
E/AndroidRuntime( 1530): at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
E/AndroidRuntime( 1530): at java.util.concurrent.FutureTask.run(FutureTask.java:242)
E/AndroidRuntime( 1530): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
E/AndroidRuntime( 1530): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
E/AndroidRuntime( 1530): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
E/AndroidRuntime( 1530): at java.lang.Thread.run(Thread.java:864)
E/AndroidRuntime( 1530): Caused by: java.lang.IllegalAccessError: tried to access method android.support.v4.net.ConnectivityManagerCompat.<init>:(Lcom/facebook/react/bridge/ReactApplicationContext;)V from class com.facebook.react.modules.netinfo.NetInfoModule
E/AndroidRuntime( 1530): at com.facebook.react.modules.netinfo.NetInfoModule.<init>(NetInfoModule.java:57)
E/AndroidRuntime( 1530): at com.facebook.react.shell.MainReactPackage.createNativeModules(MainReactPackage.java:55)
E/AndroidRuntime( 1530): at com.facebook.react.ReactInstanceManagerImpl.processPackage(ReactInstanceManagerImpl.java:692)
E/AndroidRuntime( 1530): at com.facebook.react.ReactInstanceManagerImpl.createReactContext(ReactInstanceManagerImpl.java:633)
E/AndroidRuntime( 1530): at com.facebook.react.ReactInstanceManagerImpl.access$600(ReactInstanceManagerImpl.java:78)
E/AndroidRuntime( 1530): at com.facebook.react.ReactInstanceManagerImpl$ReactContextInitAsyncTask.doInBackground(ReactInstanceManagerImpl.java:169)
E/AndroidRuntime( 1530): at com.facebook.react.ReactInstanceManagerImpl$ReactContextInitAsyncTask.doInBackground(ReactInstanceManagerImpl.java:155)
E/AndroidRuntime( 1530): at android.os.AsyncTask$2.call(AsyncTask.java:288)
E/AndroidRuntime( 1530): at java.util.concurrent.FutureTask.run(FutureTask.java:237)
E/AndroidRuntime( 1530): ... 4 more
解決方法:將support包版本改為
compile 'com.android.support:appcompat-v7:23.1.+'
1、在build.gradle中加入:
compile 'com.facebook.react:react-native:0.20.+'
2、修改minSdkVersion:
defaultConfig { ... minSdkVersion 16 ... }3、增加網路許可權:
<uses-permission android:name="android.permission.INTERNET" />
4、新增原生程式碼:
package5、把JS程式碼新增到原生應用:com.zhejiangdaily; import android.app.Activity; import android.os.Bundle; import android.view.KeyEvent; import com.facebook.react.LifecycleState; import com.facebook.react.ReactInstanceManager; import com.facebook.react.ReactRootView; import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler; import com.facebook.react.shell.MainReactPackage; /** * Created by zhejiang on 2016/3/24 0024. */ public class FirstReactActivity 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") .setJSMainModuleName("index.android") .addPackage(new MainReactPackage()) .setUseDeveloperSupport(BuildConfig.DEBUG) .setInitialLifecycleState(LifecycleState.RESUMED) .build(); mReactRootView.startReactApplication(mReactInstanceManager, "MyAwesomeApp", null); setContentView(mReactRootView); } @Override public void invokeDefaultOnBackPressed() { super.onBackPressed(); } @Override protected void onPause() { super.onPause(); if (mReactInstanceManager != null) { mReactInstanceManager.onPause(); } } @Override protected void onResume() { super.onResume(); if (mReactInstanceManager != null) { mReactInstanceManager.onResume(this, this); } } @Override public void onBackPressed() { if (mReactInstanceManager != null) { mReactInstanceManager.onBackPressed(); } else { super.onBackPressed(); } } @Override public boolean onKeyUp(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_MENU && mReactInstanceManager != null) { mReactInstanceManager.showDevOptionsDialog(); return true; } return super.onKeyUp(keyCode, event); } }
在工程根目錄,執行以下三個命令:
npm init
npm install --save react-native
curl -o .flowconfig https://raw.githubusercontent.com/facebook/react-native/master/.flowconfig
上面的程式碼會建立一個node模組,然後react-native
作為npm依賴新增。現在開啟新建立的package.json
檔案然後在scripts
欄位下新增如下內容:
"start": "node node_modules/react-native/local-cli/cli.js start"
複製並貼上下面的這段程式碼到你工程根目錄下的index.android.js
——這是一個簡單的React Native應用:
'use strict';
var React = require('react-native');
var {
Text,
View
} = React;
class MyAwesomeApp extends React.Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.hello}>Hello, World</Text>
</View>
)
}
}
var styles = React.StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
},
hello: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
});
React.AppRegistry.registerComponent('MyAwesomeApp', () => MyAwesomeApp);
6、開啟伺服器,編譯包:
react-native start
gradlew.bat installDebug/assembleDebug
三、遇到的問題:
1、undefined is not an object (evaluating 'screenPhysicalPixels.width')
問題:所引用的react native版本過低,出錯時所引用版本是0.17+解決方法:
dependencies {
compile "com.facebook.react:react-native:0.20.+"
}
方法二:(沒試過)
- Set
"react-native": "^0.20.0",
inpackage.json
- Delete
node_modules
- Run
react-native upgrade
(updatesandroid/app/build.gradle
among others) - Uninstall app on my phone
react-native run-android
2、ReferenceError:Can't find variable:_fbBatchedBridge(line 1 in the generated
問題分析:Android手機和電腦伺服器不在同一個網路下面
解決方法:
(Android 5.0及以上)使用adb reverse命令
首先把你的裝置通過USB資料線連線到電腦上,並開啟USB除錯(關於如何開啟USB除錯,參見上面的章節)。
- 執行
adb reverse tcp:8081 tcp:8081
- 不需要更多配置,你就可以使用
Reload JS
和其它的開發選項了。
(Android 5.0以下)通過Wi-Fi連線你的本地開發伺服器
- 首先確保你的電腦和手機裝置在同一個Wi-Fi環境下。
- 在裝置上執行你的React Native應用。和開啟其它App一樣操作。
- 你應該會看到一個“紅屏”錯誤提示。這是正常的,下面的步驟會解決這個報錯。
- 搖晃裝置,或者執行
adb shell input keyevent 82
,可以開啟開發者選單。 - 點選進入
Dev Settings
。 - 點選
Debug server host for device
。 - 輸入你電腦的IP地址和埠號(譬如10.0.1.1:8081)。在Mac上,你可以在系統設定/網路裡找查詢你的IP地址。在Windows上,開啟命令提示符並輸入
ipconfig
來查詢你的IP地址。在Linux上你可以在終端中輸入ifconfig
來查詢你的IP地址。 - 回到開發者選單然後選擇
Reload JS
。
3、Unable to download JS bundle
問題分析:js名字(包括在package.json中)和React Native預設不一致。我當時的情況是js模板命名為index.js,在package.json中也是如此。但是執行時伺服器提示
request:/index.android.bundle?platform=android&dev=true&hot=false
解決方法:將index.js改名為index.android.js,並且在package.json中也改名。重新執行gradlew.bat assembleDebug打包,並且重啟伺服器,執行react-native start
4、gradle編譯 java.lang.OutOfMemoryError: GC overhead limit exceeded
問題分析:JVM7所設定的預設快取大小太小導致編譯失敗。需要設定虛擬機器堆記憶體空間大小,避免在編譯期間OOM
解決方法:
在build.gradle中新增:
android {
... dexOptions { incremental true javaMaxHeapSize "4g" } ... }
修改gradle.properties:(增加兩處,當前主module下和node_modules下,搜一下全域性的-Xmx)
org.gradle.jvmargs=-Xmx3096m -XX:MaxPermSize=1024m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
問題分析:Android方法數65K限制,需要DEX分包
解決方法:(在build.gradle中修改)
dependencies { ... compile 'com.android.support:multidex:' ... }
defaultConfig { ... multiDexEnabled true ... }
android:name="android.support.multidex.MultiDexApplication"
最後,重新build。
6、com.android.build.api.transform.TransformException: com.android.builder.packaging.DuplicateFileException: Duplicate files copied in APK lib/armeabi/libwebp.so
問題分析:so檔案重複了(ImageLoader增加的WebP和Fresco本身所帶有的WebP所衝突)
解決方法:刪除衝突檔案
寫在最後的話:
轉載請轉自:
如有問題,請聯絡QQ838704711
相關推薦
Android React Native植入原生應用小記
一、React Native教程介紹 二、植入流程: 0、準備工作及一些提示性: 本人系統為Win10系統,安裝了visual studio2015,node.js4.1版本,curl,ssl,python2.7,Android Studio2.1版本及buildToo
React Native嵌入原生應用的坑
今天試著在原生應用中引入React Native,本以為按照官網的步驟來做就沒問題,結果著實踩了很多坑。現記錄下來,防止以後踩同樣的坑 一、React Native專案在64位android手機上執行,會提示 "/data/data/com.xxx.xxx/lib-main/libgnustl_shared.
Android React Native使用原生模組
有時候我們的App需要訪問平臺API,並且React Native可能還沒有相應的模組包裝;或者你需要複用一些Java程式碼,而不是用Javascript重新實現一遍;又或者你需要實現某些高效能的、多執行緒的程式碼,譬如圖片處理、資料庫、或者各種高階擴充套
React-Native 與原生的3種互動通訊(Android)
前言 最近到新公司,採用React-Native開發App。在某些效能方面有問題或者模組特殊的開發情況,不可避免的需要我們原生開發(Android\IOS)給予前端開發支援。 在為前端書寫模組部分,不可避免的要接觸核心的通訊部分。 大致分為2種情況:
基於React Native封裝的表單提交Container,用於替代RN官方元件KeyboardAvoidingView(不相容Android)react-native-keyboardavoidv
react-native-keyboardavoidview 基於React Native封裝的表單提交Container,用於替代RN官方元件KeyboardAvoidingView(不相容Android) Theory 重寫TextInput的onFocus方法,藉助Sc
[Android] React Native技術精講與高質量上線APP開發 多棧技術
【多棧技術更有競爭力】本課程將手把手帶你用RN技術開發、優化、直到最後釋出上線一款完整的跨平臺APP;讓你擁有一次真正參與上線專案開發的歷程,同時全面掌握React Native技術,使你的技術能力和專案經驗都得到前所未有的提升! https://pan.baidu.com/s/1p4c
動手建立一個自己的「React native」原生模組
前言 我們在使用RN的時候,會發現RN提供了很多Module供JS呼叫,這些Module能夠滿足我們一些基礎的應用場景,但是在實際的專案中,必定會有一些互動邏輯需要我們自己去實現,這時候就需要我們自定義一些Module供JS呼叫,那麼怎麼才能讓JS呼叫到我們自定義的Module呢? 下面我們就一步步的去實現
react native接入原生專案(mac pro)
首先保證安裝了node,watchman,yarn。 1.新建一個資料夾A,裡面新建一個資料夾android,然後把專案根目錄下所有內容放入這個android裡。直接全選複製的話沒有git,可以把整個專案移過去再改名為android。 2.在A下新建package.json: {
React Native iOS原生模組開發實戰|教程|心得|如何建立React Native iOS原生模組
尊重版權,未經授權不得轉載 本文出自:賈鵬輝的技術部落格(http://blog.csdn.net/fengyuzhengfan/article/details/54691432) 告訴大家一個好訊息,為大家精心準備的React Native視訊教程釋出了,大家
React Native和原生iOS Objective-C的互動解決方案
用一個RCTRootView作為iOS裡一個Controller的view。在RN層的左上角返回按鈕點選後pop回iOS層。發現無法執行,除錯發現controller的navigationCont的值是空的。發現與RN互動的這個self地址和iOS層的self並不是同一個
React Native封裝原生元件釋出到npm
因為一個任務,要寫原生的獲取使用者手機資料夾,實現使用者自定義資料夾的功能,寫好了之後嘗試封裝成元件。1. 首先,有一個rn專案,用Adnroid Studio開啟 android -> app -> build.gradle如圖新建一個 Android Modu
React Native 與 原生互動
React Native 與原生互動一般有三種方式,分別是Callback,Promise,RCTDeviceEventEmitter import { AppRegistry, StyleSheet, Text, View, NativeModule
React Native在直播應用中的實踐
React Native是近年來最值得花時間學習的移動開發新技術,其在不斷進化、成熟的同時,效能也在持續提升。卜赫主要分享了React Native Pili在開發過程中的設計斟酌和踩過的坑。以下是正文: React Native是什麼 React Native的i
React Native 與原生之間的通訊(iOS)
本文將講述下在原生和React Native之間的通訊方式。方式和邏輯綜合了自己的思維方式,主要參考了React Native中文官方文件,因為感覺它講的方式有些不妥,所以就按自己思路組織了下文。 雖然發覺一遍文章要把所有通訊方式講清楚不太科學,不過把思路講講倒是可以,
React Native和原生app通訊機制詳解
概述 React Native用iOS自帶的JavaScriptCore作為JS的解析引擎,但並沒有用到JavaScriptCore提供的一些可以讓JS與OC互調的特性,而是自己實現了一套機制,這套機制可以通用於所有JS引擎上,在沒有JavaScriptCor
react-native 呼叫原生方法
第一步,新建MyReactPackage.java: package com.goodthingshappeneverday; import com.facebook.react.ReactPackage; import com.facebook.react.bridge
react native之原生和RN的互動
前言:前端時間隨著自己的學習和研究,也寫了幾篇關於react native的文章,雖然都是比較簡的,但是都是根據自己的效果來做的流程,所以還是比較實用的,可以避免很多的坑。這篇react native
react-native封裝原生下拉重新整理元件
之前改進過一個react-native-pull元件解決了iOS上重新整理頭部出現空白問題,並且將listview改成了flatlist。 github如下: react-native-pullvi
react-native 呼叫原生模組詳解
一,繼承 ReactContextBaseJavaModule 實現如下方法 自定義方法用 @ReactMethod註釋 /** * 日誌列印module * Created by ybj on 2016/2/26.
React Native 使用原生 UI 元件
在之前的一篇文章中,我記錄了已有的Android專案如何接入React Native,介紹了RN如何呼叫原生的方法,本篇文章上在之前的一篇的文章的基礎上續寫的,這一篇文章中我將記錄Android如何封裝原生元件,然後RN來使用它。如果對接入RN還不太瞭解的,可以看看我的另一篇文章 Android原生專案接