apktool多渠道自动打包

项目上头儿刚跟我说用apktool打包,之前没接触过有点懵,参考网上的文章一步一步的来,参考文章是:http://blog.csdn.net/a641832648/article/details/52163493
准备工作:
需要的工具:一个apk安装包,jdk,sdk,apktool,jdk和sdk就不说了,apktool可以网上去下载,也可以 点击下载
反编译网上一堆文章,我这里就不说了,直接说签名打包吧
原理:
    1.用apktool 打包 (java -jar apktool.jar b xxx xxx_us.apk),通过这个指令会生成一个未签名的apk,注意,此指令需要依赖aapt,aapt的下载上面工具链接里有。
    2.用jdk的jarsigner工具给apk签名(指令有很多,我用的是jarsigner -verbose -keystore abc.keystore -signedjar xxx_s.apk xxx_us.apk keyAlias -storepass *** -keypass ***)

话不多说,开始实践。
apktool工具的三个文件

反编译后会在文件夹中生成跟apk名字一样的文件夹,反编译指令:java -jar apktool.jar d -r ****.apk
接着在命令控制台切换到这个文件夹的路径下。打包命令:
 正确命令:java -jar apktool.jar b 反编译的文件夹名 -o MyTest.apk
正确结果:

 如果你出现了这个错误请不要紧张,因为红框内要写反编译出来的文件夹名字而不是apk名字。

此时文件夹下的列表是这样子的。


下一步就是签名,先把签名文件放在这个目录下,签名的命令是:jarsigner -verbose -keystore ***.jks -signedjar signMyTest.apk MyTest.apk AliasName -storepass **** -keypass ****


如果签名也完成了,基本上就没什么问题了,接下来就是写代码来完成这些操作了。

 我使用IntelliJ来完成的,以下呢就是利用IJ来生成jar包。先写代码再打成jar包。

打包的代码如下:

public static void main(String[] args) {
        System.out.println("====**====By cherry=====**======");

        if (args.length != 5) {
            System.out
                    .println("==ERROR==usage:java -jar rePack.jar apkName keyFile keyPasswd aliasName storePasswd======");
            System.out
                    .println("==INFO==Example: java -jar rePack.jar test.apk android.keystore 123456 android 123456======");
            return;
        }

        String apk = args[0];
        String keyFile = args[1];
        String keyPasswd = args[2];
        String aliName = args[3];
        String storePasswd = args[4];


        SplitApk sp = new SplitApk(apk, keyFile, keyPasswd,aliName,storePasswd);
        sp.mySplit();
    }

