本人是做后端php的,对各类语言和方向都有兴趣,多而不精。最近公司项目有一个移动端app,决定采用react-native开发,项目中有这么个要求,要求react-native中嵌入原生页面,然后原生页面嵌入unity,并实现原生和unity之前相互通信,网络查找资料后实现这些功能,查找过程中,遇到很多问题,并且参照了很多网友的博客,在此做一个记录,以防后患。
开发环境及工具:
macbook pro, webstorm,android studio,unity
本篇文章是第一篇,实现react-native加入android原生。
1.创建react-native项目:react-native init rauDemo
进入目录:cd rauDemo
用webstorm打开项目进行编辑项目,用android studio打开内部android项目,本步的目的是指定本机的android sdk的路径,否则会报如下错误:
*What went wrong:
Aproblem occurred configuring project ':app'.
>SDK location not found.Define location with sdk.dir in the local.properties file or with anANDROID_HOME environment variable.
测试运行:usb连接手机,react-native run-android
成功运行,如下图:
2.android studio打开的android目录如下:
添加代码,将java方法封装成react可调用的方法,按照官方方式:
在src/main/java/com.raudemo下添加代码,
(1)添加RedirectModule.java,代码如下:
public class RedirectModule extends ReactContextBaseJavaModule {
public RedirectModule(ReactApplicationContext reactContext) {
super(reactContext);
}
@Override
public String getName() {
return "RedirectModule";
}
/**
* 从JS页面跳转到原生activity 同时也可以从JS传递相关数据到原生
* @param name 需要打开的Activity的class
* @param params
*/
@ReactMethod
public void startActivityFromJS(String name, String params){
try{
Activity currentActivity = getCurrentActivity();
if(null!=currentActivity){
Class toActivity = Class.forName(name);
Intent intent = new Intent(currentActivity,toActivity);
intent.putExtra("params", params);
currentActivity.startActivity(intent);
}
}catch(Exception e){
throw new JSApplicationIllegalArgumentException(
"不能打开Activity : "+e.getMessage()+e.toString());
}
}
}
(2)添加MyReactPackage.java,代码如下:
public class MyReactPackage implements ReactPackage {
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
return Arrays.<NativeModule>asList(
new RedirectModule(reactContext)
);
}
public List<Class<? extends JavaScriptModule>> createJSModules() {
return Collections.emptyList();
}
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}
(3)MainApplication.java添加代码:newMyReactPackage(),最后如下:
public class MainApplication 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(),
new MyReactPackage()
);
}
@Override
protected String getJSMainModuleName() {
return "index";
}
};
@Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
@Override
public void onCreate() {
super.onCreate();
SoLoader.init(this, /* native exopackage */ false);
}
}
最后项目结构如图:
3.android studio新建页面,命名UnityActuivity,为之后嵌入Unity程序准备。
修改页面布局,代码包里有,需要将UnityActivity设置成横屏,在AndroidManifest.xml里面UnityActivity添加android:screenOrientation="landscape",原因是Unity导出的程序会有屏幕横屏等设置,需要相对应。过后说这个问题
4.修改react-native代码:
在App.js内导入TouchableOpacity和NativeModules组件,NativeModules即为react-native提供的入口,android原生写的RedirectModule可以通过这个组件读到。
Return的页面里面添加如下代码:
<TouchableOpacity onPress={()=>{
NativeModules.RedirectModule.startActivityFromJS('com.raudemo.UnityActivity','eeeee')
}}>
<Text>
跳转原生android
</Text>
</TouchableOpacity>
目的是实现点击跳转原生页面。
截图如下:
点击跳转后如下:
至此,react-native跳转原生页面完成。
完整代码:稍后奉上