阅读 208

Android 使用Maven私库管理React Native组件

浅谈Gradle

因为考虑到读者可能有人之前没接触过安卓,这里简单说一下Android如何通过Gradle引入第三方库。

an_imRN_Step_1.png

打开安卓的原生工程,大家会发先有两个build.gradle,一个在根文件下,一个在app的目录下。 点开根目录下的build.gradle大致如下

// 定义项目中所有模块共用的代码库和依赖项
buildscript {
	// 定义代码库 用来搜索依赖的第三方代码
    repositories {
        google() 
        jcenter() 
    }
    // 依赖块配置Gradle需要使用的依赖项
    dependencies {
        classpath 'com.android.tools.build:gradle:3.4.1'
        
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
	 // 这里最好好上面的repositories保持一致
    repositories {
        google()
        jcenter()
        
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

复制代码

点开app目录下的build.gradle大致如下

// 声明是Android应用程序还是库模块
apply plugin: 'com.android.application'

android {
	// 用于指定项目的编译SDK版本
    compileSdkVersion 29
    // 指定项目构建工具的版本
    buildToolsVersion "29.0.2"
    defaultConfig {
    	// 应用程序包名
        applicationId "com.example.creditsystem"
        // 最小 sdk 版本
        minSdkVersion 15
        // 目标 sdk 版本
        targetSdkVersion 29
        // 版本号
        versionCode 1
        // 版本名
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
    // 指定生成安装文件的配置
    buildTypes {
        release {
        	// 是否对代码进行混淆
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

// 指定当前项目的所有依赖关系:本地依赖、库依赖、远程依赖
dependencies {
	// 本地依赖:可以对本地Jar包或目录添加依赖关系
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test:runner:1.2.0'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}
复制代码

可以理解为:根目录下build.gradlerepositories是用来声明依赖了哪些远程库,app目录下的build.gradledependencies 是用来声明具体使用了哪些代码库,在Sycn🐘的时候会从远程库中遍历查找并下载依赖的代码库。

使用nexus搭建maven私服

  • 下载nexus
brew install nexus
复制代码

注意: nexus有可能已经被墙了,需要在命令行配置代理才能下载成功。

  • 运行nexus
brew services start nexus
复制代码
  • 在浏览器中输入nexus管理地址为127.0.0.1:8081/nexus
  • 点击右上角登录按钮,默认管理员帐号密码分别为adminadmin123
  • 关闭nexus
brew services stop nexus
复制代码

上传到maven私库

如图选中Repositories

Maven_RNACUpload_Step_1.png 点击Add按钮

Maven_RNEN_Step_2.png 填写 Repository ID 和 Repository Name

Maven_RNEN_Step_3.png

  1. 选中Artifact Upload
  2. GAV Definition 选择 From POM
  3. 点击 select POM 上传POM文件

Maven_RNEN_Step_4.png 选择 /node_modules/react-native/android/com/facebook/react/react-native/0.54.0 路径下的 react-native-0.54.0.pom

Maven_RNEN_Step_5.png 选择 Select Artifact(s)Upload

Maven_RNEN_Step_6.png

选择 /node_modules/react-native/android/com/facebook/react/react-native/0.54.0 路径下的 react-native-0.54.0.aar

Maven_RNEN_Step_7.png

  1. 点击add Artifact 会发现aar出现在Artifacts列表中
  2. 点击 Upload Artifact就完成上传了。

Maven_RNEN_Step_8.png

  1. 点击 Browse Index
  2. 点击刷新会看到有com文件夹

Maven_RNEN_Step_9.png

  1. 回到项目区 找到我们创建的项目
  2. 点击项目右侧的仓库地址

Maven_RNEN_Step_10.png

  1. 依次往下级目录点击直到最里面的目录下
  2. 查看aar和pom文件是否存在,都存在说明上传成功了。

Maven_RNEN_Step_11.png

测试我们上传的RN环境库

在根目录下的 build.gradle中添加我的私有maven库的地址,app中的build.gradle无需修改。

allprojects {
    repositories {
        maven{ url'http://maven.aliyun.com/nexus/content/repositories/google'}
        maven{ url'http://maven.aliyun.com/nexus/content/repositories/jcenter'}
        maven{ url'http://127.0.0.1:8081/nexus/content/repositories/RNEnvironment_0.54.0/'}
        maven{ url'http://127.0.0.1:8081/nexus/content/repositories/RNCreditSystem/'}
// 将本地的maven库注释
//        mavenLocal()
//        maven {
//            // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
//            url "$rootDir/../node_modules/react-native/android"
//        }
    }
}
复制代码

然后点击🐘同步一下,点击运行,如果一切OK说明替换成功。

将RN代码打包

  • ./android/app/src/main 路径下创建 assets 文件夹。
  • 执行命令
react-native bundle --entry-file index.js --platform android --dev false --bundle-output ./android/app/src/main/assets/index.android.bundle --assets-dest ./android/app/src/main/res/
复制代码
--entry-file: ios 或者 android 入口的 js 名称,比如 index.ios.js index.ios.js 在高版本0.48之后已经统一变成 index.js 了.
--platform: 平台名称( ios 或者 android )
--dev: 设置为 false 的时候将会对 JavaScript 代码进行优化处理
--bundle-output: 生成的 jsbundle 文件的名称,比如 ./ios/bundle/index.ios.jsbundle
--assets-dest: 图片以及其他资源存放的目录,比如 ./ios/bundle
复制代码
  • ../android/app/src/main/assets地址里你会看到 index.android.bundle文件,这个bundle就是我们RN离线包

使用Maven管理RN组件代码

  • 打开安卓项目,在app的同级新建一个module

操作:File -> New -> New Module -> Android Libraey -> 填写名字 rnmodule

  • rnmodule中创建一个RNMainActivity来加载RN,

操作:双指击rnmodule 然后 New -> Activety -> Empty Activety -> 填写名字 RNMainActivity

  • 我的RNMainActivity代码如下:
// 这里是为了导入 rnmodule 这个包
import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactRootView;
import com.facebook.react.common.LifecycleState;
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
import com.facebook.react.shell.MainReactPackage;


public class RNMainActivity extends AppCompatActivity implements DefaultHardwareBackBtnHandler {
    private ReactRootView mReactRootView;
    private ReactInstanceManager mReactInstanceManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);


        mReactRootView = new ReactRootView(this);
        mReactInstanceManager = ReactInstanceManager.builder()
                .setApplication(getApplication())
                .setBundleAssetName("index.android.bundle")
                .setJSMainModulePath("index")
                .addPackage(new MainReactPackage())
                .setUseDeveloperSupport(BuildConfig.DEBUG)
                .setInitialLifecycleState(LifecycleState.RESUMED)
                .build();

        // 注意这里的MyReactNativeApp必须对应“index.js”中的
        // “AppRegistry.registerComponent()”的第一个参数
        mReactRootView.startReactApplication(mReactInstanceManager, "creditSystem", null);

        setContentView(mReactRootView);
    }

    @Override
    public void invokeDefaultOnBackPressed() {
        super.onBackPressed();
    }
}
复制代码
  • 在主工程app中的MainActivity中调用 RNMainActivity,添加一个按钮点击跳转RN页面,代码如下:

MainActivity位置src -> main -> java -> com.example.creditSystem -> MainActivity

package com.example.creditsystem;

import androidx.appcompat.app.AppCompatActivity;
import android.widget.Button;
import android.view.View;
import android.os.Bundle;
import android.content.Intent;

// 引用我们新建rnmodule中加载RN的 RNMainActivity
import com.example.rnmodule.RNMainActivity;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button mButton = (Button)findViewById(R.id.button);
        mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent();
                intent.setClass(view.getContext(), RNMainActivity.class);//指明要跳转的Activity类
                startActivity(intent);
            }
        });
    }

}
复制代码

对应的xml位置src -> main -> res -> layout -> activity_main.xml

// activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/phone"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        android:clickable="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/button"
        android:text="按钮"/>

</androidx.constraintlayout.widget.ConstraintLayout>

复制代码
  • 点击🐘同步成功后,运行程序,点击按钮,RN页面加载成功则代表一切正常
  • 在工程目录下的gradle.properties中声明Maven私库的一些信息,具体如下
# 仓库地址
MAVEN_REPO_RELEASE_URL=http://127.0.0.1:8081/nexus/content/repositories/RNCreditSystem/

#对应maven的GroupId的值
GROUP = RNCreditSystem

# groupid
GROUP_ID = RNCreditSystem

# 账号和密码
NEXUS_USERNAME=admin
NEXUS_PASSWORD=admin123

# type
TYPE = aar

# 描述
DESCRIPTION = test
复制代码
  • 找到rnmodule中的build.gradle文件添加uploadArchives
apply plugin: 'maven'

uploadArchives { //新增 ,因为Android Studio gradle 支持maven插件,所以可以添加此task
    configuration = configurations.archives
    repositories {
        mavenDeployer {

            repository(url: MAVEN_REPO_RELEASE_URL) {
                authentication(userName: NEXUS_USERNAME, password: NEXUS_PASSWORD)
            }

            pom.project {
                version '1.1.8' //版本名称 上传是不能和之前的一样,否则上传失败
                artifactId GROUP_ID  //和前面网站上填写的一样
                groupId GROUP  //和前面网站上填写的一样
                packaging TYPE //填写aar
                description DESCRIPTION //更新描述
            }
        }
    }
}

复制代码
  1. 点击右侧的gradle
  2. 双击uploadArchives运行脚本
  3. 至此我们已经将RN组件上传至maven私库了

Maven_RNACUpload_Step_1.png

接入Maven私库中的RN组件

  • 新建一个名字为Test的项目
  • 在根目录的build.gradle中添加我们的Maven库地址
allprojects {
    repositories {
    	// 这里是我使用的阿里的源 相当于google() 和 jcenter()
        maven{ url'http://maven.aliyun.com/nexus/content/repositories/google'}
        maven{ url'http://maven.aliyun.com/nexus/content/repositories/jcenter'}
        // maven私库的地址
        maven{ url'http://127.0.0.1:8081/nexus/content/repositories/RNEnvironment_0.54.0/'}
        maven{ url'http://127.0.0.1:8081/nexus/content/repositories/RNCreditSystem/'}
    }
}
复制代码
  • app下的build.gradle中引入我们的RN组件
dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.0.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    implementation "com.facebook.react:react-native:0.54.0"
    implementation "RNCreditSystem:RNCreditSystem:1.1.8"
    implementation 'androidx.appcompat:appcompat:1.1.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test:runner:1.2.0'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}
复制代码
  • appMainActivity中添加一个按钮来跳转我们封装的RN界面,具体代码和上面的一模一样
  • 运行点击按钮跳转RN界面成功
文章分类
Android