Android组件化基础(二)——组件间的通信

目录

导入依赖

内容补充

修改所有使用到路由跳转的组件的build.gradle文件

 初始化ARouter的SDK

使用 ARouter 进行跳转

在活动中添加注解

设置跳转事件

组件间的通信

携带参数跳转

 只传输数据不跳转


书接上回Android组件化基础(一)——概述与基本配置-CSDN博客

        组件化后,不同组件之间没有相互依赖,模块间的跳转就不能再通过 startActivity() 这种方式,比较常用的是阿里的 ARouter 路由框架,GitHub 的项目主页上对于使用方法介绍的已经很详细,这里我们就简单说说。

导入依赖

        首先我们在根目录下的config.gradle文件添加依赖

    libARouter = "com.alibaba:arouter-api:1.5.2"
    libARouterCompiler = "com.alibaba:arouter-compiler:1.5.2"

        完整代码

ext{
    isRelease = true

    androidId = [
            compileSdk : 33,
            minSdk : 24,
            targetSdk : 33,
            versionCode : 1,
            versionName : "1.0"
    ]

    appId = [
            app : "com.example.componentdemo",
            first : "com.example.module.first",
            second : "com.example.module.second"
    ]
    dependencies = [
            "appcompat" : "androidx.appcompat:appcompat:1.4.1",
            "material" : "com.google.android.material:material:1.5.0",
            "constraintlayout" : "androidx.constraintlayout:constraintlayout:2.1.3",
    ]
    libARouter = "com.alibaba:arouter-api:1.5.2"
    libARouterCompiler = "com.alibaba:arouter-compiler:1.5.2"
}

        修改基础组件下的build.gradle文件,在dependencies中添加如下依赖

api libARouter

内容补充

  api 关键字: 当你使用 api 关键字声明依赖关系时,该依赖会对所有的模块可见,并会被传递到依赖该模块的其他模块。换句话说,如果 Module A 使用了 api 关键字引入 Module B,那么Module A 的依赖模块也能访问 Module B。

  implementation 关键字: 当你使用 implementation 关键字声明依赖关系时,该依赖只对当前模块可见,并不会被传递到依赖该模块的其他模块。这样可以避免将不必要的依赖泄漏到其他模块中。

修改所有使用到路由跳转的组件的build.gradle文件

        首先添加如下代码

javaCompileOptions {
            annotationProcessorOptions {
                // 当前模块名作为参数
                arguments = [AROUTER_MODULE_NAME: project.getName()]
            }
        }

        因为 ARouter 是利用 APT 技术通过自动生成代码建立路由表从而支持模块间跳转的,因此模块中如果有 Activity/Fragment 需要加入路由表时,就需要为其加上注解,并由注解处理器扫描后才能被添加到路由表中,而建立路由表时需要用模块名作为参数,所以才需要用 javaCompileOptions -> annotationProcessorOptions 这种形式将模块名传递给注解处理器。

        接下来导入依赖

annotationProcessor 'com.alibaba:arouter-compiler:1.5.2'

         补充说明:

annotationProcessorapi是Gradle中的两种不同的依赖声明方式。

  1. annotationProcessor: 用于声明注解处理器的依赖。注解处理器通常用于在编译时生成代码,例如在使用ARouter时,libARouterCompiler可能是一个用于生成路由映射表的注解处理器。因此,它通常不会直接影响到应用程序的运行时依赖。

  2. api: 用于声明在编译时和运行时都需要的依赖。当你使用api关键字引入依赖时,这个依赖将会被传递到依赖于你的库或应用程序中。这意味着,如果libARouterCompiler是一个用于编译时生成代码的注解处理器,它不应该被声明为api依赖,因为它只在编译时被使用,而不会直接影响到运行时的依赖。

因此,你应该将libARouterCompiler声明为annotationProcessor依赖,而不是api依赖。

        如果你的每个组件都需要使用 libARouterCompiler 进行编译时的注解处理,那么你需要将该依赖声明放在每个组件模块的 Gradle 文件中。但是请确保不要在基础组件将其声明为 api 依赖。

以下是app包下的build.gradle文件示例

plugins {
    id 'com.android.application'
}

def androidId = rootProject.ext.androidId
def appId = rootProject.ext.appId
def support =  rootProject.ext.dependencies

