Android A项目以Module的形式引用B项目详细步骤、及常见问题和aar文件的引用

时间:2024-05-23 09:45:36

    序:这段时间一直忙于封装播放器,没有什么技术性的研究,今天正好外部公司需要集成我们公司的播放器,考虑到开发定制问题,我们将播放器进行了二次封装,但是还不够完善,所以想以Module 的形式让第三方公司进行引用,以便于对方公司能够自己迭代需求,所以我写下了这篇博客,当然aar文件的引用我在这里我也会提及。

一、A项目引用Module 结合实际进行步骤阶梯操作


1、Import Module

步骤一:导入

Android A项目以Module的形式引用B项目详细步骤、及常见问题和aar文件的引用

步骤二:选择目录

Android A项目以Module的形式引用B项目详细步骤、及常见问题和aar文件的引用

步骤三:修改Module 名称(如果没有重复名字、可以不修改)

Android A项目以Module的形式引用B项目详细步骤、及常见问题和aar文件的引用

点击finish 进行导入,导入完毕后,目录结构如下:

Android A项目以Module的形式引用B项目详细步骤、及常见问题和aar文件的引用

步骤四:将Module进行项目关联

方法一:点击项目结构
Android A项目以Module的形式引用B项目详细步骤、及常见问题和aar文件的引用
方法二:点击File进行选择

Android A项目以Module的形式引用B项目详细步骤、及常见问题和aar文件的引用

Next:出现以下界面

Android A项目以Module的形式引用B项目详细步骤、及常见问题和aar文件的引用

点击Module dependency ,选择你要关联的Module

Android A项目以Module的形式引用B项目详细步骤、及常见问题和aar文件的引用

点击Ok ------Ok即可;

接下来就是漫长的等待过程。。。。。。。。。。。。。。。。。。。。。。。。。。。。

我再说一点废话,如果你引用的本身就是Module 你可以只看到这里就好了!!! 但是如果你引入的是一个项目的下Fllow Me。。。

报错了、、、、、、

错误1

Error:Dependency VideoModule:videoplayer:unspecified on project app resolves to an APK archive which is not supported as a compilation dependency. File: C:\QingNiuProject\VideoModule\videoplayer\build\outputs\apk\videoplayer-release-unsigned.apk

 解决方案

 Android A项目以Module的形式引用B项目详细步骤、及常见问题和aar文件的引用

Android A项目以Module的形式引用B项目详细步骤、及常见问题和aar文件的引用

 

之后点击try again 重试  完美的Build 成功

运行项目的时候 又报错了

错误2:需要常量表达式

Android A项目以Module的形式引用B项目详细步骤、及常见问题和aar文件的引用

查看错误位置

Android A项目以Module的形式引用B项目详细步骤、及常见问题和aar文件的引用

 主要原因是因为原来module中的R文件是不会以final形式存在的,但是在module中的一些代码里对R中的数据使用了switch,switch必须使用final常量

 解决方案:存在是 Switch...case... 语句要更改为if... else...

 

错误3 Execution failed for task :app:processDebugManifest >Manifest merger failed with multiple errors

 Android A项目以Module的形式引用B项目详细步骤、及常见问题和aar文件的引用

 解决方案: 建议第三个

1. Manifest.xml文件里的application中加上tools:replace=android:icon,(Theme也冲突的就这么写:tools:replace=android:icon, android:theme)记得要在manifest跟标签加上xmlns:tools=http://schemas.android.com/tools

我就是用的这一种

2. build.gradle根标签上加上useOldManifestMerger true

3. 最直接方案此外将Module 清单文件中的application 内的内容移动到appmainifest中,以此避免一些错误

Android A项目以Module的形式引用B项目详细步骤、及常见问题和aar文件的引用

4. 其它办法https://www.jianshu.com/p/2a31f031bfda    Android studio Module依赖 出现Manifest Merge 冲突解决方案(没遇到 为了遇到的小伙伴准备的)

 

其他错误

1.Error:Execution failed for task ':app:transformClassesWithDexForDebug'.

> com.android.build.api.transform.TransformException: com.android.ide.common.process.ProcessException: java.util.concurrent.ExecutionException: com.android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 65536

 

