java实现Android一键打包,秒秒钟生成上百个渠道包

要实现java一键生成渠道包功能,事先我们需要做好准备工作,大概有以下3点
1.准备好所以需要生成的渠道号放在excel文档中
2.需要下载两个jar包,commons-compress-1.16.1.jar和 jxl.jar
3.得准备你需要生成渠道包的apk,也就是说你需要在你的Android开发工具中先打
一个包,然后代码会根据这个包生成不同的渠道包
注:这些资料我都将在文章结尾给出,好废话不多说,现在开始功能的实现

一.首先你的电脑上得有java开发工具,我用的是IntelliJ IDEA 开发工具。

 1.新建一个java项目PackingTools,把commons-compress-1.16.1.jar和 jxl.jar这个两个jar包复制到libs文件中并添加依赖。
 2.新建一个ApkChannel类,这个类需要实现两个方法
    1.遍历读取excel文档中事先准备好的渠道号
   try {
		//ckjr.xls 是所有要打包的平台渠道名excel表格
        Workbook book = Workbook.getWorkbook(new FileInputStream(new File("F:/ckjr.xls")));
		Sheet sheet = book.getSheet(0);
		for (int i = 1; i < sheet.getRows(); i++) {
			String contents = sheet.getCell(1, i).getContents();
			if (contents != null && !"".equals(contents.trim())) {
				mQueue.offer(contents);					
			}
		}
		book.close();
	} catch (Exception e) {
		e.printStackTrace();
	}
	File dfile = new File("F:/渠道打包/" + appName);
	if(!dfile.exists())
		dfile.mkdirs();
	String path = dfile.getPath();
	int index = 0;
	while(index++<15) {
		new Thread(new Runnable() {
			@Override
			public void run() {
				new ApkChannel02().startCopy(path);
			}
		}).start();
	}


    2.把渠道号通过代码的形式注入到apk中
