React Native原理及坑點(diǎn)總結(jié)

一、React Native原理及流程介紹

(一)枉氮、RN前端調(diào)用native整體流程示损;

??js調(diào)native簡(jiǎn)單流程:

js調(diào)native流程.png



??js先根據(jù)moduleName和methodName朗和,查詢本地remoteModuleTable,remoteMethodTable谊娇,得出moduleIndex肺孤,methodIndex索引。再調(diào)用native暴露給js的nativeFlushQueueImmediate方法济欢,執(zhí)行調(diào)用native的邏輯赠堵。

詳細(xì)調(diào)用流程.png


a、native端映射表數(shù)據(jù)結(jié)構(gòu)
native端模塊映射表數(shù)據(jù)結(jié)構(gòu).png

??native在啟動(dòng)時(shí)法褥,將初始化由RCT_EXPORT_MODULE指定的模塊茫叭,并加載RCT_EXPORT_METHOD指定的方法到RCTNativeModule中,上圖中module1半等、module2等都是RCTNativeModule類揍愁。并利用JavaScriptCore提供的JSContextRef傳遞remoteModuleTable,remoteMethodTable給到rn前端;

b杀饵、rn前端映射表數(shù)據(jù)結(jié)構(gòu)

??rn前端的remoteModuleTable數(shù)據(jù):


remoteModuleT.png



??rn前端的remoteMethodTable數(shù)據(jù):

remoteMethodT.png


c莽囤、native與rn前端互調(diào)的例子

??一個(gè)native調(diào)js,同時(shí)js又調(diào)用了native的例子:

js_native_js.png


(二)切距、native調(diào)用RN前端流程朽缎;

??與前者流程不一致的是,js和Native之間并未協(xié)商一個(gè)通用的js module名及module對(duì)應(yīng)的方法Table谜悟,React Native目前在native端是直接硬編碼话肖,寫死通知rn前端的模塊名及方法名,這要求開(kāi)發(fā)者按照統(tǒng)一的寫法規(guī)范及接口文檔去調(diào)用js赌躺。


??native調(diào)用js:

nativeToJs.png



??底層仍然以JavaScriptCore作為中介狼牺,實(shí)現(xiàn)native對(duì)js的調(diào)用;

Value Object::callAsFunction(JSObjectRef thisObj, int nArgs, const JSValueRef args[]) const {
  JSValueRef exn;
  JSValueRef result = JSC_JSObjectCallAsFunction(m_context, m_obj, thisObj, nArgs, args, &exn);
  if (!result) {
    throw JSException(m_context, exn, "Exception calling object as function");
  }
  return Value(m_context, result);
}

(三)通訊原理總結(jié)礼患;

??React Native主要依賴對(duì)JavaScriptCore的深度應(yīng)用是钥,來(lái)實(shí)現(xiàn)js對(duì)native的調(diào)用掠归,通過(guò)暴露指定的類和接口來(lái)避免觸范apple的上架規(guī)定,避免像JSPatch一樣無(wú)限制的調(diào)用native代碼悄泥。rn js層實(shí)現(xiàn)dom tree和render tree的構(gòu)建虏冻,但是繪制交由了native層處理。

??實(shí)現(xiàn)方案具有創(chuàng)新性弹囚,但還不能完全滿足大型業(yè)務(wù)的開(kāi)發(fā)需求厨相,要對(duì)原有框架作些改進(jìn)和修復(fù)才能在項(xiàng)目中落地。較適合簡(jiǎn)單鸥鹉、有熱更新需要蛮穿、界面元素不太復(fù)雜的業(yè)務(wù)。希望以RN代替native開(kāi)發(fā)還為時(shí)尚早毁渗,除非有機(jī)構(gòu)或個(gè)人React Native對(duì)安卓和iOS提高兼容性践磅,和React Native底層趨于穩(wěn)定。

