Gradle カスタム プラグイン 360 の強化

以前に公開された記事: Gradle Custom Plugin で APK を Dandelion にアップロードするカスタム プラグインの機能をいくつか教えてください。

一般的に、リリースするときは、APK を強化する必要があります。結局のところ、その方が安全です。ここでは、以前のプラグインを組み合わせて、APK を強化するタスクを定義します。それでは、もう少し自動化してみましょう。梱包→強化→ダンディリオンをアップロード

これは自動展開であるため、グラフィカルな強化操作ツールを使用してはなりません。

手順:

1. 360 強化セキュリティをダウンロード

強化中なので、まず 360 公式 Web サイトに登録し、強化保護をダウンロードする必要があります:公式 Web サイト(Tencent の強化は APK のローカル アップロードをサポートしていないようです)。

ディレクトリを解凍します
ここに画像の説明を挿入
。ここでは、コマンド ラインから jiagu.jar を実行して、APK の自動強化を完了する必要があります。

help.txt には強化されたコマンドがいくつかあります。興味があれば、すべて試してみることができます。

360 度の補強が完了したら、補強タスクの作成を開始します。

2. 強化されたタスクタスクを作成する

強化タスクの作成はタスクのアップロードと同じで、DefaultTaskを継承し、メソッドに @TaskAction アノテーションを付けることでタスクが実行されます。

強化タスクを作成するには、主に次のことを行います。

  • 1. 強化タスク用のグループを設定し、アップロード タスクと同じグループに入れます。

  • 2. 強化に必要なパラメータ(例: 強化された jar パッケージ ファイル、アカウントのパスワード、署名情報、強化前の APK、強化後のパスなど) を保存する Model クラスを作成します。
  • 3. ハードニングを行う際にModelクラスのパラメータ情報を取得する

  • 4.ログイン、署名のインポート、補強、自動署名の設定など、360 補強に必要なコマンドを実行します。

public class ReinforceTask extends DefaultTask {

    private BaseVariant mVariant;
    private Project mTargetProject;

    //加固相关的信息
    public static class ReinforceModel {

        //加固包的位置(jiagu.jar) 及登录账号密码
        public File reinforceJarFile;
        public String reinforceUsername;
        public String reinforcePassword;

        //签名文件 密码等信息
        public File signStoreFile;
        public String signPassword;
        public String signKeyAlias;
        public String signKeyPassword;

        //打包apk路径及加固后apk的路径
        public File inputApkFile;
        public File outputApkFile;
    }


    public void init(BaseVariant variant, Project project) {
        this.mVariant = variant;
        this.mTargetProject = project;
        setDescription("reinforce for apk");
        setGroup(TestJavaPlugin.PLUGIN_EXTENSION_NAME);
    }

    @TaskAction
    public void reinforceApk() {
        System.out.println("==============start JiaGu");

        ReinforceModel request = initReinforceModel();

        String loginCmdData = "java -jar %s -login %s %s";
        String loginExec = String
            .format(loginCmdData, request.reinforceJarFile, request.reinforceUsername,
                request.reinforcePassword);
        String loginMessage = exec(loginExec);
        System.out.println("==========exe JiaGu Result: " + loginMessage);

        String signCmdData = "java -jar %s -importsign %s %s %s %s";
        String signExec = String
            .format(signCmdData, request.reinforceJarFile, request.signStoreFile,
                request.signPassword,
                request.signKeyAlias, request.signKeyPassword);
        //导入签名
        String signResult = exec(signExec);
        System.out.println("===========exe JiaGu Sign Result: " + signResult);
        //自动签名
        String suffixCmd = " -autosign ";

        if (!request.outputApkFile.exists()) {
            request.outputApkFile.mkdirs();
        }
        //jiagu.jar ,input apk file path, output apk dir
        String reinforceCmdData = "java -jar %s -jiagu %s %s";
        String reinforceExec = String
            .format(reinforceCmdData, request.reinforceJarFile, request.inputApkFile,
                request.outputApkFile);
        //reinforce
        String jiaguResult = exec(reinforceExec + suffixCmd);

        System.out.println("=========exe APK JiaGu Result : " + jiaguResult);
    }

