GithubHelp home page GithubHelp logo

excludeaar's Introduction

用于过滤aar中冲突类(class)和so库的脚本,也可以用来过滤jar中冲突class

依赖:

allprojects {
  repositories {
       maven { url 'https://jitpack.io' }
    }
}
classpath 'com.github.ssiyy:ExcludeAar:v1.0.1'

使用方法

 apply plugin: 'exclude_plugin'

 excludePluginExt {
        aars {
            BaiduLBS_Android_debug { //过滤架包的名称
                implementation = false  //是否依赖过滤之后架包
                path "/libs/exclude/BaiduLBS_Android_debug.aar" //架包的路径
                excludePackages 'com.baidu.location' //过滤的包名
                excludeSos 'liblocSDK7b'
                excludeSoAbis 'x86'
            }
        }
        jars{
            BaiduLBS_Android_7_5_2{//过滤架包的名称
                path "/libs/exclude/BaiduLBS_Android_7.5.2.jar" //架包的路径
                excludePackages 'com.baidu.android','com.baidu.lbsapi' //过滤的包名
            }

            map_baidu{//过滤架包的名称
                path "/libs/exclude/map-baidu.jar"//架包的路径
                excludePackages "io.dcloud.js.map.adapter"//过滤的包名
                excludeClasses "io.dcloud.js.map.IFMapDispose","io.dcloud.js.map.JsMapCircle","io.dcloud.js.map.MapJsUtil"//过滤的类名
            }
        }
    }

注意:

配置完之后运行一下根据名称生成的过滤任务 gradle.png

属性解释

属性名 默认值 解释
path 无默认值(必要值) 路径
implementation true 是否依赖过滤之后的架包
excludePackages 空数组 需要过滤的包名
excludeClasses 空数组 需要过滤的类名(全类名,不要".class"结尾)
excludeSos 空数组 需要过滤的so名(不要".so"结尾,aar包特有)
excludeSoAbis 空数组 需要过滤的so abi

Demo截图

demo

demo1

可以看到图一中的百度包被过滤掉了

AAR包过滤冲突class和so库怎么实现

1,获取到需要过滤的原始AAR包

2,解压AAR包

3,解压AAR包中所包含的jar

4,删除解压AAR包中包含的jar

5,按照过滤规则对解压之后的class文件按重新打包(AAR的class文件过滤在这里实现的)

6,按照过滤规则重新打包成AAR包(AAR的SO文件过滤在这里实现的)

7,创建一个新的Configuration并且添加一个Artifact

8,在工程中引用过滤后的AAR

① 获取到需要过滤的原始AAR包

def getDefaultAar() {
    Configuration c = configurations.getByName("default")
    def files = c.artifacts.files.filter {
        it.name ==~ /.*\.aar/
    }

    def file = null
    if (!files.empty) {
        file = files[0]
    }
    return file
}

② 解压AAR包

/**
 * 解压getDefaultAar()返回的aar包
 */
task unZipAar(type: Copy) {
    from zipTree(getDefaultAar())
    into unZipAarFile
    //完成aar解压之后,设置unzipJar的from和deleteJars的delete
    doLast {
        Set<File> jarFiles = new HashSet<>()
        if (unZipAarFile.exists()) {
            unZipAarFile.traverse(type: groovy.io.FileType.FILES, nameFilter: ~/.*\.jar/) { file ->
                jarFiles.add(file)
            }
        }
        unzipJar.from(
                jarFiles.collect {
                    zipTree(it)
                }
        )
 
        deleteJars.delete(jarFiles)
    }
}

就是直接把aar包解压了,为什么可以解压aar包呢?因为“AAR文件的文件扩展名为 .aar,文件本身是一个强制性条目的zip文件”,详细解释请看这里

③ 解压AAR包中所包含的jar

/**
 * 注意:from 已经在上面的unZipAar设置了
 * 解压aar包中包含的jar包
 */
task unzipJar(type: Copy) {
    into unZipJarFile
}

为什么可以解压jar包呢?因为“JAR文件是一种归档文件,以ZIP格式构建,以.jar为文件扩展名”,详细解释请看这里

④ 删除解压之后的jars

/**
 *
 * 注意:from 已经在上面的unZipAar设置了
 * 删除解压之后的jars
 */
task deleteJars(type: Delete)

⑤ 按照过滤规则对解压的class.jar重新打包(这个是重点)

/**
 * 用Jar任务过滤并生成新的jar包
 */
task zipJar(type: Jar) {
    baseName = 'classes'
    from unZipJarFile
    destinationDir unZipAarFile
    exclude getExcludePackageRegex(excludePackages)
    exclude getExcludeClassRegex(excludeClasses)
}