private void startCopy(String outPath) {
		try {
			String channel;
			while((channel=mQueue.poll(1, TimeUnit.SECONDS))!=null) {
				File file = new File(apkPath);
				FileOutputStream fos = new FileOutputStream(outPath+"/"+appName+"_" + channel +versionName);
				ZipFile zipFile = new ZipFile(file);
				ZipArchiveOutputStream zos = new ZipArchiveOutputStream(fos);
				Enumeration entries =  zipFile.getEntries();
				while(entries.hasMoreElements()) {
					ZipArchiveEntry entry = entries.nextElement();
					zos.putArchiveEntry(entry);
//					zos.putArchiveEntry(new ZipArchiveEntry(entry.getName()));
					int length;
					byte[] buffer = new byte[1024];
					InputStream is = zipFile.getInputStream(entry);
					while((length=is.read(buffer))!=-1) {
						zos.write(buffer, 0, length);
					}
					is.close();
					buffer = null;
				}
				zos.putArchiveEntry(new ZipArchiveEntry("META-INF/channel_" + channel));
				zos.closeArchiveEntry();
				zos.close();
				System.out.println("剩余" + mQueue.size());
			}
			if(mQueue.size()==0) {
				openOutputFile();
//				System.out.println("done");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

完整代码如下:

import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.apache.commons.compress.archivers.zip.ZipFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

import jxl.Sheet;
import jxl.Workbook;


/**
 *@desc   java实现一键打包工具
 *@author zhengjun
 *@created at 2018/5/4 16:59
*/
public class ApkChannel{

	private static final String versionName = "_3.7.8.apk"; //当前打包的版本号

    private static final String appName = "ckjr"; //apk名称,根据你的项目自己命名
    
	//事先准备好的打包apk,根据这个apk生成不同平台的apk,放在事先在F盘建好的 "渠道打包" 这个文件夹中
	private static final String apkPath = "F:/渠道打包/"+appName+versionName; 
	
	static LinkedBlockingQueue mQueue = new LinkedBlockingQueue<>(); //存储从excel中读取到的所有渠道号

	public static void main(String[] args) {
		try {
			//ckjr.xls 是所有要打包的平台渠道名
            Workbook book = Workbook.getWorkbook(new FileInputStream(new File("F:/ckjr.xls")));
			Sheet sheet = book.getSheet(0);
			//这里循环从1开始是因为我的excel文档中空了一行没写内容
			for (int i = 1; i < sheet.getRows(); i++) {
				String contents = sheet.getCell(1, i).getContents();
				if (contents != null && !"".equals(contents.trim())) {
					mQueue.offer(contents);					
				}
			}
			book.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		File dfile = new File("F:/渠道打包/" + appName);
		if(!dfile.exists())
			dfile.mkdirs();
		String path = dfile.getPath();
		int index = 0;
		while(index++<15) {
			new Thread(new Runnable() {
				@Override
				public void run() {
					new ApkChannel().startCopy(path);
				}
			}).start();
		}
	}
	
	//开始打包
	private void startCopy(String outPath) {
		try {
			String channel;
			while((channel=mQueue.poll(1, TimeUnit.SECONDS))!=null) {
				File file = new File(apkPath);
				FileOutputStream fos = new FileOutputStream(outPath+"/"+appName+"_" + channel +versionName);
				ZipFile zipFile = new ZipFile(file);
				ZipArchiveOutputStream zos = new ZipArchiveOutputStream(fos);
				Enumeration entries =  zipFile.getEntries();
				while(entries.hasMoreElements()) {
					ZipArchiveEntry entry = entries.nextElement();
					zos.putArchiveEntry(entry);
					int length;
					byte[] buffer = new byte[1024];
					InputStream is = zipFile.getInputStream(entry);
					while((length=is.read(buffer))!=-1) {
						zos.write(buffer, 0, length);
					}
					is.close();
					buffer = null;
				}
				zos.putArchiveEntry(new ZipArchiveEntry("META-INF/channel_" + channel));
				zos.closeArchiveEntry();
				zos.close();
				System.out.println("剩余" + mQueue.size());
			}
			if(mQueue.size()==0) {
				openOutputFile();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	boolean opened = false;
	//打包完成之后 自动打开输出路径
	private void openOutputFile() {
		synchronized (this) {
			if(opened) {
				return;
			}
			opened = true;
		}
		String[] cmd = new String[5];  
        cmd[0] = "cmd";  
        cmd[1] = "/c";  
        cmd[2] = "start";  
        cmd[3] = " ";  
        cmd[4] = "F:/渠道打包";  
        try {
			Runtime.getRuntime().exec(cmd);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

最后运行main方法即可

二. 还需要在你的Android项目中进行一些处理
1.获取包的渠道号

 /**
     * 获取渠道号
     *
     * @param context
     * @return
     */
    public static String getChannel(Context context) {
        if (context == null)
            return "";
        if (!TextUtils.isEmpty(channel)) {
            return channel;
        }
        try {
            ZipFile zipFile = new ZipFile(context.getApplicationInfo().sourceDir);
            Enumeration entries = zipFile.entries();
            while (entries.hasMoreElements()) {
                ZipEntry entry = (ZipEntry) entries.nextElement();
                String entryName = entry.getName();
                //META-INF/channel_这个标识需要跟你打包时候注入渠道号时的一致
                if (entryName.contains("META-INF/channel_")) {
                    channel = entryName.replace("META-INF/channel_", "");
                    break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (TextUtils.isEmpty(channel)){
            channel = "ckjr_hos";
        }
        return channel;
    }

2.在application中进行umeng初始化的时候注入进去

   //友盟初始化,第一个参数为友盟的appkey,第二个参数为渠道号
   UMConfigure.init(this, AppConfig.UMENAPPKEY
                , getChannel(getApplicationContext()), UMConfigure.DEVICE_TYPE_PHONE, "");

最后附上源码的链接地址:https://download.csdn.net/download/qq_20489601/10692821

你可能感兴趣的:(android开发)