In project development, with the growth of business, it is often necessary to make some custom modifications to package code or resources during apK compilation, such as hot fix, plug-in generation, non-buried point statistics, channel package generation and so on.

But the company project business developers are basically rarely exposed to the relevant technology, here to learn the attitude, to implement a set of 7ZIP compression apK resource file Gradle plug-in.

APK thin combat resources custom 7Z compression

APK slim in the industry has a lot of mature open source technology to reflect the solution, such as Meituan Android App package slim optimization practice in detail in this blog. Here we start from resource compression, using 7z tools, to achieve a set of their own resource compression Gradle plug-in.

A brief introduction to Gradle plug-ins

Generally, simple logic can be written in a build.gradle file, but for ease of management and reuse, the plug-in can be isolated as a project. After compiling the independent Gradle plugin, we can publish it to the local Maven repository or jCenter for reference by other projects.

Introduction to project Structure

Gradle plug-ins can be developed using Android Studio or IntelliJ. AS development requires you to create your own plug-in project structure, while IntelliJ can automatically generate the project structure, but some operations are not easy to use.

As shown in the figure below, we use IntelliJ New to create a project and boot it to generate our initial project structure and gradle-wrapper.

The standard project structure is as follows:

If you are developing with as, you need to create the above structure manually. As you can see from the project, it supports both Groovy and Java, and of course from IntelliJ creating the project boot, it also supports Kotlin. Each language has its own language characteristics. For example, we develop Gradle plug-in, develop in Groovy where we interact with project build and compile, and develop the core code of business in the language we are good at (Java). Here, we use 7zip to implement with Java encapsulation.

The resources folder is important because the files in this folder indicate the entry to the plug-in and the name of the plug-in reference. If you export the Maven library and cannot find your own plug-in reference, you can first check that the file structure is correct.

apk-shrink.properties

implementation-class=win.canking.gradle.ShrinkPlugin
Copy the code
Apply the plugin 'apk - the shrinkCopy the code

When build. Gradle parsing the apply plugin, will find win. Canking. Gradle. ShrinkPlugin, start executing the apply * * * * method ()

Possible problems with the project

1, publish local Maven, build. Gradle configuration as follows

apply plugin: 'groovy'
apply plugin: 'java'
apply plugin: 'maven'

group 'win.canking.gradle'
version '1.0.1'
archivesBaseName = 'apk-shrink'//ArtifactId defaults to project module name compileGroovy {sourceCompatibility = 1.7
    targetCompatibility = 1.7
    options.encoding = "UTF-8"
}

dependencies {
    compile gradleApi()
    compile localGroovy()
    compile 'com. Android. Tools. Build: gradle: 2.1.0'} uploadArchives {repositories. The mavenDeployer {/ / documents released to the following directory repository (url: uri ('.. /.. /ChargeHelperPro/gradleplugin/'))}}Copy the code

Execute the following code to generate a local Maven library

gradlew -p {module name} clean build uploadArchives --info
Copy the code

2, different JDK compilation issues, pay special attention, need to configure sourceCompatibility

Check the export directory to see if maven has been generated. The directory structure is as follows:

Decompile the generated JAR package to see if the packaging is correct.

APK User-defined resource compression

APK package structure

An APK file is essentially a ZIP file that can be decompressed using a decompression tool to see the internal structure.

name desp
res Resource file, where the resources are mapped to the project R file, generating the reference ID
assets Static resource files are accessed using AssetManager
lib Third package JAR or native SO library
META-INF Signature information, cert.rsa cert.sf manifrst.mf
AndroidManifest Project manifest file, including four components, package information, permissions, etc
classes.dex Java class file is an Android execution file generated by the DX tool
resources.arsc A compiled binary resource file that contains code references to resources

Resource file compression

aapt l -v xxx.apk
Copy the code

It can be seen from the figure that some resource files in APK are stored and in an uncompressed state. We can reprocess APK and compress files with a tool of high compression ratio (7zip) to achieve the purpose of slim down.

Obtain the 7zip tool path

To obtain the 7zip tool directory on the PC, run “which 7za”

        ProcessBuilder pb = new ProcessBuilder(new String[]{"which"."7za"});
        String sevenZipPath = "";
	try {
            Process process = pb.start();
            InputStreamReader ir = new InputStreamReader(process.getInputStream());
            LineNumberReader input = new LineNumberReader(ir);
            String tmp;
            while((tmp = input.readLine()) ! = null) {if (tmp.endsWith(File.separator + "7za")) {
                    sevenZipPath = tmp;
                    Log.a("Shrink"."7zip path:" + sevenZipPath);
                }
            }
            process.waitFor();
            process.destroy();
        } catch (Exception e) {
            Log.e("Error"."no shrink" + e.getMessage());
            return;
        }
Copy the code

Define the type of file to compress:

 public class CompressInfo {
    public Set<String> compressFilesPattern;

    private CompressInfo() {
        this.compressFilesPattern = new HashSet<>();
    }

    public static CompressInfo init() {
        CompressInfo info = new CompressInfo();
        info.compressFilesPattern.add(".png");
        info.compressFilesPattern.add(".jpg");
        info.compressFilesPattern.add(".JPG");
        info.compressFilesPattern.add(".jpeg");
        info.compressFilesPattern.add(".gif");
        info.compressFilesPattern.add(".arsc");
        returninfo; }}Copy the code

Call 7za to compress the object file

    private static void do7zip(String srcDirPath, String outZipPath, String sevenZipPath)
            throws IOException, InterruptedException {
        String srcFilesPath = new File(srcDirPath).getAbsolutePath() + File.separator + "*";
        outZipPath = new File(outZipPath).getAbsolutePath();

        ProcessBuilder pb = new ProcessBuilder(new String[]{sevenZipPath, "a"."-tzip", outZipPath, srcFilesPath, "-mx9"});
        Process process = pb.start();

        InputStreamReader ir = new InputStreamReader(process.getInputStream());
        LineNumberReader input = new LineNumberReader(ir);
        String line;
        while((line = input.readLine()) ! = null) { Log.d(input.getLineNumber() +":" + line);
        }
        process.waitFor();
        process.destroy();
    }
Copy the code

Specify task to perform the compression task

    @Override
    void apply(Project project) {
        Log.d("shrink apply")
        if (project.getPlugins().hasPlugin(AppPlugin)) {

            def config = project.extensions.create(SHRINK_CONFIG, ShrinkExtension)
            project.afterEvaluate {
                project.tasks.matching {
                    println it.name
                    it.name.startsWith('packageRelease')
                } each {
                    t ->
                        t.doLast {
                            if (config.enable) {
                                Log.d("shrink start...")
                                GradleMrg.do7zipCompressApk(config.apkPath)
                                Log.d("shrink EDN")}}}}}}Copy the code

Note: This Demo depends on the compilation process of the project, so you need to configure related compression parameters in your own project build.gradle:

shrinkConfig {
    enable = true
    apkPath = '/PATH/App-release.apk'// Can be automatically obtained by the code method}Copy the code

You can also customize a separate task that does not depend on the compile process.

Compression effect comparison:

This case source code to submit to GitHub, welcome to exchange learning and star.


Welcome to reprint, please indicate the source: Changxing E station Canking.win