A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

Android 多渠道打包方式详解(下)



  • 5、Zipalign优化


如图所示,sdk/build-tools里面每个版本都是有这个东西的,加到环境变量中就好了!!!

zipalign 优化处理相关代码

[AppleScript] 纯文本查看 复制代码
* 需要安装并Android SDK并配置环境变量Build Tools路径
 * 优化apk文件,这个需要Android Build Tools 中的zipalign程序文件
 *
 * @param apkFilePath 要优化的apk文件路径
 * @param outFilePath 优化后的apk存放文件路径
 */
public boolean zipalign(String apkFilePath, String outFilePath) {
    return executeCommand("zipalign", "-f", "-v", "4", apkFilePath, outFilePath);
}

美团方式

上面说的反编译要各种解包,打包,签名,相对也比较繁琐,然后我们可以发现,apk其实都是一个压缩包,我们直接在这个压缩包里添加对应的文件作为渠道号标记是不是又能省去上面繁琐的步奏呢?!打开一个APK文件之后你会看到META-INF这个文件夹!

美团的方式就是在这里面直接再添加一个文件,然后通过这个文件的名称来指定对应的渠道号!

话不多说,直接上代码!!

[Java] 纯文本查看 复制代码
public static void addUmengChannel(String filepath, String channel) {
    String channel_title = "umengchannel_";
    if(filepath.substring(filepath.lastIndexOf(".") + 1).toLowerCase().equals("apk")) {
        String path2 = "";
        if(filepath.lastIndexOf(File.separator) >= 0) {
            path2 = filepath.substring(0, filepath.lastIndexOf(File.separator) + 1);//得到父路径
        }
 
        if(path2.length() != 0) {
            File s = new File(filepath);//原始的apk
            File t = new File(filepath.substring(0, filepath.lastIndexOf(".")) + "_" + channel + ".apk");//目标apk
            if(!t.exists()) {//不存在就创建
                try {
                    t.createNewFile();
                } catch (IOException var12) {
                    var12.printStackTrace();
                }
            }
 
            Utils.fileChannelCopy(s, t);//拷贝原始apk到目标apk
            File addFile = new File(path2 + channel_title + channel);//需要添加的渠道文件 
            if(!addFile.exists()) {
                try {
                    addFile.createNewFile();
                } catch (IOException var11) {
                    var11.printStackTrace();
                }
            }
 
            try {
                Utils.addFileToExistingZip(t, addFile);//将新加的渠道文件添加到目标apk文件中
                addFile.delete();
            } catch (IOException var10) {
                var10.printStackTrace();
            }
 
        }
    }
} 
 
 
public static void addFileToExistingZip(File zipFile, File file) throws IOException {
        File tempFile = File.createTempFile(zipFile.getName(), (String)null);
        tempFile.delete();
        boolean renameOk = zipFile.renameTo(tempFile);//拷贝
        if(!renameOk) {
            throw new RuntimeException("could not rename the file " + zipFile.getAbsolutePath() + " to " + tempFile.getAbsolutePath());
        } else {
            byte[] buf = new byte[1024];
            ZipInputStream zin = new ZipInputStream(new FileInputStream(tempFile));
            ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFile));
 
            for(ZipEntry entry = zin.getNextEntry(); entry != null; entry = zin.getNextEntry()) {
                String in = entry.getName();
                if(in.contains("umengchannel")) {//如果有重复的就不复制回去了!
                    continue;
                }
 
                out.putNextEntry(new ZipEntry(in));
 
                int len1;
                while((len1 = zin.read(buf)) > 0) {
                    out.write(buf, 0, len1);
                }
            }
 
            zin.close();
            FileInputStream in1 = new FileInputStream(file);
            out.putNextEntry(new ZipEntry("META-INF/" + file.getName()));//创建对应的渠道文件
 
            int len2;
            while((len2 = in1.read(buf)) > 0) {
                out.write(buf, 0, len2);
            }
 
            out.closeEntry();
            in1.close();
            out.close();
            tempFile.delete();
        }
    }

最后送上读取相关的方法:

[Java] 纯文本查看 复制代码
public static String getChannel(Context context) {
        ApplicationInfo appinfo = context.getApplicationInfo();
        String sourceDir = appinfo.sourceDir;
        String ret = "";
        ZipFile zipfile = null;
        try {
            zipfile = new ZipFile(sourceDir);
            Enumeration> entries = zipfile.entries();
            while (entries.hasMoreElements()) {
                ZipEntry entry = ((ZipEntry) entries.nextElement());
                String entryName = entry.getName();
                    //这里需要替换成你的那个key
                if (entryName.startsWith(YOUR_CHNANNEL_NAME)) {
                    ret = entryName;
                    break;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (zipfile != null) {
                try {
                    zipfile.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
 
        String[] split = ret.split("_");
        if (split != null && split.length >= 2) {
            return ret.substring(split[0].length() + 1);
 
        } else {
            return "";
        }
    }

当然你肯定要手动设置了,这个没法直接在清单文件中去配置了!!

小结

主要的方式就是这三种了!可以说一个比一个快,一个比一个的定制也要高,效率提高了,灵活性似乎就会下降的,至于到底使用哪种方式,还是根据实际情况灵活选择吧,反正到现在,这些方案都是很成熟的,没有什么坑



0 个回复

您需要登录后才可以回帖 登录 | 加入黑马