    @NotNull
    private ReinforceModel initReinforceModel() {
        Extension extension = Extension.getConfig(mTargetProject);

        ReinforceModel request = new ReinforceModel();
        request.outputApkFile = extension.outputFile;
        request.reinforceJarFile = extension.reinforceJarFile;
        request.reinforceUsername = extension.reinforceUsername;
        request.reinforcePassword = extension.reinforcePassword;

        NamedDomainObjectContainer<SigningConfig> signingConfigs = ((AppExtension) mTargetProject
            .getExtensions().findByName(TestJavaPlugin.ANDROID_EXTENSION_NAME)).getSigningConfigs();

        if (signingConfigs == null) {
            throw new IllegalArgumentException("please config your sign info.");
        }

        for (SigningConfig config : signingConfigs) {
            request.signStoreFile = config.getStoreFile();
            request.signPassword = config.getStorePassword();
            request.signKeyAlias = config.getKeyAlias();
            request.signKeyPassword = config.getKeyPassword();
        }

        for (BaseVariantOutput output : mVariant.getOutputs()) {
            request.inputApkFile = output.getOutputFile();
            if (request.inputApkFile == null || !request.inputApkFile.exists()) {
                throw new GradleException("apk file is not exist!");
            }
        }

        if (request.signStoreFile == null || !request.signStoreFile.exists()) {
            throw new IllegalArgumentException("please config your sign info.");
        }
        return request;
    }

