ReactNative与Android(安卓)集成踩坑
16lz
2021-12-04
- 1. 设置项目目录结构
- 首先创建一个空目录用于存放React Native项目 , 然后在其中创建一个android子目录 , 把你现有的Android项目拷贝到android子目录中 ;
- 2. 安装JavaScript依赖包
- 在项目根目录下创建一个名为package.json的空文本文件,然后填入以下内容:
- name 随意
- version字段没有太大意义(除非你要把你的项目发布到npm仓库)
- scripts中是用于启动packager服务的命令
- dependencies中的react和react-native的版本取决于你的具体需求(一般来说照着复制就行 )
- 然后在项目目录(根目录)中 命令行 (npm install) 安装React和ReactNative模块...等吧 需要点儿时间
- 3. 配置AndroidStudio 将ReactNative添加到Android项目中
- 坑① : 最小支持版本为 API 16
- 坑② : com.android.support:appcompat-v7 的版本为 23
- 配置Maven
// 这个是在project中的build.gradle文件中的 allprojects { repositories { ... maven { // All of React Native (JS, Android binaries) is installed from npm // 只要npm install执行完成了 下面这个目录是真实存在的 不存在的话Gradle构建会失败 url "$rootDir/../node_modules/react-native/android" } } ... }
- 权限申请 :
- 如果需要访问 DevSettingsActivity 界面(即开发者菜单),则还需要在 AndroidManifest.xml 中声明:(此处直接复制比较好,打DevSett联想不出来)
- 开发者菜单一般仅用于在开发时从Packager服务器刷新JavaScript代码,所以在正式发布时你可以去掉这一权限。
- 4. 编写ReactNative代码
- 根目录下新建index.js (index.js是React Native应用在Android上的入口文件 而且它是不可或缺的)
- 首先是 index.js 代码
// 设置首页是哪一个类 AppRegistry.registerComponent('MyReactNativeApp', () => NewClass);
- 然后是NewClass代码(中文网中的Text输入Demo)
export default class NewClass extends Component
- 5. 6.0权限申请
- 某个Activity中动态申请悬浮窗权限 申请代码如下(中文网示例)
@Override protected void onActivityResult( int requestCode, int resultCode, Intent data) { if (requestCode == OVERLAY_PERMISSION_REQ_CODE) { if (Build.VERSION. SDK_INT >= Build.VERSION_CODES. M ) { if (!Settings. canDrawOverlays ( this )) { // TODO } } } }
- 6. 核心代码 ReactRootView ReactInstanceManager
/** * @作者 RedWolfChao * @时间 2018/2/22 16:38 * @描述 代码没有很好的弄6.0权限处理 所以在没有授权的情况下, APP会崩溃 */ public class MainActivity extends AppCompatActivity implements DefaultHardwareBackBtnHandler {
private static final int OVERLAY_PERMISSION_REQ_CODE = 10001 ; // ReactNative核心类 private ReactRootView mReactRootView ; // ... private ReactInstanceManager mReactInstanceManager ;
@Override protected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); initPermission(); initReactNative(); }
/** * 初始化ReactNative */ private void initReactNative() { mReactRootView = new ReactRootView( this ); mReactInstanceManager = ReactInstanceManager. builder () .setApplication(getApplication()) // 此处中文网中有点不一样 中文网中的文档感觉有点儿过时 .setBundleAssetName( "index.bundle" ) .setJSMainModuleName( "index" ) .addPackage( new MainReactPackage()) .setUseDeveloperSupport(BuildConfig. DEBUG ) .setInitialLifecycleState(LifecycleState. RESUMED ) .build(); // 注意这里的MyReactNativeApp 必须对应 "index.js"中的"AppRegistry.registerComponent()"的第一个参数 mReactRootView .startReactApplication( mReactInstanceManager , "MyReactNativeApp" , null ); setContentView( mReactRootView ); }
@Override protected void onActivityResult( int requestCode, int resultCode, Intent data) { if (requestCode == OVERLAY_PERMISSION_REQ_CODE ) { if (Build.VERSION. SDK_INT >= Build.VERSION_CODES. M ) { if (!Settings. canDrawOverlays ( this )) { // TODO } } } }
/** * 请求弹窗权限 */ private void initPermission() { if (Build.VERSION. SDK_INT >= Build.VERSION_CODES. M ) { if (!Settings. canDrawOverlays ( this )) { Intent intent = new Intent(Settings. ACTION_MANAGE_OVERLAY_PERMISSION , Uri. parse ( "package:" + getPackageName())); startActivityForResult(intent, OVERLAY_PERMISSION_REQ_CODE ); } } }
@Override public void invokeDefaultOnBackPressed() { super .onBackPressed(); }
@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); }
@Override protected void onPause() { super .onPause(); if ( mReactInstanceManager != null ) { mReactInstanceManager .onHostPause( this ); } }
@Override protected void onResume() { super .onResume(); if ( mReactInstanceManager != null ) { mReactInstanceManager .onHostResume( this , this ); } }
@Override protected void onDestroy() { super .onDestroy();
if ( mReactInstanceManager != null ) { mReactInstanceManager .onHostDestroy( this ); } } }
- 配置Manifest.xml
< category android :name= "android.intent.category.LAUNCHER" /> intent-filter > activity >
- 7. 起 ReactNative 服务 在根目录命令行
- 8. 运行即可 , 可以直接run app(AS的三角符号运行) , 也可以用gradlew installDebug命令行 (中文网说是直接运行会崩溃..我没遇见过)
- 9. 打包 (未测试)
- 你也可以使用Android Studio来打release包!其步骤基本和原生应用一样,只是在每次编译打包之前需要先执行js文件的打包(即生成离线的jsbundle文件)。具体的js打包命令如下:
$ react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/com/your-company-name/app-package-name/src/main/assets/index.android.bundle --assets-dest android/com/your-company-name/app-package-name/src/main/res/
- 注意把上述命令中的路径替换为你实际项目的路径。如果assets目录不存在,则需要提前自己创建一个。
- 然后在Android Studio中正常生成release版本即可!
更多相关文章
- Android高手进阶教程(七)之----Android(安卓)中Preferences的使
- android解析json(2)
- Android有用代码片段(三)
- android apk获得系统权限
- 在Android中使用Html5
- UnityAndroid(2) Android加载Unity
- Android(安卓)Duplicate files copied in APK
- Android应用程序的权限列表
- Android修改和添加APN网络