??但是線程之間切換存在開(kāi)銷灸异,頻繁通訊將導(dǎo)致業(yè)務(wù)流程復(fù)雜府适,需要通過(guò)callback來(lái)實(shí)現(xiàn)。同時(shí)線程切換肺樟,一般會(huì)有10-30毫秒的耗時(shí)檐春,對(duì)于即時(shí)要求嚴(yán)格的場(chǎng)景,應(yīng)盡量避免頻繁需要js與native間的通訊么伯;

二疟暖、充電樁RNBridge層、及RN前端實(shí)現(xiàn)介紹蹦狂;

??為了方便RN業(yè)務(wù)順利開(kāi)展誓篱,有必要對(duì)app原有功能進(jìn)行封裝,如"網(wǎng)絡(luò)凯楔、數(shù)據(jù)庫(kù)窜骄、藍(lán)牙、動(dòng)畫"等摆屯,React Native原生支持不太好或不夠完善的部分邻遏,進(jìn)行補(bǔ)充或修復(fù)。

RNBridge層次結(jié)構(gòu).png



??RN前端項(xiàng)目結(jié)構(gòu)圖:
RN前端結(jié)構(gòu).png



??項(xiàng)目中主要是針對(duì)RN的動(dòng)畫實(shí)現(xiàn)機(jī)制有做一些修改虐骑,RN的動(dòng)畫是依賴于js線程和主線程間的通訊准验,但是js線程切換到主線程的時(shí)間不是一致的,時(shí)快時(shí)慢廷没,這樣會(huì)導(dǎo)致主線程更新動(dòng)畫的幀間隔不一致糊饱,如果js線程卡頓,那么主線程的動(dòng)畫也相應(yīng)卡頓颠黎。


??針對(duì)以上問(wèn)題另锋,想到了用native的方式實(shí)現(xiàn)動(dòng)畫滞项,依賴于js端傳來(lái)的表達(dá)式,聲明『動(dòng)畫類型夭坪、動(dòng)畫時(shí)長(zhǎng)文判、時(shí)間循環(huán)次數(shù)』等,RN前端只是給native發(fā)送了動(dòng)畫指令及參數(shù)室梅,動(dòng)畫過(guò)程完全由native操作戏仓。從而最大限度實(shí)現(xiàn)較好的性能。





三亡鼠、安卓效果演示及簡(jiǎn)單介紹赏殃;

四、開(kāi)發(fā)過(guò)程遇到的問(wèn)題及坑點(diǎn)拆宛;

RN遇到的坑點(diǎn).png



相關(guān)的經(jīng)驗(yàn)總結(jié)備忘:

安卓經(jīng)驗(yàn)總結(jié):
a.用react-native run-android時(shí)嗓奢,提示local.properties,的ndk目錄浑厚、sdk目錄未設(shè)置,打開(kāi)設(shè)置根盒;

b.不能下載https://jcenter.bintray.com/com/google/auto/value/auto-value/1.5.2/auto-value-1.5.2.jar钳幅,可以將ss代理設(shè)置成全局代理⊙字停或者不走shadowsocks客戶端敢艰,直接由as配置ip、port册赛、password钠导、帳戶。

c.默認(rèn)rn demo加載的是本地assets的bundle森瘪,則輸入以下命令:
1)mkdir android/app/src/main/assets
2)react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res

d.搖晃vivo牡属,輸入ip:port,之后扼睬,要重啟npm服務(wù)逮栅,才可以在線打bundle包;

e.提示在本地ip的環(huán)境下窗宇,加載locolhost的請(qǐng)求措伐,被跨域攔截,安裝chrome跨域工具军俊;

f.cd Awesome
react-native run-android
i.compile project(':android-jsc')
compile 'org.webkit:android-jsc:r174650'

g.單例莫名被析構(gòu)侥加,原因是當(dāng)前rn js代碼有問(wèn)題,會(huì)強(qiáng)制析構(gòu)ReactActivity及相關(guān)聯(lián)的單例類粪躬。原因未知担败。
開(kāi)發(fā)過(guò)程中常見(jiàn)的問(wèn)題總結(jié):
a.Super expression must either be null or a function, not undefined
component的首字母沒(méi)有為大寫

