一:前言
为了配合运营和市场伙伴的工作,app中一些模块或界面需要频繁变动。于Android,可以使用webview, 热更新和rn等方法。其中webview 较为常规, 但加载速度慢,热更新还没接触(部分大厂在用),rn的话看起来很美(facebook出品,github star多),所以我选择rn进行尝试,此文是我集成rn的一个总结。
二: Android 项目配置
预设读者已经成功配置rn,as,并熟悉as工程下文件目录,遇到问题可以google。
- 新建文件夹,命名为androidwithreact
- 进入androidwithreact文件夹,新建android文件夹
- 将原有的android项目复制到android文件夹下
- 修改android/build.gradle文件,配置rn版本
}<pre><code>allprojects { repositories { jcenter() mavenLocal() maven { url "$rootDir/../node_modules/react-native/android" } }
- 修改app(module)下build.gradle 在dependencies中添加
compile 'com.facebook.react:react-native:+'
- 在manifest文件中添加一下代码方便进入开发者模式
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
新建activity作为rn呈现的载体
public class ReactActivity extends AppCompatActivity implements DefaultHardwareBackBtnHandler { private ReactRootView mReactRootView; private ReactInstanceManager mReactInstanceManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //创建一个ReactRootView,把它设置成Activity的主视图 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, "androidwithreact", null); setContentView(mReactRootView); } @Override public void invokeDefaultOnBackPressed() { super.onBackPressed(); } //传递一些Activity的生命周期事件到ReactInstanceManager,这是的JavaScript代码可以控制当前用户按下返回按钮的时候作何处理(譬如控制导航切换等等)。如果JavaScript端不处理相应的事件,你的invokeDefaultOnBackPressed方法会被调用。默认情况,这会直接结束你的Activity。 @Override protected void onPause() { super.onPause(); if (mReactInstanceManager != null) { mReactInstanceManager.onHostPause(); } } @Override protected void onResume() { super.onResume(); if (mReactInstanceManager != null) { mReactInstanceManager.onHostResume(this,this); } } @Override public void onBackPressed() { //mReactInstanceManager.showDevOptionsDialog(); Toast.makeText(this, "dianjialefanhuijian", Toast.LENGTH_SHORT).show(); if (mReactInstanceManager != null) { mReactInstanceManager.onBackPressed(); } else { super.onBackPressed(); } } //我们需要改动一下开发者菜单。默认情况下,任何开发者菜单都可以通过摇晃或者设备类触发,不过这对模拟器不是很有用。所以我们让它在按下Menu键的时候可以显示 @Override public boolean onKeyUp(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_MENU && mReactInstanceManager != null) { mReactInstanceManager.showDevOptionsDialog(); return true; } return super.onKeyUp(keyCode, event); } }
三: rn配置
- npm init 新建一个rn项目 里面有package.json和node_modules文件夹
- 让我们回到androidwithreact文件夹下 将上述两个文件复制进来
复制一个index.android.js 文件进来最后一行修改,第一个参数要修改
AppRegistry.registerComponent('androidwithreact', () => xxx);
四: 报错问题
module 0 …… stackoverflow上的解决方法是package.json中的rn版本与as中配置的版本不匹配,建议换成最新的。
- v4包冲突 在android目录下的build.gradle中添加
android { dexOptions { preDexLibraries = false } }
- bundle not packaged correctly切换到androidwithreact目录下,执行npm start开启服务