    private String exec(String command) {
        StringBuilder resultBuilder = new StringBuilder();
        Process pro = null;
        BufferedReader input = null;
        Runtime runTime = Runtime.getRuntime();
        if (runTime == null) {
            throw new NullPointerException("reinforce task failed,Runtime is null");
        }
        try {
            pro = runTime.exec(command);
            input = new BufferedReader(new InputStreamReader(pro.getInputStream()));
            String line;
            while ((line = input.readLine()) != null) {
                resultBuilder.append(line).append("\n");
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            if (pro != null) {
                pro.destroy();
            }
            if (input != null) {
                try {
                    input.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return resultBuilder.toString();
    }
}

ここで次のことがわかります。

1. ReinforceModel を使用して、補強に必要なパラメータ情報を保存します。2.初期化 init() メソッドで
グループ 3 を設定し、initReinforceModel() メソッドで、強化に必要な口座番号、署名、その他の情報を取得します。4. reinforceApk() メソッドを通じて、ログイン、署名のインポート、強化、自動署名のコマンドがそれぞれ実行されます。

この時点で、カスタム強化タスクは完了です。

次に、先ほどのDandelion タスクへの自動アップロードを組み合わせて、パッケージ化-強化-アップロードのプロセスを実現します。

3. プラグインの拡張子を変更する

パッケージ化、強化、アップロードのプロセスを完了するには、前の記事の Extension クラスを変更し、360 度の強化に必要なパラメーターを追加して、強化タスクを確実に完了できるようにする必要があります。


public class Extension {


  public String uKey;
  public String apiKey;
  public String appName;

  //==========加固相关的信息
	//指向加固的jar包
  public File reinforceJarFile;
  //登陆用户名
  public String reinforceUsername;
  //登陆密码
  public String reinforcePassword;
  //输出apk的目录
  public File outputFile;

  public Extension() {
  }

  public Extension(String uKey, String apiKey, String appName, File reinforceJarFile,
      String reinforceUsername, String reinforcePassword, File outputFile) {
    this.uKey = uKey;
    this.apiKey = apiKey;
    this.appName = appName;
    this.reinforceJarFile = reinforceJarFile;
    this.reinforceUsername = reinforceUsername;
    this.reinforcePassword = reinforcePassword;
    this.outputFile = outputFile;
  }
  public Extension(String appName, String uKey, String apiKey) {
    this.uKey = uKey;
    this.apiKey = apiKey;
    this.appName = appName;
  }
  public static Extension getConfig(Project project) {
    Extension extension = project.getExtensions().findByType(Extension.class);
    if (extension == null) {
      extension = new Extension();
    }
    return extension;
  }

}


ここでは、強化された jar パッケージ ファイル、ユーザー名、パスワード、強化された APK パスのみを追加し、署名情報などは追加していないことがわかります。これらのパラメータはシステム拡張によって取得できるためです。

強化された apk パスを追加することは、後で Dandelion にアップロードするときに強化されたパッケージを変更することです。それ以外の場合、アップロードされたパッケージは、強化される前のパッケージのままです。

4. アップロードタスクのapkパスを変更する

以前にアップロードされたタスクは、直接取得されたシステム パッケージ化パスです。強化後に入力された apk パスに変更する必要があります。


public class PGYUploadTask extends DefaultTask {

  private BaseVariant mVariant;
  private Project mTargetProject;

  public static class PGYRequest {

    public String uKey;
    public String apiKey;
    //1,install by public 2,install by password 3,install by invite
    public String installType;
  }

  public void init(BaseVariant variant, Project project) {
    this.mVariant = variant;
    this.mTargetProject = project;
    setDescription("upload to pgy");
    setGroup(TestJavaPlugin.PLUGIN_EXTENSION_NAME);
  }

  @TaskAction
  public void uploadToPGY() {
    Extension extension = Extension.getConfig(mTargetProject);

    PGYRequest request = new PGYRequest();
    request.apiKey = extension.apiKey;
    request.uKey = extension.uKey;
    File apkDir = extension.outputFile;
    if (apkDir == null || !apkDir.exists()) {
      upload(request);
    } else {
      File[] files = apkDir.listFiles();
      if (files != null && files.length > 0) {
        upload(request.uKey, request.apiKey, files[0]);
      }else{
        upload(request);
      }
    }

//    for (BaseVariantOutput output : mVariant.getOutputs()) {
//      File file = output.getOutputFile();
//      if (file == null || !file.exists()) {
//        throw new GradleException("apk file is not exist!");
//      }
//      Extension extension = Extension.getConfig(mTargetProject);
//
//      PGYRequest request = new PGYRequest();
//      request.apiKey = extension.apiKey;
//      request.uKey = extension.uKey;
//      upload(request.uKey, request.apiKey, file);
//    }

  }

  private void upload(PGYRequest request) {
    for (BaseVariantOutput output : mVariant.getOutputs()) {
      File file = output.getOutputFile();
      if (file == null || !file.exists()) {
        throw new GradleException("apk file is not exist!");
      }
      upload(request.uKey, request.apiKey, file);
    }
  }

  private void upload(String ukey, String apiKey, File apkFile) {
    //builder
    MultipartBody.Builder bodyBuilder = new MultipartBody.Builder().setType(MultipartBody.FORM);
    //add part
    bodyBuilder.addFormDataPart("uKey", ukey);
    bodyBuilder.addFormDataPart("_api_key", apiKey);
    //add file
    bodyBuilder.addFormDataPart("file", apkFile.getName(), RequestBody
        .create(MediaType.parse("*/*"), apkFile));

    //request

    Request request = new Request.Builder()
        .url("http://upload.pgyer.com/apiv1/app/upload")
        .post(bodyBuilder.build())
        .build();

    OkHttpClient client = new OkHttpClient();
    try {
      Response response = client.newCall(request).execute();
      String result = response.body().string();
      System.out.println("upload result: " + result);
    } catch (IOException e) {
      e.printStackTrace();
    } catch (Exception e) {

    }
  }

}


ここでは、拡張機能で定義された強化された APK パスに従って、アップロードする APK を選択します (360 はマルチチャネル パッケージ化をサポートします)。

他のコンテンツについては、理解できない場合は、Gradle Custom Plugin を読んで APK を Dandelion にアップロードしてください。

最後に、タスクの依存関係の変更が完了しました。プロセスはパッケージ化、強化、アップロードです。

5. プラグインの依存関係を変更する

ここでは、プラグイン内のタスクの依存関係を変更するだけで済みます。


public class TestJavaPlugin implements Plugin<Project> {

  public static final String PLUGIN_EXTENSION_NAME = "uploadHelperJava";
  public static final String ANDROID_EXTENSION_NAME = "android";
  @Override
  public void apply(Project project) {
    Extension customExtension = project.getExtensions().create(PLUGIN_EXTENSION_NAME, Extension.class);
    //    project.getExtensions().create(PLUGIN_EXTENSION_NAME, Extension.class, project);
    //项目编译完成后,回调
    project.afterEvaluate(new Action<Project>() {
      @Override
      public void execute(Project project) {
        DomainObjectSet<ApplicationVariant> appVariants = ((AppExtension) project
            .getExtensions().findByName(ANDROID_EXTENSION_NAME)).getApplicationVariants();
        for (ApplicationVariant variant : appVariants) {
          //release apk
          if (variant.getBuildType().getName().equalsIgnoreCase("uploadRelease") ) {
            String variantName =
                variant.getName().substring(0, 1).toUpperCase() + variant.getName().substring(1);
            PGYUploadTask uploadTask = project.getTasks()
                .create("uploadJavaFor" + variantName, PGYUploadTask.class);
            uploadTask.init(variant, project);

            ReinforceTask reinforceTask = project.getTasks()
                .create("reinforceFor" + variantName, ReinforceTask.class);
            reinforceTask.init(variant,project);

            //依赖关系
            variant.getAssembleProvider().get().dependsOn(project.getTasks().findByName("clean"));
            reinforceTask.dependsOn(variant.getAssembleProvider().get());
            uploadTask.dependsOn(reinforceTask);

          }
        }
      }
    });
  }
}

強化されたタスクの依存関係にタスクをパッケージ化してから、タスクの依存関係をアップロードしてタスクを強化します。このようにして、プロセス全体が完了します。クリーン、パッケージ、強化、アップロード。

6. プロジェクトコール

ここでは主にプラグインの公開、補強パッケージのプロジェクトへのコピー、プラグインの参照、パラメータの入力、呼び出しなどが行われます。

1. まず、プラグインを再公開します

クリックして、alone_plugin の下の UploadArchives をクリックします。
ここに画像の説明を挿入

2.使用するアイテムには360強化プロテクションを導入

ここに画像の説明を挿入

解凍した鉄筋ファイルをプロジェクトの libs フォルダにコピーします (ファイル名はオプションです。reinforcementJarFile を設定するときに指定するだけです)。

ここで、強化コマンドはすべて jiagu.jar を通じて実行されます。

パラメータコマンドはすべてhelp.txtにあるので、ここでは紹介しません。

3. プロジェクトの下の build.gradle でプラグインが導入されます

テストプロジェクトの紹介、強化されたアップロードプラグイン

buildscript {
    repositories {
        google()
        jcenter()
        maven{
            url uri('./repo/')
        }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.3.1'
        classpath 'com.liu.alone.plugin:java-plugin:1.0.0'
    }
}
allprojects {
    repositories {
        google()
        jcenter()
    }
}
task clean(type: Delete) {
    delete rootProject.buildDir
}

4. アプリのモジュールでプラグインを導入します

アプリのbuild.gradle

android {
  	...
    signingConfigs {
        release {
            storeFile file('xxx.jks')
            storePassword "xxx"
            keyAlias "xxx"
            keyPassword "xxx"
        }
    }


    buildTypes {
        release {
            minifyEnabled false
            signingConfig signingConfigs.release
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
        uploadRelease {
            minifyEnabled false
            signingConfig signingConfigs.release
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}
	...
apply plugin: 'com.liu.alone.plugin'
uploadHelperJava {
    appName = "testGradle"

    uKey = "c9d2625c0cf221d8f4a98738f4c05e9a"

    apiKey = "fac8875534d045a2be3f229abd46cc3e"

    //加固相关的信息
    reinforceJarFile = file("../libs/jiagu.jar")
    reinforceUsername = "xxx"
    reinforcePassword = "xxx"
    outputFile = file("${buildDir.getAbsolutePath()}\\jiagu")

}

作成したプラグインや、設定アップロードの強化に必要なパラメータ情報などを参照してください。reinforcementJarFile
この強化ファイルは、libs 配下の jiagu.jar を指します。鉄筋が別のディレクトリに保存されている場合は、ここで変更できます。

5.最後にタスクを呼び出します

Gradle で定義した Tasks タスクの UploadJavaForUploadRelease を実行します。
ここに画像の説明を挿入

印刷結果

任务完成_已签名


> Task :app:uploadJavaForUploadRelease
upload result: {"code":0,"message":"","data":{"appKey":"bb2b8b14f405d9024b0e18954beaadb8","userKey":"c9d2625c0cf221d8f4a98738f4c05e9a","appType":"2","appIsLastest":"2","appFileSize":"2206305","appName":"ObjectAnimatorTest","appVersion":"1.0","appVersionNo":"1","appBuildVersion":"9","appIdentifier":"com.liu.objectanimatortest","appIcon":"825df8e761ed960f5c3237e9af332df7","appDescription":"","appUpdateDescription":"","appScreenshots":"","appShortcutUrl":"t6rG","appCreated":"2020-01-02 11:19:53","appUpdated":"2020-01-02 11:19:53","appQRCodeURL":"http:\/\/www.pgyer.com\/app\/qrcodeHistory\/5dea8789700159c1d2804374dc80293b2e3f5e5ffd53531b777cfc4a33843c29"}}

ログを印刷して、最初に署名が完了し、次にアップロード タスクが実行され、最後にアップロード結果が返されることを確認します。

他の

1.プラグインbuild.gradle

apply plugin: 'java-library'
apply plugin: 'maven'
dependencies {
    compile gradleApi()
    compile localGroovy()
    compile 'com.android.tools.build:gradle:3.3.1'
    implementation("com.squareup.okhttp3:okhttp:3.8.1")
}
repositories {
    mavenCentral()

}

group = 'com.liu.alone.plugin'
version = '1.0.0'
archivesBaseName = 'java-plugin'
//upload
uploadArchives {
    repositories {
        mavenDeployer {
            repository(url: uri('../repo'))
        }
    }
}

主に、Java 依存関係ライブラリ、okhttp アップロード ライブラリ、プラグインによって公開されたコンテンツがあります。

2. プラグインの全体構造

主に、build.gradle、プロパティ ファイル、プラグイン クラス、2 つのタスク クラス、および拡張プロパティ クラスです。
ここに画像の説明を挿入

この時点で、パッケージ化 – 強化 – アップロードというプロセスが完了しました。

アップロード前に必ずしも強化する必要がない場合、それを制御するために拡張機能で変数を定義できますか? 必要なのは、プラグインの依存関係を変更し、タスクの apk アップロード パスをアップロードすることだけです。

おすすめ

転載: blog.csdn.net/ecliujianbo/article/details/103801481