这个步骤就是把之前解压的class文件,按照过滤规则用Jar重新打包成jar文件

⑥ 重新打包成AAR包

/**
 * 重新把文件压缩成新的aar包
 */
task excludeAar(type: Zip) {
    group 'Siy'
    description '生成一个过滤之后的aar包'
    baseName excludeAarName
    extension "aar"
    from unZipAarFile
    exclude getExcludeSoRegex(excludeSos)
    destinationDir excludeAarFile
}

这个步骤过滤so,并且重新打包 成aar文件

⑦ 创建一个新的Configuration并且添加一个Artifact

configurations.maybeCreate("exclude")
artifacts.add("exclude",excludeAar)

⑧ 在工程中引用过滤后的AAR

implementation project(path: ':xxx_aar', configuration: 'exclude')

过滤规则

//需要过滤的包名
String[] excludePackages = ['com.baidu']
//需要过滤的类(需要全类名,不需要.class结尾)
String[] excludeClasses = []
//需要过滤的so
String[] excludeSos = ['liblocSDK7b']

static String[] getExcludePackageRegex(String[] packages) {
    packages?.collect {
        it?.replace('.', '\\')?.plus("\\**")
    }
}

static String[] getExcludeClassRegex(String[] classes) {
    classes?.collect {
        it?.replace('.', '\\')?.plus(".class")
    }
}

static String[] getExcludeSoRegex(String[] sos) {
    sos?.collect {
        "**\\${it}.so"
    }
}

JAR包过滤冲突class包怎么实现

1,获取到需要过滤的原始JAR包

2,解压JAR包

3,按照过滤规则对解压的class文件重新打包

4,创建一个新的Configuration并且添加一个Artifact

5,在工程中引用过滤后的JAR

① 获取到需要过滤的原始JAR包

def getDefaultJar() {
      Configuration c = configurations.getByName("default")
      def files = c.artifacts.files.filter {
          it.name ==~ /.*\.jar/
      }
 
      def file = null
      if (!files.empty) {
          file = files[0]
      }
    return file
}

② 解压JAR包

/**
 * 解压getDefaultJar()返回的jar文件
 */
task unzipJar(type: Copy) {
    def zipFile = getDefaultJar()
    def outputDir = unZipJarFile
    from zipTree(zipFile)
    into outputDir
}

③ 按照过滤规则对解压的JAR重新打包

/**
 * 用Jar任务过滤并生成新的jar包
 */
task excludeJar(type: Jar) {
    group 'Siy'
    description '生成一个过滤之后的jar包'
 
    //需要打包的资源所在的路径集和
    from unZipJarFile
 
    //去除路径集下部分的资源
    exclude getExcludePackageRegex(excludePackages)
    exclude getExcludeClassRegex(excludeClasses)
 
    //整理输出的 Jar 文件后缀名
    extension = "jar"
 
    //最终的 Jar 文件名......如果没设置,默认为 [baseName]-[appendix]-[version]-[classifier].[extension]
    baseName = excludeJarName
 
    //生成jar包的路径
    destinationDir excludeJarFile
}

④ 创建一个新的Configuration并且添加一个Artifact

configurations.maybeCreate("siy_test")
artifacts.add("siy_test", zipJar)

⑤ 在工程中引用过滤后的JAR

implementation project(path: ':test_jar_exclude', configuration: 'siy_test')

过滤规则

//需要过滤的包名
def excludePackages = ['com.baidu']
//需要过滤的类(需要全类名)
def excludeClasses = []
 
static def getExcludePackageRegex(def packages) {
    packages?.collect {
        it?.replace('.', '\\')?.plus("\\**")
    }
}
 
static def getExcludeClassRegex(def classes) {
    classes?.collect {
        it?.replace('.', '\\')?.plus(".class")
    }
}

详细介绍请看这里

excludeaar's People

Contributors

ssiyy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

excludeaar's Issues

先自动化检测主module跟放在libs/exclude文件夹内的aar文件之间存在的冲突包名,然后再过滤那些冲突的包名,这种该怎么实现呢?

楼主你好,有个问题想请教下:目前这个开源库是要先在