b.https://github.com/facebook/react-native/issues/14314
Packager can not find entry file index.ios.js in any of the roots... #14314
watchman watch-del-all
rm -rf node_modules && npm install
npm start -- --reset-cache

c.no bundle url
一般是shadowsocks開(kāi)了全局代理導(dǎo)致昔穴。

d.Unable to resolve module `AccessibilityInfo`
重啟電腦,并且npm start --reset-cache

e.Error: Cannot find module '/Users/liuyihao/beehome/node_modules/react-native/local-cli/cli.js'
    at Function.Module._resolveFilename (module.js:485:15)
    at Function.Module._load (module.js:437:25)
    at Function.Module.runMain (module.js:605:10)
    at startup (bootstrap_node.js:158:16)
    at bootstrap_node.js:575:3
npm ERR! code ELIFECYCLE
npm ERR! errno 1
提示npm ERR! code ELIFECYCLE
rm -rf node_modules && rm ./package-lock.json && npm install

f.
如果出現(xiàn)修改了的代碼不生效氢架,或者出現(xiàn)"Module `*` does not exist in the Haste module map"傻咖、<br>"Unable to resolve module `AccessibilityInfo`",可以嘗試重啟清除npm緩存;
Reset Metro Bundler cache: `rm -rf /tmp/metro-bundler-cache-*` or `npm start -- --reset-cache`.

h.
render方法的括號(hào)一定要在return后面岖研,不可以換行卿操,否則將crash.
return ()

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市孙援,隨后出現(xiàn)的幾起案子害淤,更是在濱河造成了極大的恐慌,老刑警劉巖拓售,帶你破解...
    沈念sama閱讀 212,718評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件窥摄,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡础淤,警方通過(guò)查閱死者的電腦和手機(jī)崭放,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)鸽凶,“玉大人币砂,你說(shuō)我怎么就攤上這事〔=模” “怎么了决摧?”我有些...
    開(kāi)封第一講書人閱讀 158,207評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)凑兰。 經(jīng)常有香客問(wèn)我掌桩,道長(zhǎng),這世上最難降的妖魔是什么姑食? 我笑而不...
    開(kāi)封第一講書人閱讀 56,755評(píng)論 1 284
  • 正文 為了忘掉前任波岛,我火速辦了婚禮,結(jié)果婚禮上矢门,老公的妹妹穿的比我還像新娘盆色。我一直安慰自己,他們只是感情好祟剔,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,862評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布隔躲。 她就那樣靜靜地躺著,像睡著了一般物延。 火紅的嫁衣襯著肌膚如雪宣旱。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 50,050評(píng)論 1 291
  • 那天叛薯,我揣著相機(jī)與錄音浑吟,去河邊找鬼笙纤。 笑死,一個(gè)胖子當(dāng)著我的面吹牛组力,可吹牛的內(nèi)容都是我干的省容。 我是一名探鬼主播,決...
    沈念sama閱讀 39,136評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼燎字,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼腥椒!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起候衍,我...
    開(kāi)封第一講書人閱讀 37,882評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤笼蛛,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后蛉鹿,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體滨砍,經(jīng)...
    沈念sama閱讀 44,330評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,651評(píng)論 2 327
  • 正文 我和宋清朗相戀三年妖异,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了惋戏。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,789評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡他膳,死狀恐怖日川,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情矩乐,我是刑警寧澤,帶...
    沈念sama閱讀 34,477評(píng)論 4 333
  • 正文 年R本政府宣布回论,位于F島的核電站散罕,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏傀蓉。R本人自食惡果不足惜欧漱,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,135評(píng)論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望葬燎。 院中可真熱鬧误甚,春花似錦、人聲如沸谱净。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,864評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)壕探。三九已至冈钦,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間李请,已是汗流浹背瞧筛。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,099評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工厉熟, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人较幌。 一個(gè)月前我還...
    沈念sama閱讀 46,598評(píng)論 2 362
  • 正文 我出身青樓揍瑟,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親乍炉。 傳聞我的和親對(duì)象是個(gè)殘疾皇子绢片,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,697評(píng)論 2 351

推薦閱讀更多精彩內(nèi)容