ReactNative跨平臺(tái)開發(fā)實(shí)踐-簡易直播demo2

接ReactNative跨平臺(tái)開發(fā)實(shí)踐-簡易直播demo1

三:實(shí)現(xiàn)細(xì)節(jié)

1.集成ReactNative

官網(wǎng)上已經(jīng)對(duì)安卓與iOS平臺(tái)集成ReactNative描述的很詳細(xì)了,在此就僅附上官網(wǎng)地址,按照官網(wǎng)步驟就可以集成到現(xiàn)有的原生APP中了。
官網(wǎng)地址:http://facebook.github.io/react-native/docs/integration-with-existing-apps.html

2.第三方庫使用方法

簡要介紹下對(duì)于本demo中使用到的百度推流端SDK,播放端SDK與融云IM SDK的使用方式。
以iOS端為例:
整個(gè)工程是基于cocoapods來開發(fā)的,因?yàn)橐昧说谌綆?,使用cocoapods方便管理。

    pod 'BaiduBCECapture', "~> 2.0"
    pod 'BaiduBCEPlayerLSS', "2.0.0"
    pod 'RongCloudIM', "~> 2.8.14"

推流SDK:BaiduBCECapture與播放SDK:BaiduBCEPlayerLSS的使用比較簡單,根據(jù)官網(wǎng)提供的demo中的調(diào)用方法,將自己的View(在安卓中則是surfaceView)交給SDK來持有就能實(shí)現(xiàn)視頻渲染了。
下圖則是具體的與第三方SDK的交互流程:

類設(shè)計(jì)思路.png

根據(jù)上圖再看代碼就很清晰了。
再簡要介紹下融云IM SDK:RongCloudIM的使用方法,基本原理為實(shí)現(xiàn)協(xié)議RCIMClientReceiveMessageDelegate,接收到消息進(jìn)入?yún)f(xié)議方法onReceived,其余例如發(fā)送消息的操作都是由單例來完成。

3.(重點(diǎn))將native組件包裝成component暴露給JS的實(shí)現(xiàn)過程

首先附上官網(wǎng)中將Native UI Component封裝給RN的地址:
iOS:http://facebook.github.io/react-native/docs/native-components-ios.html
Android:http://facebook.github.io/react-native/docs/native-components-android.html
根據(jù)前面的設(shè)計(jì)思路,可以總結(jié)出需要封裝的類即為持有了Model的原生類,RN層需要在這個(gè)原生組件之上放置按鈕等控件。
iOS的封裝的步驟按照官網(wǎng)步驟即可,但安卓的就要復(fù)雜一些,首先明確在安卓中是由ViewGroup來管理一系列的View的,但由于我們是想跟iOS的設(shè)計(jì)思路保持一致,即在RN中直接使用原生類的component,在其上加控件,那么需要封裝的就不能是官網(wǎng)示例中的 SimpleViewManager了,必須是可以管理View的ViewGroup,由于我不會(huì)安卓開發(fā),關(guān)于這點(diǎn)走了不少的彎路,還是萬分感謝安卓的同事的指點(diǎn)。

public class ZYLiveBackGroundViewManager extends ViewGroupManager<FrameLayout>

暴露給RN的方法:
1.無需回調(diào)的方法:RCT_EXPORT_METHOD(),如界面上的返回按鈕就無需回調(diào),這個(gè)按鈕直接返回設(shè)置頁,無論結(jié)束推流或播放停止時(shí)是成功還是失敗都會(huì)返回,所以無需將其設(shè)置為回調(diào)方法。
2.需要回調(diào)的方法:RCT_REMAP_METHOD(),如推流界面的控制攝像頭方向,設(shè)置美顏,設(shè)置閃光燈以及開啟推流等按鈕都需要知道是否操作成功,若操作成功更改界面,來提示用戶操作成功,這類需要更新UI的方法就需要回調(diào)。
具體實(shí)現(xiàn)方法附上官網(wǎng)地址:
iOS:http://facebook.github.io/react-native/docs/native-modules-ios.html
Android:http://facebook.github.io/react-native/docs/native-modules-android.html

這里值得注意的是RN在設(shè)計(jì)的時(shí)候,無論是iOS還是安卓,只要是原生封裝暴露給RN的component,都已經(jīng)實(shí)現(xiàn)了橋接協(xié)議:

iOS:
@interface RCTViewManager : NSObject <RCTBridgeModule>

android:
...
public abstract class ViewGroupManager <T extends ViewGroup>
    extends BaseViewManager<T, LayoutShadowNode>