`
excludePluginExt {
autoDependencies = true //是否自动依赖即是否依赖过滤之后的架包
aars {
BaiduLBS_Android_debug { //过滤架包的名称
path "/libs/exclude/BaiduLBS_Android_debug.aar" //架包的路径
excludePackages 'com.baidu.location' //过滤的包名
}
}
jars{
BaiduLBS_Android_7_5_2{//过滤架包的名称
path "/libs/exclude/BaiduLBS_Android_7.5.2.jar" //架包的路径
excludePackages 'com.baidu.android','com.baidu.lbsapi' //过滤的包名
}

        map_baidu{//过滤架包的名称
            path "/libs/exclude/map-baidu.jar"//架包的路径
            excludePackages "io.dcloud.js.map.adapter"//过滤的包名
            excludeClasses "io.dcloud.js.map.IFMapDispose","io.dcloud.js.map.JsMapCircle","io.dcloud.js.map.MapJsUtil"//过滤的类名
        }
    }
}

`

这里声明要过滤的包名啥的,然后再执行指定的Task。如果要实现:先自动化检测主module跟放在libs/exclude文件夹内的aar文件之间存在的冲突包名,然后再过滤那些冲突的包名,这种该怎么实现呢?

路径文件不存在

Execution failed for task ':unzipJar_SystemUISharedLib'.

Cannot expand ZIP '/libs/SystemUISharedLib.jar' as it does not exist.
跑了demo也是这样 是不能用了吗

执行任务报错

Task :app:unZip_aar_DSAR_SDK
Execution optimizations have been disabled for task ':app:unZip_aar_DSAR_SDK' to ensure correctness due to the following reasons:

报错 Cannot add task 'unZip_jar_libchips' as a task with that name already exists.

报错 Cannot add task 'unZip_jar_libchips' as a task with that name already exists.

excludePluginExt {
aars {
BaiduLBS_Android_debug { //过滤架包的名称
implementation = false
path = "/libs/excludes/BaiduLBS_Android_debug.aar" //架包的路径
// excludeClasses 'com.example.library.BaiduLocationService'
excludePackages = ['com.baidu.android', 'com.baidu.lbsapi']
// excludeSos 'liblocSDK7b'
// excludeSoAbis 'x86'
}
}

jars{

// android_opt_datetimepicker{//过滤架包的名称
// path = "/libs/android-opt-datetimepicker.jar" //架包的路径
// excludePackages "android","androidx" //过滤的包名
// }
libchips{//过滤架包的名称
path = "/libs/excludes/libchips.jar"//架包的路径
excludePackages 'android.arch','android.support','androidx'//过滤的包名
// excludeClasses "io.dcloud.js.map.IFMapDispose","io.dcloud.js.map.JsMapCircle","io.dcloud.js.map.MapJsUtil"//过滤的类名
}
}
}

aar的使用方式是否需要修改

作者你好:

如果按照github项目中的方式来处理,那集成aar的方式就需要修改了吧,需要给每一个aar指定一个特定的configuration是么?感觉这样有点麻烦

能否直接根据aar的name来获取到aar文件路径呢?

构建时合并AndroidManifest.xml出现org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; 前言中不允许有内容

 Exception is:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:processDevDebugManifest'.
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:103)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:73)
    ........  
Caused by: java.lang.RuntimeException: com.android.manifmerger.ManifestMerger2$MergeFailureException: org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; 前言中不允许有内容。
        at com.android.builder.core.AndroidBuilder.mergeManifestsForApplication(AndroidBuilder.java:548)
        at com.android.build.gradle.tasks.MergeManifests.doFullTaskAction(MergeManifests.java:173)
        at com.android.build.gradle.internal.tasks.IncrementalTask.taskAction(IncrementalTask.java:106)
        at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:73)
        at org.gradle.api.internal.project.taskfactory.IncrementalTaskAction.doExecute(IncrementalTaskAction.java:50)
        ... 104 more
Caused by: com.android.manifmerger.ManifestMerger2$MergeFailureException: org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; 前言中不允许有内容。
        at com.android.manifmerger.ManifestMerger2.loadLibraries(ManifestMerger2.java:965)
        at com.android.manifmerger.ManifestMerger2.merge(ManifestMerger2.java:165)
        at com.android.manifmerger.ManifestMerger2.access$600(ManifestMerger2.java:61)
        at com.android.manifmerger.ManifestMerger2$Invoker.merge(ManifestMerger2.java:1542)
        at com.android.builder.core.AndroidBuilder.mergeManifestsForApplication(AndroidBuilder.java:508)
        ... 117 more
Caused by: org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; 前言中不允许有内容。
      
        at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:203)
        at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(ErrorHandlerWrapper.java:177)
        at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:400)
        at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:327)
        at com.sun.org.apache.xerces.internal.impl.XMLScanner.reportFatalError(XMLScanner.java:1437)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:999)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:606)
        at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:118)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:510)
        at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:848)
        at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:777)
        at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
        at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213)
        at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:643)
        at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl.parse(SAXParserImpl.java:327)
        at com.android.utils.PositionXmlParser.parse(PositionXmlParser.java:176)
        at com.android.utils.PositionXmlParser.parse(PositionXmlParser.java:139)
