需求
为什么打那么多的渠道包,相信这个不需要说明了,中国android发布的渠道多也是没有办法的。
多渠道打包的原理参照美团多渠道打包,python的实现方法参照GavinCT
我的Java实现
我是做Android的,所以就用java实现了一遍。一个巩固一下知识,二是Android 的环境下面一定都有java环境了,不需要再装python的环境了。下面是具体的步骤。
- 目录排版如下
- info
- apks //存放需要添加渠道的apk文件
- channel.txt //渠道信息文件
- czt.txt //空文件
- 第一步 加载 apks目录下载所有的 apk文件
private void initApks(){
if (apks == null) {
apks = new ArrayList<>();
}else {
apks.clear();
}
File apkDir = new File(channelConfigPath, "info/apks");
if (!apkDir.exists()){
throw new IllegalArgumentException("can't find apk files in :" + apkDir.getAbsolutePath());
}
File[] files = apkDir.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
return pathname.getName().endsWith(".apk");
}
});
for (File f : files){
apks.add(f);
}
if (apks.isEmpty()){
throw new RuntimeException("not fond apk in :" + apkDir.getAbsolutePath());
}
System.out.println("init apk finish");
}
- 第二步加载渠道文件,文件内容结构如下:
360
baidu
等等
private void initChannel(){
if (channels == null){
channels = new ArrayList<>();
}else {
channels.clear();
}
File channelFile = new File(channelConfigPath, "info/channel.txt");
if (!channelFile.exists()){
throw new IllegalArgumentException("can't find channel file at :" + channelFile.getAbsolutePath());
}
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(channelFile));
String ch = null;
while ((ch = reader.readLine()) != null){
channels.add(ch);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
throw new RuntimeException("read channel file error");
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("read channel file error");
}finally {
if (reader != null){
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
System.out.println("init channel finish");
}
- 第三步生成一个空文件,用来添加到apk里面
private void initEmptyFile(){
if (srcEmptyFile == null){
srcEmptyFile = new File(channelConfigPath, "info/czt.txt");
}
if (!srcEmptyFile.exists()) {
try {
srcEmptyFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("create czt.txt file eroor");
}
}
}
- 最后生成渠道的apk文件
private void buildChannelApk(){
for (File f : apks){
String fileName = f.getName();
String filerRealName = fileName.split("\\.")[0];
File storeDir = new File(f.getParentFile(), filerRealName);
if (!storeDir.exists()){
storeDir.mkdirs();
}
for (String channel : channels){
File outChannelFile = new File(storeDir, filerRealName + "_" + channel + ".apk");
try {
FileUtils.copyFile(f, outChannelFile);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("copy apk file error" + f.getAbsolutePath());
}
try {
Map<String, String> env = new HashMap<>();
env.put("create", "true");
// locate file system by using the syntax
// defined in java.net.JarURLConnection
URI uri = URI.create("jar:" + outChannelFile.toURI());
try (FileSystem zipfs = FileSystems.newFileSystem(uri, env)) {
Path externalTxtFile = Paths.get(srcEmptyFile.toURI());
Path pathInZipfile = zipfs.getPath(String.format(CHANNEL, channel));
// copy a file into the zip file
Files.copy(externalTxtFile, pathInZipfile,
StandardCopyOption.REPLACE_EXISTING);
}
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("build file error");
}finally {
}
System.out.println("build " + outChannelFile.getName() + " finish");
}
System.out.println("build apk finish");
}
}