美文网首页
如何实现provided AAR?如何实现Jar依赖AAR

如何实现provided AAR?如何实现Jar依赖AAR

作者: SMSM | 来源:发表于2018-03-18 23:25 被阅读489次

    其实实现思路是简简单单的,就是对AAR剥皮提取其中的classes.jar。直接provided其中的jar即可。
    第二个问题,如何Jar依赖AAR也是一样的道理,比如我们要对一组接口打成一个Jar包,但是接口的入参用到了Fragment,不好意思,编译失败,因为找不到Fragment
    解决方案
    1、获取依赖项对应的AAR地址,通过新增compile的方式对使用者提供入口。
    2、extractAarTransform:把AAR拆开提前其中的jar到指定目录,。
    3、aarTransform:过滤出所有的Jar文件,并输出。

    可悲的是,在Gradle2版本上原生的ExtractAarTransform运行失效,未执行transform方法。没办法只能自己手动调用了。

    源码如下:

    import com.android.utils.FileUtils
    import com.google.common.collect.ImmutableList
    import com.google.common.collect.Lists
    import com.google.common.io.ByteStreams
    import com.google.common.io.Files
    import org.gradle.api.artifacts.transform.ArtifactTransform
    
    import javax.inject.Inject
    import java.util.jar.JarOutputStream
    import java.util.jar.Manifest
    import java.util.regex.Pattern
    import java.util.zip.ZipEntry
    import java.util.zip.ZipInputStream
    
    apply plugin: 'java-library'
    apply plugin: MyPlugin
    
    def SUPPORT_LIBS_VERSION = '25.1.1'
    def targetSdkVersion = 19
    def cachePath = "build/pitaya-caches/aar2jar"
    
    public class MyPlugin implements Plugin<Project> {
       @Override
       void apply(Project project) {
    
           project.getConfigurations().create("AARCompile", new Action<Configuration>() {
               @Override
               public void execute(Configuration config) {
    
               }
           })
       }
    }
    
    
    sourceCompatibility = "1.7"
    targetCompatibility = "1.7"
    
    
    sourceSets {
       main {
           java.srcDirs = ['src/main/java/']
       }
    }
    
    dependencies {
       /*
         Android Jar
        */
       Properties properties = new Properties()
       properties.load(project.rootProject.file('local.properties').newDataInputStream())
       def sdkDir = properties.getProperty('sdk.dir')
    
       if (isGradle3()) {
           compileOnly files("${sdkDir}/platforms/android-${targetSdkVersion}/android.jar")
       } else {
           project.dependencies.add("compileOnly", files("${sdkDir}/platforms/android-${targetSdkVersion}/android.jar"))
       }
    
       AARCompile "com.android.support:appcompat-v7:$SUPPORT_LIBS_VERSION"
       AARCompile "com.android.support:recyclerview-v7:$SUPPORT_LIBS_VERSION"
    
       ExtractAarTransform extractAarTransform = new ExtractAarTransform()
       extractAarTransform.setOutputDirectory(new File(project.rootDir, cachePath))
       AarTransform aarTransform = new AarTransform()
       List<File> fileList = Lists.newArrayList()
    
       configurations.AARCompile.files.collect {
           if (it.absolutePath.endsWith(".jar")) {
               fileList.add(it.absoluteFile)
    
               compileOnly project.files(it.absolutePath)
    
               System.out.println("From AARCompile **===> " + it.absolutePath)
               return
           }
    
           List<File> tempRoot = extractAarTransform.transform(it.absoluteFile)
           List<File> tempAAR2JarFile = aarTransform.transform(tempRoot.get(0))
    
           if (isGradle3()) {
               compileOnly project.files(tempAAR2JarFile.toArray())
           } else {
               project.dependencies.add("compileOnly", project.files(tempAAR2JarFile.toArray()))
           }
    
    
           fileList.add(tempAAR2JarFile)
           System.out.println("From AARCompile AAR2JarFiles ===> " + tempAAR2JarFile.toArray())
           System.out.println("From AARCompile ===> " + it.absolutePath)
       }
    }
    
    
    public class ExtractAarTransform extends ArtifactTransform {
       private static final String LIBS_PREFIX = "libs/";
       private static final int LIBS_PREFIX_LENGTH = "libs/".length();
       private static final int JARS_PREFIX_LENGTH = "jars".length() + 1;
    
       @Inject
       public ExtractAarTransform() {
       }
    
       public List<File> transform(File input) {
           //TODO 1
           File outputDir = new File(this.getOutputDirectory(), input.name);
           FileUtils.mkdirs(outputDir);
    
           StringBuilder sb = new StringBuilder(20);
           sb.append("jars").append(File.separatorChar);
    
           try {
               InputStream fis = new BufferedInputStream(new FileInputStream(input));
               Throwable var5 = null;
    
               try {
                   ZipInputStream zis = new ZipInputStream(fis);
                   Throwable var7 = null;
    
                   try {
                       ZipEntry entry;
                       try {
                           while ((entry = zis.getNextEntry()) != null) {
                               try {
                                   String name = entry.getName();
                                   if (!entry.isDirectory()) {
                                       //TODO 2
                                       String path = name;
                                       if (!name.equals("classes.jar")) {
                                           continue
                                       }
    
                                       if (!name.equals("classes.jar") && !name.equals("lint.jar")) {
                                           if (name.startsWith("libs/")) {
                                               sb.setLength(JARS_PREFIX_LENGTH);
                                               String path2 = name.substring(LIBS_PREFIX_LENGTH);
                                               if ("classes.jar".equals(path2)) {
                                                   sb.append("libs/").append("classes-2.jar");
                                               } else if ("lint.jar".equals(path2)) {
                                                   sb.append("libs/").append("lint-2.jar");
                                               } else {
                                                   sb.append("libs/").append(path2);
                                               }
    
                                               path = sb.toString();
                                           }
                                       } else {
                                           sb.setLength(JARS_PREFIX_LENGTH);
                                           sb.append(name);
                                           path = sb.toString();
                                       }
    
                                       File outputFile = new File(outputDir, path.replace("/".chars[0], File.separatorChar));
                                       FileUtils.mkdirs(outputFile.getParentFile());
                                       OutputStream outputStream = new BufferedOutputStream(new FileOutputStream(outputFile));
                                       Throwable var13 = null;
    
                                       try {
                                           ByteStreams.copy(zis, outputStream);
                                           outputStream.flush();
                                       } catch (Throwable var81) {
                                           var13 = var81;
                                           throw var81;
                                       } finally {
                                           if (outputStream != null) {
                                               if (var13 != null) {
                                                   try {
                                                       outputStream.close();
                                                   } catch (Throwable var79) {
                                                       var13.addSuppressed(var79);
                                                   }
                                               } else {
                                                   outputStream.close();
                                               }
                                           }
    
                                       }
                                   }
                               } finally {
                                   zis.closeEntry();
                               }
                           }
                       } catch (Throwable var84) {
                           var7 = var84;
                           throw var84;
                       }
                   } finally {
                       if (zis != null) {
                           if (var7 != null) {
                               try {
                                   zis.close();
                               } catch (Throwable var78) {
                                   var7.addSuppressed(var78);
                               }
                           } else {
                               zis.close();
                           }
                       }
    
                   }
               } catch (Throwable var86) {
                   var5 = var86;
                   throw var86;
               } finally {
                   if (fis != null) {
                       if (var5 != null) {
                           try {
                               fis.close();
                           } catch (Throwable var77) {
                               var5.addSuppressed(var77);
                           }
                       } else {
                           fis.close();
                       }
                   }
    
               }
           } catch (Throwable var88) {
               throw new RuntimeException(var88);
           }
    
           File classesJar = new File(new File(outputDir, "jars"), "classes.jar");
           if (!classesJar.exists()) {
               try {
                   Files.createParentDirs(classesJar);
                   JarOutputStream jarOutputStream = new JarOutputStream(new BufferedOutputStream(new FileOutputStream(classesJar)), new Manifest());
                   jarOutputStream.close();
               } catch (IOException var80) {
                   throw new RuntimeException("Cannot create missing classes.jar", var80);
               }
           }
    
           return ImmutableList.of(outputDir);
       }
    }
    
    public class AarTransform extends ArtifactTransform {
    
       @Inject
       public AarTransform() {
       }
    
       public List<File> transform(File input) {
           return getJars(input);
       }
    
       private static List<File> getJars(File explodedAar) {
           List<File> files = Lists.newArrayList();
           File jarFolder = new File(explodedAar, "jars");
    
           File file = FileUtils.join(jarFolder, "classes.jar");
    
           if (file.isFile()) {
               files.add(file);
           }
    
           File localJarFolder = new File(jarFolder, "libs");
           File[] jars = localJarFolder.listFiles(new FilenameFilter() {
               @Override
               boolean accept(File dir, String name) {
                   return name.endsWith(".jar");
               }
           });
           if (jars != null) {
               files.addAll(Arrays.asList(jars));
           }
    
           return files;
       }
    }
    
    private boolean isGradle3() {
       Pattern GRADLE_ACCEPTABLE_VERSIONS = Pattern.compile("4\\.\\d*|0\\.\\d*[1-9]\\d*\$")
       if (GRADLE_ACCEPTABLE_VERSIONS.matcher(project.getGradle().getGradleVersion()).matches()) {
           return true
       }
       return false
    }
    
    

    相关文章

      网友评论

          本文标题:如何实现provided AAR?如何实现Jar依赖AAR

          本文链接:https://www.haomeiwen.com/subject/yzoyqftx.html