android {
    namespace 'com.example.componentdemo'
    compileSdk androidId.compileSdk

    defaultConfig {
        applicationId appId.app
        minSdk androidId.minSdk
        targetSdk androidId.targetSdk
        versionCode androidId.versionCode
        versionName androidId.versionName

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

        javaCompileOptions {
            annotationProcessorOptions {
                // 当前模块名作为参数
                arguments = [AROUTER_MODULE_NAME: project.getName()]
            }
        }
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

dependencies {


    if (isRelease){
        implementation project(":moduleCore:first")
        implementation project(":moduleCore:second")
    }

    implementation project(":moduleBase:libBase")
    annotationProcessor 'com.alibaba:arouter-compiler:1.5.2'
    
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}

本文还需要修改first和second包下的build.gradle文件

 初始化ARouter的SDK

在app下即主工程的入口MainActivity的包新建一个类

package com.example.componentdemo;

import android.app.Application;

import com.alibaba.android.arouter.BuildConfig;
import com.alibaba.android.arouter.launcher.ARouter;

public class BaseApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        if (BuildConfig.DEBUG){
            ARouter.openLog();
            ARouter.openDebug();
        }
        ARouter.init(this);
    }
}

然后修改AndroidMenifest文件的application内容,

android:name=".BaseApplication"

使用 ARouter 进行跳转

在活动中添加注解

设置跳转事件

(这是主活动的)

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        textView1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                ARouter.getInstance().build("/first/FirstActivity").navigation();
            }
        });
        textView2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                ARouter.getInstance().build("/second/SecondActivity").navigation();
            }
        });
    }

 这是FirstActivity的

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_first);

        textView = (TextView) findViewById(R.id.first);
        message = (TextView) findViewById(R.id.text1);
        textView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                ARouter.getInstance().build("/second/SecondActivity").navigation();
            }
        });
    }

如果发现活动无法跳转或是报错,可以尝试在根目录下的 gradle.properties文件添加改行代码

android.enableJetifier=true

 android.enableJetifier=true是一个Gradle属性,用于在构建过程中启用Jetifier。Jetifier是一个工具,用于将旧版的Android Support库依赖转换为适用于AndroidX的新版依赖,这样可以使项目能够与AndroidX兼容。启用Jetifier可以确保项目中的所有依赖都与AndroidX兼容,而不仅仅是直接依赖的库。

组件间的通信

携带参数跳转

跳转启动方:FirstActivity

ARouter.getInstance().build("/second/SecondActivity")
                        .withString("from","FirstActivity :")
                        .withString("key","Hello! Here is FirstActivity!")
                        .navigation();

 参数接收方:SecondActivity

@Route(path = "/second/SecondActivity")
public class SecondActivity extends AppCompatActivity {

    //为每一个参数声明一个字段,并使用@Autowired注解标记
    @Autowired(name = "from")
    public String from;

    @Autowired(name = "key")
    public String info;

    ...    

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

        textView3 = (TextView) findViewById(R.id.info_from);
        textView4 = (TextView) findViewById(R.id.info_key);

        ARouter.getInstance().inject(this);//自动注入参数
        textView3.setText(from);
        textView4.setText(info);

       ...
    }
    ...
}

 效果

 只传输数据不跳转

        首先,在基础组件libBase包下新建一个接口InfoProvider,继承自

IProvider。当然,你也可以新建一个基础组件,新建完成之后记得在使用的组件下导入项目。这里为了方便,选择了前者。

public interface InfoProvider extends IProvider {

    int getId();
    String getInfo();
}

         然后随便在一个组件中实现它,这里我选择在first组件下实现

@Route(path = "/first/MyInfoProvider")
public class MyInfoProvider implements InfoProvider {
    @Override
    public int getId() {
        return 666;
    }

    @Override
    public String getInfo() {
        return "Hello World!";
    }

    @Override
    public void init(Context context) {

    }
}

         然后可以随便选择一个组件去应用

ARouter.getInstance().inject(this);
        Toast.makeText(this,"" + provider.getId() + " " + provider.getInfo(),Toast.LENGTH_LONG).show();

 

ARouter.getInstance().inject(this);
        textView5 = (TextView) findViewById(R.id.info_id);
        textView6 = (TextView) findViewById(R.id.info_info);
        textView5.setText(provider.getId() + "");
        textView6.setText(provider.getInfo());

 

        另外, ARouter.getInstance().inject(this)不能为跳转参数和接口同时注入参数,意思是,接待参数跳转和接口不能同时写在一个活动里,至少我为了图方便写在同一个活动时频频报错,分开写时运行成功

本文参考博客:一步步搭建组件化项目&ARouter的使用-CSDN博客Android 组件化基础(一)—— 概述与基本配置_组件化在项目中的意义-CSDN博客 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值