java realizes one key package of Android and generates hundreds of channel packages in seconds

Posted by terje-s on Tue, 24 Dec 2019 15:36:56 +0100

In order to realize the function of generating channel package by one key in java, we need to make preparations in advance. There are about three points as follows
1. Put the channel number that needs to be generated in the excel file when it is ready
2. You need to download two jar packages, commons-compress-1.16.1.jar and jxl.jar
3. You need to prepare the apk that you need to generate the channel package, that is, you need to first type in your Android development tool
A package, and the code will generate different channel packages based on the package
Note: I will give all these materials at the end of the article. I don't need to talk about much nonsense. Now, I will start to realize the function

1, First of all, you have to have java development tools on your computer. I use IntelliJ IDEA development tools.

 1.Build a new one. java project PackingTools,hold commons-compress-1.16.1.jar and jxl.jar The two one. jar Copy packets to libs File and add dependencies.
 2.Build a new one. ApkChannel Class, this class needs to implement two methods
    1.Ergodic read excel Channel number prepared in advance in the document
   try {
		//ckjr.xls is the excel table of all platform channel names to be packaged
        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:/Channel packing/" + 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.Inject the channel number into the apk in
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<ZipArchiveEntry> 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("Surplus" + mQueue.size());
			}
			if(mQueue.size()==0) {
				openOutputFile();
//				System.out.println("done");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

The complete code is as follows:

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 Implement one click packaging tool
 *@author zhengjun
 *@created at 2018/5/4 16:59
*/
public class ApkChannel{

	private static final String versionName = "_3.7.8.apk"; //Version number of the current package

    private static final String appName = "ckjr"; //apk name, name according to your project
    
	//Pack apk prepared in advance, generate apk of different platforms according to the apk, and put it in the folder of "channel packaging" built in disk F in advance
	private static final String apkPath = "F:/Channel packing/"+appName+versionName; 
	
	static LinkedBlockingQueue<String> mQueue = new LinkedBlockingQueue<>(); //Store all channel numbers read from excel

	public static void main(String[] args) {
		try {
			//ckjr.xls is the name of all platform channels to be packaged
            Workbook book = Workbook.getWorkbook(new FileInputStream(new File("F:/ckjr.xls")));
			Sheet sheet = book.getSheet(0);
			//This loop starts from 1 because there is a blank line in my excel document
			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:/Channel packing/" + 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();
		}
	}
	
	//Start packing
	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<ZipArchiveEntry> 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("Surplus" + mQueue.size());
			}
			if(mQueue.size()==0) {
				openOutputFile();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	boolean opened = false;
	//Automatically open output path after packaging
	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:/Channel packing";  
        try {
			Runtime.getRuntime().exec(cmd);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

Finally, run the main method

2, You also need to do some processing in your Android project
1. Channel number for obtaining package

 /**
     * Access channel No
     *
     * @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? This ID needs to be consistent with the channel number when you pack
                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. Inject it when initializing the document in the application

   //The first parameter is the appkey of the alliance, and the second parameter is the channel number
   UMConfigure.init(this, AppConfig.UMENAPPKEY
                , getChannel(getApplicationContext()), UMConfigure.DEVICE_TYPE_PHONE, "");

Finally, attach the source code link address: https://download.csdn.net/download/qq_20489601/10692821

Topics: Java Excel Apache Android