SplitApk代码如下:

  ArrayList<String> channel = new ArrayList<String>();
    String curPath;//
    String apkName;  //
    String keyFile;  //
    String keyPasswd;  //
    String aliName;
    String storePass;

    public SplitApk(String apkName, String keyFile, String keyPasswd,String aliName,String storePass) {//
        this.curPath = new File("").getAbsolutePath();
        this.apkName = apkName;
        this.keyFile = keyFile;
        this.keyPasswd = keyPasswd;
        this.aliName = aliName;
        this.storePass = storePass;
    }

    public void mySplit() {
        getCannelFile();//
        modifyXudao();//
    }

    /**
     *
     */
    private void getCannelFile() {
        File f = new File("channel.txt");//
        if (f.exists() && f.isFile()) {
            BufferedReader br = null;
            FileReader fr = null;
            try {
                fr = new FileReader(f);
                br = new BufferedReader(fr);
                String line = null;
                while ((line = br.readLine()) != null) {
                    String[] array = line.split("\t");//
                    channel.add(array[0]);
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (fr != null) {
                        fr.close();
                    }
                    if (br != null) {
                        br.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        } else {

        }
    }

    /**
     *
     *
     * @throws Exception
     */
    private void modifyXudao() {

        String cmdUnpack = "cmd.exe /C java -jar apktool.jar d -f -s "
                + apkName;
        runCmd(cmdUnpack);



        String[] apkFilePath = apkName.split("\\\\");
        String shortApkName = apkFilePath[apkFilePath.length - 1];
        System.out.println("shortApkName = "+shortApkName);
        String dir = shortApkName.split(".apk")[0];
        System.err.println("dir = "+dir);
        File packDir = new File(dir);

        String f_mani = packDir.getAbsolutePath() + "\\AndroidManifest.xml";
        String f_mani_bak = curPath + "\\AndroidManifest.xml";

        File manifest = new File(f_mani);
        File manifest_bak = new File(f_mani_bak);

        manifest.renameTo(manifest_bak);

        for (int i = 0; i < 10; i++) {
            if (manifest_bak.exists()) {
                break;
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        if (manifest_bak.exists()) {

        } else {

        }


        File f = new File("apk");
        if (!f.exists()) {
            f.mkdir();
        }


        for (int i = 0; i < channel.size(); i++) {
            String id = channel.get(i);

            BufferedReader br = null;
            FileReader fr = null;
            FileWriter fw = null;
            try {
                fr = new FileReader(manifest_bak);
                br = new BufferedReader(fr);
                String line = null;
                StringBuffer sb = new StringBuffer();
                while ((line = br.readLine()) != null) {
                    if (line.contains("deacon_id")) {
                        line = line.replaceAll("deacon_id", id);

                    }
                    sb.append(line + "\n");
                }


                fw = new FileWriter(f_mani);
                fw.write(sb.toString());
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (fr != null) {
                        fr.close();
                    }
                    if (br != null) {
                        br.close();
                    }
                    if (fw != null) {
                        fw.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }




            String unsignApk = id + "_" + dir + "_un.apk";
            String cmdPack = String.format(
                    "cmd.exe /C java -jar apktool.jar b %s -o %s", dir, unsignApk);
            runCmd(cmdPack);



            String signApk = "./apk/" + id + "_" + dir + ".apk";
            String cmdKey = String
                    .format("cmd.exe /C jarsigner -verbose -keystore %s -signedjar %s %s  %s -storepass %s -keypass %s",
                            keyFile, signApk, unsignApk,aliName,storePass,keyPasswd);
            runCmd(cmdKey);


            File unApk = new File(unsignApk);
            unApk.delete();
        }


        String cmdKey = String.format("cmd.exe /C rd /s/q %s", dir);
        runCmd(cmdKey);
        manifest_bak.delete();


    }


    public void runCmd(String cmd) {
        Runtime rt = Runtime.getRuntime();
        BufferedReader br = null;
        InputStreamReader isr = null;
        try {
            Process p = rt.exec(cmd);
            // p.waitFor();
            isr = new InputStreamReader(p.getInputStream());
            br = new BufferedReader(isr);
            String msg = null;
            while ((msg = br.readLine()) != null) {
                System.out.println(msg);
            }
        } catch (Exception e) {
            e.printStackTrace();

        } finally {
            try {
                if (isr != null) {
                    isr.close();
                }
                if (br != null) {
                    br.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

代码写完了接下来就是打包成jar包:

这位兄弟写的很详细可以参考,http://blog.csdn.net/fesdgasdgasdg/article/details/73556109

我就不说了,每个人习惯的ide不一样,我之前也用过jcreator,它的方式是这样子的。http://blog.csdn.net/ycyhjj2865/article/details/5485547。

注意:IJ打包成jar的时候,要配置Mani-Class,一定要写上包名。

1、打包完了以后呢,把jar包复制到跟apk同路径下,也就是apktool这个路径。

2、创建一个名为channel.txt的文件,在里面写上需要打包的渠道号,用换行符隔开。不要问为什么是channel.text文件,因为

SplitApk里面已经配置了,也可以变成你想要的名字。

我写了五个渠道。

此时,文件夹下的列表是这样子的。


3、打开cmd,在控制台输入 java -jar AutoPack.jar app-release.apk ***.jks  jks的keyPassWord  jks的AliasName
 jks的storePasswd


打包成功的话会在当前文件夹中生成一个apk文件夹,打包成功的签名文件都会放在这个文件夹里面:


可以修改获取渠道号的文件名,可以修改mate-data中的替换的字段,多渠道打包就完成了。

文章最开始处的参考文章链接里面有批处理文件的解决方案,需要的可以去看看。再把参考文章链接发一次。http://blog.csdn.net/a641832648/article/details/52163493


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值