...

去除class的目的达到了,但是依赖之后无法正确构建打包

执行任务后,aar里面要过滤的包名是没看到了,但是点击as “运行”按钮,出现:Duplicate class cn.sirius.nga.BuildConfig found in modules jetified-exclude_GDTSDK_unionNormal-runtime.jar (exclude_GDTSDK_unionNormal.aar) and jetified-XXX_sdk_v3.1.0-runtime.jar (:XXX_sdk_v3.1.0:)

作者你好,我集成了你的开源库,执行任务后,aar里面要过滤的包名是没看到了,但是点击as “运行”按钮,出现:Duplicate class cn.sirius.nga.BuildConfig found in modules jetified-exclude_GDTSDK_unionNormal-runtime.jar (exclude_GDTSDK_unionNormal.aar) and jetified-XXX_sdk_v3.1.0-runtime.jar (:XXX_sdk_v3.1.0:)

image

请问下如果不想使用NamedDomainObjectContainer

excludePluginExt {
        aars {
            BaiduLBS_Android_debug { //过滤架包的名称
                implementation = false  //是否依赖过滤之后架包
                path "/libs/exclude/BaiduLBS_Android_debug.aar" //架包的路径
                excludePackages 'com.baidu.location' //过滤的包名
                excludeSos 'liblocSDK7b'
                excludeSoAbis 'x86'
            }
        }
        jars{
            BaiduLBS_Android_7_5_2{//过滤架包的名称
                path "/libs/exclude/BaiduLBS_Android_7.5.2.jar" //架包的路径
                excludePackages 'com.baidu.android','com.baidu.lbsapi' //过滤的包名
            }

            map_baidu{//过滤架包的名称
                path "/libs/exclude/map-baidu.jar"//架包的路径
                excludePackages "io.dcloud.js.map.adapter"//过滤的包名
                excludeClasses "io.dcloud.js.map.IFMapDispose","io.dcloud.js.map.JsMapCircle","io.dcloud.js.map.MapJsUtil"//过滤的类名
            }
        }
    }

如果想改成

excludePluginExt {
        aars {
        
                implementation = false  //是否依赖过滤之后架包
                path "/libs/exclude/BaiduLBS_Android_debug.aar" //架包的路径
                excludePackages 'com.baidu.location' //过滤的包名
                excludeSos 'liblocSDK7b'
                excludeSoAbis 'x86'
         
        }
}

这样的话,应该就不需要NamedDomainObjectContainer<>了吧?请问下应该怎么写这种

编译不过

ERROR: Unable to resolve dependency for ':exclude-demo@debug/compileClasspath': Failed to transform file 'exclude_BaiduLBS_Android_debug.aar' to match attributes {artifactType=jar}

请问一下大佬,java.lang.NoClassDefFoundError 该怎么办

我通过在dependence里面增加这样的配置,剔除掉了重复的部分:


    excludePluginExt {
        autoDependencies = true
        aars {
            "VGame-Core-1220" {
                path "/libs/exclude/VGame-Core-1220.aar"
                excludePackages 'com.ss.android.a', 'com.ss.android.download', 'com.ss.android.downloadad', 'com.ss.android.downloadlib', 'com.ss.android.socialbase'
            }
        }
    }

然后编译成功了,运行时候失败,请问有什么办法可以搞定呢?

java.lang.NoClassDefFoundError: Failed resolution of: Lcom/ss/android/downloadlib/addownload/GlobalInfo;
        at com.ss.union.game.sdk.common.download.GameDownloadManager.doInit(SourceFile:154)
        at com.ss.union.game.sdk.core.base.init.GameSdkCoreInit.init(SourceFile:69)
        at com.ss.union.game.sdk.core.base.init.a.f.doIt(SourceFile:17)

需要导出为aar的library中需要导入另外的aar,应该如何配置?

现在有个比较特殊的需求,A.aar是放在library B中的,然后需要library B打包成B.aar给主项目用。要求A.aar的代码被flat到B中,而不是主项目直接引用A.aar。A.aar中有个so需要被去除,因为和主项目冲突了。
我使用demo的方法,去除倒的确是去除了,但是使用assembleRelease生成的B.aar里面代码结构很奇怪,主class.jar里面压缩了另外一个class.jar,里面就是A的代码。
image
导入时便会class not found了。
这个怎么解决呢?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.