解决方案:在主build.gradle中添加以下语句:

 android {

    compileSdkVersion 24

    buildToolsVersion "24.0.2"

    defaultConfig {

        applicationId "com.xxx.xxx"

        minSdkVersion 16

        targetSdkVersion 24

        versionCode 1

        versionName "1.0"

        multiDexEnabled true

    }


 2.Method put in org.json.JSONObject not mocked

 Android A项目以Module的形式引用B项目详细步骤、及常见问题和aar文件的引用 

解决方案

在对应modulegradle文件中的dependencies中加上这句:

testCompile 'org.json:json:20140107'

 

5. 在主module和其他module中都有继承Application的子类,并且注册了,出现冲突

解决方案

application继承Module 中的application   或者 将module中的application的内容复制到app application

 

 

 

 

此外我发现这个位置有红X,但是不影响正常运行 

Android A项目以Module的形式引用B项目详细步骤、及常见问题和aar文件的引用

查看错误码:

Element: class com.intellij.psi.impl.source.xml.XmlTagImpl because: parent is null

invalidated at: see attachment

com.intellij.psi.PsiInvalidElementAccessException: Element: class com.intellij.psi.impl.source.xml.XmlTagImpl because: parent is null

invalidated at: see attachment

 解决方案:

1.重启AndroidStudio

2.如果方法1不起作用,点击File——Invalidate Caches/Restart...

如果以上两种方案都不行  你可以 Module 拷贝出来  重新导入(亲测有效)

 

 

稳定版代码

 

当你的Module 不需要修改的时候 你可以直接引用

 Android A项目以Module的形式引用B项目详细步骤、及常见问题和aar文件的引用

aar的形式放在项目中引用

看到module层的outputs文件夹下生成了.aar文件,

 Android A项目以Module的形式引用B项目详细步骤、及常见问题和aar文件的引用

修改该.aar文件的后缀名为.zip,解压后,可以看到classes.jar文件

 Android A项目以Module的形式引用B项目详细步骤、及常见问题和aar文件的引用

module层的intermediates文件夹下,也生成了一个bundles文件夹,.jar文件也可以用这里生成的,这个就是生成的jar包

 Android A项目以Module的形式引用B项目详细步骤、及常见问题和aar文件的引用

 

 

 

步骤一:将aar文件copylibs目录

 

步骤二:在build.gradle中添加对应的代码

repositories {
    flatDir {
        dirs 'libs'
    }
}
dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:26.+'
    compile 'com.android.support.constraint:constraint-layout:1.0.2'
    testCompile 'junit:junit:4.12'
    compile(name: 'videoplayer-release', ext: 'aar')

}

步骤三:Sycn Now工程,如果能在build目录中找到对应的生成文件,说明成功了


--------------------------------------------------------------------------------------------------------------


Module   混淆

作用

1.增加Apk反编译之后代码泄露的困难性

2.生成的apk体积会缩小

 

所有子Module都不能配置混淆,即minifyEnabled true。如果需要,也只能在主Module中配置。

在主Module中配置了混淆,打包时会作用在所有的Module上,即其他的Module的代码也会被混淆。

所有Moduleres目录中的内容也会合并到主Moduleres对应目录和文件中。参考文章:http://blog.****.net/fesdgasdgasdg/article/details/78133821

所有被主Module直接或间接引用的子ModuleAndroidManifest.xml文件,在打包时内容都会合并到主ModuleAndroidManifest.xml文件中,

包括权限,注册的组件等

 

步骤一:在proguard-rules.pro 文件中加入以下

#指定代码的压缩级别
    -optimizationpasses 5

    #包明不混合大小写
    -dontusemixedcaseclassnames

    
#不去忽略非公共的库类
    -dontskipnonpubliclibraryclasses

     
#优化  不优化输入的类文件
    -dontoptimize

     
#预校验
    -dontpreverify

     
#混淆时是否记录日志
    -verbose

     
# 混淆时所采用的算法
    -optimizations !code/simplification/arithmetic,!field/*,!class/merging/*

    #保护注解
    -keepattributes *Annotation*
     #如果引用了v4或者v7包
        -dontwarn android.support.**
 #保持 native 方法不被混淆
    -keepclasseswithmembernames class * {
        native <methods>;
    }

    #保持自定义控件类不被混淆
    -keepclasseswithmembers class * {
        public <init>(android.content.Context, android.util.AttributeSet);
    }

    #保持自定义控件类不被混淆
    -keepclassmembers class * extends android.app.Activity {
       public void *(android.view.View);
    }

    #保持 Parcelable 不被混淆
    -keep class * implements android.os.Parcelable {
      public static final android.os.Parcelable$Creator *;
    }

    #保持 Serializable 不被混淆
    -keepnames class * implements java.io.Serializable

    #保持 Serializable 不被混淆并且enum 类也不被混淆
    -keepclassmembers class * implements java.io.Serializable {
        static final long serialVersionUID;
        private static final java.io.ObjectStreamField[] serialPersistentFields;
        !static !transient <fields>;
        !private <fields>;
        !private <methods>;
        private void writeObject(java.io.ObjectOutputStream);
        private void readObject(java.io.ObjectInputStream);
        java.lang.Object writeReplace();
        java.lang.Object readResolve();
    }

    #保持枚举 enum 类不被混淆 如果混淆报错,建议直接使用上面的 -keepclassmembers class * implements java.io.Serializable即可
    #-keepclassmembers enum * {
    #  public static **[] values();
    #  public static ** valueOf(java.lang.String);
    #}

    -keepclassmembers class * {
        public void *ButtonClicked(android.view.View);
    }

    #不混淆资源类
    -keepclassmembers class **.R$* {
        public static <fields>;
    }

    #避免混淆泛型 如果混淆报错建议关掉
    #–keepattributes Signature

 步骤二:在主APP的gradle内添加下面代码:

    buildTypes {
        release {
//            //签名
//            signingConfig signingConfigs.videoConfig
            //混淆
            minifyEnabled true
            //对齐
            zipAlignEnabled true

            //移除无用的resource 文件
            shrinkResources true

            //加载默认混淆配置文件
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

 可能会遇到的错误:

Error:Execution failed for task ':app:prepareVideoplayerReleaseLibrary'.

> Unable to unzip 'C:\QingNiuProject\VideoAarTest\app\libs\videoplayer-release.aar' to 'C:\Users\admin\.android\build-cache\c146c1e3524f82cd7200e3e649de0f97a4107d15\output'

 解决方案:重新替换Aar包即可解决


加QQ群:659014357 !!!  需要你们的支持,你们是我继续写作的动力,感谢。