C#版Unity-APK打包工具

最近应大佬的要求,给渠道做了一个打包工具。

这里说的打包工具,不是在unity里直接调用打包,而是更改已打包好的APK,进行换皮换资源换渠道操作。

 -------------------------------------------------------

--本文的打包为基于母包去打子渠道子包,这种方式打出来的子包,流畅度没有源码打出来的包那么好。

如果你想使用源码打包,跳转到我的另一篇文章,文章内容是用网站或者winform程序使用命令行进行打包,也可以打批量。

https://www.cnblogs.com/vsirWaiter/p/16639243.html

开发只需要开发完成,上传源码,打包可以直接解放,交给运营自己去操作就行了。

可以达到jenkinesr打包的效果,并且还能自定义做很多事。

--------------------------------------------------------------

废话不多说,本文的打包工具,winform先开起来。

下载一个ApkTools工具。

下载地址:

【金山文档】 apktool
https://kdocs.cn/l/cnzBPJDmtgEc

这个包里的apktool.jar比较老,所以需替换一个新版本的,下载地址如下。

【金山文档】 apktool_2.6.1
https://kdocs.cn/l/csjDyQNnTeB2

之所以脱裤子放个屁,主要是为了让大家知道不同版本的apktool.jar,同样的指令,解出来的东西是有可能不一样的。

然后要在网上下载一个zipalign.exe

作用:用于未签名的apk对齐。

然后在你的Android Studio的SDK目录里找到apksigner.jar这个东西,我选的是31版本,作用是用来给未签名的APK签名。

 

 

 如上图,PackagingTools为winform创建的exe,前面所说的需依赖的东西都解压放在这个目录。

那么,开工。

第一步:解包。

启动PackagingTools.exe。

try
                {
                    using (p2 = new Process())
                    {
                        //设置要启动的应用程序
                        try
                        {
                            p2.StartInfo.FileName = @"cmd.exe";// 
                                                               // //是否使用操作系统shell启动
                            p2.StartInfo.UseShellExecute = false;
                            // 接受来自调用程序的输入信息
                            p2.StartInfo.RedirectStandardInput = true;
                            //输出信息
                            p2.StartInfo.RedirectStandardOutput = true;
                            // 输出错误
                            p2.StartInfo.RedirectStandardError = true;
                            //不显示程序窗口
                            p2.StartInfo.CreateNoWindow = true;
                            // //启动程序
                            p2.Start();
                            SetTextLogoInfo("母包开始解包!");
                            p2.StandardInput.WriteLine("apktool.bat d " + apkName + " -f -only-main-classes");
                            p2.StandardInput.WriteLine("ApkUnpack Completed");

                            StreamReader rd = p2.StandardOutput;
                            bool isUnPack = true;
                            while (isUnPack)
                            {
                                string strOuput = rd.ReadLine();

                                if (!string.IsNullOrEmpty(strOuput))
                                {
                                    Thread.Sleep(30);
                                    SetTextLogoInfo(strOuput);
                                    if (strOuput.Contains("ApkUnpack Completed"))
                                    {
                                        isUnPack = false;
                                        Thread.Sleep(30);
                                        SetTextLogoInfo("母包解包完成!");
                                    }
                                }
                            }
                            p2.Close();
                        }
                        catch (Exception ex)
                        {

                            p2.Close();
                        }

                    }

                }
                catch (Exception ex)
                {


                }

  2、修改AndroidManifest.xml、value/strings.xml、icon等信息。

  这一步不上代码了,用代码复制粘贴文件和修改xml。

  3、合包回编。

  

p3 = new Process()
p3.StartInfo.FileName = @"cmd.exe";// // //是否使用操作系统shell启动 p3.StartInfo.UseShellExecute = false; // 接受来自调用程序的输入信息 p3.StartInfo.RedirectStandardInput = true; //输出信息 p3.StartInfo.RedirectStandardOutput = true; // 输出错误 p3.StartInfo.RedirectStandardError = true; //不显示程序窗口 p3.StartInfo.CreateNoWindow = true; // //启动程序 p3.Start(); SetTextLogoInfo("准备开始合包回编译!"); string hFolder = apkName.Substring(0, apkName.LastIndexOf('.')); if (File.Exists(exePath + "\\" + hFolder + "\\dist\\" + hFolder + ".apk")) { File.Delete(exePath + "\\" + hFolder + "\\dist\\" + hFolder + ".apk"); } p3.StandardInput.WriteLine("apktool.bat b " + hFolder); p3.StandardInput.WriteLine("ApkUnpack compile Completed"); StreamReader rd = p3.StandardOutput; bool isUnPack = true; while (isUnPack) { string strOuput = rd.ReadLine(); if (!string.IsNullOrEmpty(strOuput)) { Thread.Sleep(30); SetTextLogoInfo(strOuput); if (strOuput.Contains("ApkUnpack compile Completed")) { isUnPack = false; Thread.Sleep(30); SetTextLogoInfo("合包回编译完成!"); } } }

  注意合包回编之后的apk在解包目录下的dist文件夹内。

  回编完成后将apk拷贝至解包合包的程序目录下,这样我们的cmd命令就不需要指定各个东西的路径,都会默认在程序目录下。

  假如拷贝到程序目录下后,我们将其命名为tmp.apk。

  4、APK对齐操作。

p3.StandardInput.WriteLine("zipalign -v 4 tmp.apk dst.apk");//前者为未对齐,后者为已对齐

  tmp.apk为合包后的未签名APK,dst.apk为未签名APK对齐后的未签名APK。

  如果对齐1次后去签名,如若签名失败,则将对齐一次的dst.apk再对齐一次。

  一般情况下2次对齐99.999999999%的都没问题。

  5、签名回签。

p3.StandardInput.WriteLine("java -jar apksigner.jar sign -verbose --ks xxxxxxx.keystore --v1-signing-enabled false --v2-signing-enabled true --ks-pass pass:yyyyyyy --ks-key-alias xxxxxxx.keystore --key-pass pass:yyyyyyy --out 1.apk dst.apk");

  调用以上代码进行签名。

  xxxxxxx.keystore为你的签名文件。

  yyyyyyy为你的签名密码。

  最后面的dst.apk为未签名的APK。

  最后面的1.apk为签名成功后的apk。

  完成。

  1.apk,再用程序对其重新命名即可。

  

以上原本都是CMD执行的命令,这里是用winform调用CMD按顺序执行的,因为运营是不想用程序员的操作方式来玩这个的。

 

posted @ 2022-08-13 17:56  威少小二orz  阅读(563)  评论(0编辑  收藏  举报