...
...
public abstract class BaseViewManager<T extends View, C extends LayoutShadowNode> extends ViewManager<T, C> 
...
...
public abstract class ViewManager<T extends View, C extends ReactShadowNode> extends BaseJavaModule 
...

這樣做的原因應(yīng)該去看下源碼才能理解了,但對(duì)我們來說,本身已經(jīng)暴露成功的Native UI Component就已經(jīng)可以當(dāng)成Native Module來使用了。所以,關(guān)于module的方法都可直接寫在這個(gè)component中。
使用方法如下,以iOS中的推流層為例:

nativeStreamView.js
module.exports = requireNativeComponent('ZYLiveBackGroundView', null);//將原生封裝的Component暴露出來

streamView.js
import ZYLiveBackGroundView from './nativeStreamView';//獲取原生暴露的Component
var myModule = NativeModules.ZYLiveBackGroundViewManager;//獲取原生暴露的module,其實(shí)都是從iOS的ZYLiveBackGroundViewManager這個(gè)類中獲取的
...//component的使用:
<ZYLiveBackGroundView style={styles.background}>
...
...//module的使用
myModule.onBack();
...

介紹完JS調(diào)用原生類后再介紹下原生調(diào)用RN的實(shí)現(xiàn),上訴基本是JS來調(diào)用原生的控件或方法的,但由于加入了聊天室的功能,融云IM SDK是用原生來實(shí)現(xiàn)的,當(dāng)收到新的消息是,SDK的回調(diào)也僅限于原生類,而我們需要在界面上顯示收到的這個(gè)消息,所以需要在原生收到消息時(shí)告知JS來更新界面,這也叫作消息分發(fā)。
附上官網(wǎng)實(shí)現(xiàn)方法:
iOS:http://facebook.github.io/react-native/docs/native-modules-ios.html#sending-events-to-javascript
Android:http://facebook.github.io/react-native/docs/native-modules-android.html#sending-events-to-javascript
首先我去查找了RCTEventEmitter這個(gè)消息分發(fā)類,發(fā)現(xiàn)這個(gè)類與RCTViewManager無關(guān),所以沒法再在同一個(gè)原生類中實(shí)現(xiàn)消息回傳RN了,只能新建一個(gè)專門用于實(shí)現(xiàn)調(diào)用JS的類。

iOS ,Android:
IMCloud

具體的使用方法官方文檔里已經(jīng)描述的很清楚了,這里就不重復(fù)了,直接看代碼就明白了。

四.打包

無論是iOS打包或安卓打包都需要將JS文件與圖片文件打包至bundle中,引入工程,但官網(wǎng)中并未提及這點(diǎn)(略坑),所以簡要說一下打包的步驟。

iOS打包步驟:

1.打包命令:到項(xiàng)目根目錄下執(zhí)行

react-native bundle --entry-file ./index.ios.js --bundle-output ./ios/index.ios.jsbundle --platform ios --assets-dest ./ios --dev false

輸出文件也可不放到iOS工程下,然后回到Xcode中,添加剛剛生成的
idex.ios.jsbundle與assets文件,其中assets的添加方式要選為Create Folder Reference,然后將Scheme修改為release,獲取jsbundle的方式改為:

//打包后獲取離線bundle
    jsCodeLocation = [NSURL URLWithString:[[NSBundle mainBundle] pathForResource:@"index.ios.jsbundle" ofType:nil]];

就可以打包上傳iOS應(yīng)用了。

安卓打包步驟

參考:
http://www.itdecent.cn/p/61e27d9b02f2

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,872評(píng)論 25 709
  • 最近在學(xué)習(xí)ReactNative開發(fā),感覺還是很容易上手的,搜集了不少資料,分享給大家。 為什么選ReactNat...
    StChris閱讀 1,700評(píng)論 0 37
  • 一、要想理解多線程,必須要了解一下幾個(gè)概念: 1.什么是進(jìn)程: 例如:同時(shí)打開QQ和微信,系統(tǒng)同時(shí)啟動(dòng)兩個(gè)程序,此...
    MangoJ閱讀 231評(píng)論 0 1
  • 今天小朋友們期中考試全部完成了,語文成績沒有出來,數(shù)學(xué)與英語出來了。然后弟就對(duì)我說:“媽媽,有一個(gè)好消息,一...
    銘嵐閱讀 181評(píng)論 0 0
  • #日記迎春20170304日行一善 早晨去打掃工作室,擺好墊子,準(zhǔn)備茶水,水果等,為學(xué)習(xí)小組的活動(dòng)做準(zhǔn)備,感謝提前...
    靜儉閱讀 200評(píng)論 0 0

友情鏈接更多精彩內(nèi)容