안 드 로 이 드 멀 티 채널 패키지 APK

인터넷 에서 여러 채널 로 APK 를 포장 하 는 것 을 보 았 는데 생각 은 문제 가 없다. 원문 주소:http://www.cnblogs.com/yyyyy5101/archive/2012/10/23/2735912.html
다음은 구체 적 인 내용 이다.
안 드 로 이 드 응용 이 업 로드 될 때 모든 채널 을 구분 해 야 합 니 다.일반적으로 설정 파일 에서 채널 id 를 변경 합 니 다. 여러 채널 이 있 으 면 수 동 으로 apk 를 수정 하고 생 성 하면 매우 번 거 롭 고 오류 확률 이 증가 합 니 다.
포장 도구 종 류 를 공유 합 니 다.
우리 프로젝트 에서 사용 하 는 umeng 은 통계 분석 도 구 를 만 듭 니 다. umeng 은 채널 별로 포장 할 때 manifest. xml 의 것 을 수정 해 야 합 니 다.
  value 값.
이 값 은 strings. xml 에 < string name = "channel name" > appchannel < / string >, 그래서 컴 파일 할 때 app 만 수정 하면 됩 니 다.channel。
다음은 도구 류 입 니 다. 직접 실행 하면 됩 니 다.
package com.yang.main;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
/**
 * @description: android       ,        ,      channels 
 * @author: [email protected]
 * @time:    2012-10-23  5:17:47
 */
public class CompiledApkUpdate {

    private static final String androidSDK_PATH = "D:\\android\\android-sdk-windows\\";        //android SDK  

    public static final String APK_NAME = "duitang.apk";
    public static final String PROJECT_LIBARY = "";
    public static final String PROJECT_PATH = "D:\\android\\workspace\\tmp\\duitang\\";        //        
    public static final String APK_PATH = "D:\\android\\workspace\\tmp\\apk\\duitang_";        //     apk     duitang_   
    
    
    private static final String apk_PATH_keystore = "D:\\android\\keystore\\bb";        //apk      
    private static final String channelFlag = "app_channel";
    
//    public static String[] channels = {"duitang"}; 
    private static String currentChannelName = "";
    public static String[] channels = {"duitang","91","360","QQ","jifeng","anzhuo","anzhi","youyi","appchina","wangyi","baidu","souhu","3g","nduo","xiaomi","huawei","meizu","lianxiang","aliyun","taobao","google","nearme","mumayi","wandoujia","crosscat","dangle","maopao","feiliu"}; 

    public static void main(String[] args) { 
        replaceChannel();
    }

    /**
     *       
     */
    public static void replaceChannel() {
        try {
            String outPath = PROJECT_PATH + "res\\values\\strings.xml"; //       
            String content = read(outPath);
            for(int channelid=0;channelid<channels.length;channelid++){
                String tmpContent = content;
                tmpContent = tmpContent.replaceFirst(channelFlag, channels[channelid]);
                currentChannelName = channels[channelid];
                write(tmpContent,outPath);
                System.out.println("replace channel name over...");
                packageRes(); //           。       。
                createUnsignedApk();
                signedApk(channelid);
            }
            write(content,outPath);        //     channel_name
            System.out.println("execute over!");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    /**
     * class     classes.dex
     */
    public static void packageDex(){
        try { 
            System.out.println("dx.bat start...");
            Process process = Runtime.getRuntime().exec(androidSDK_PATH
                    +"platform-tools\\dx.bat --dex --output="
                    +PROJECT_PATH+"bin\\classes.dex "
                    +PROJECT_PATH+"bin\\classes "
                    +PROJECT_PATH+"libs\\*.jar"); 
            
            new MyThread(process.getErrorStream()).start();

            new MyThread(process.getInputStream()).start();
            
            process.waitFor();  
            process.destroy();  
            System.out.println("dx.bat over...");
        } catch (Exception e) { 
            e.printStackTrace(); 
        } 
    }
    
    /**
     * res assets     res.zip
     */
    public static void packageRes(){
        try{
            System.out.println(currentChannelName+" create resources.ap");
            String library = "";
            if(PROJECT_LIBARY!=null&&!PROJECT_LIBARY.equals("")){
                library = "-S " + PROJECT_LIBARY + "res ";
            }
            Process process = null;
            process = Runtime
                    .getRuntime()
                    .exec(  androidSDK_PATH
                            + "platform-tools\\aapt.exe package -f " +
                            "-M " + PROJECT_PATH + "AndroidManifest.xml " +            //-M       
                            "-S " + PROJECT_PATH + "res " +                            //-S       
                            library +
                            "-A " + PROJECT_PATH + "assets " +                        //-A   assets
                            "-I " + androidSDK_PATH + "platforms\\android-16\\android.jar " +    //-I   android 
                            "-F " + PROJECT_PATH + "bin\\resources.ap_ --auto-add-overlay"); //        resources.ap_
            new MyThread(process.getErrorStream()).start();
            new MyThread(process.getInputStream()).start();
            process.waitFor();
            process.destroy();
            System.out.println(currentChannelName+" resources.ap over...");
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    
    /**
     * classes.dex res.zip AndroidManifest.xml       apk
     */
    public static void createUnsignedApk(){
        try{
            System.out.println(currentChannelName+" createUnsignedApk start");
            Process process = null;
            process = Runtime.getRuntime().exec(
                    androidSDK_PATH+ "tools\\apkbuilder.bat "
                    + PROJECT_PATH + "bin\\"+APK_NAME+" -u -z "
                    + PROJECT_PATH + "bin\\resources.ap_ -f "
                    + PROJECT_PATH + "bin\\classes.dex"); //       apk
            new MyThread(process.getErrorStream()).start();
            new MyThread(process.getErrorStream()).start();
            process.waitFor();
            process.destroy();
            System.out.println(currentChannelName+" createUnsignedApk over");
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    
    /**
     *   apk
     */
    public static void signedApk(int channelid){
        try{
            System.out.println(currentChannelName+" signed apk start");
            Process process = null;
            String jarsigner;
            jarsigner = "jarsigner -keystore "+apk_PATH_keystore+" -storepass ***** -keypass ****** " +
                    "-signedjar "
                    + APK_PATH
                    + channels[channelid]
                    + ".apk "
                    + PROJECT_PATH
                    + "bin\\"+APK_NAME+" *****";            //  apk
            process = Runtime
                    .getRuntime()
                    .exec(jarsigner); //  apk    
            new MyThread(process.getErrorStream()).start();

            new MyThread(process.getInputStream()).start();
            process.waitFor();
            process.destroy();
            System.out.println(currentChannelName+" signed apk over"); //          。          
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    
    
    public static String read(String path) {
        StringBuffer res = new StringBuffer();
        String line = null;
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(path),"UTF-8"));
            while ((line = reader.readLine()) != null) {
                res.append(line + "
"); } reader.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return res.toString(); } public static boolean write(String cont, String dist) { try { OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(new File(dist)),"utf-8"); writer.write(cont); writer.flush(); writer.close(); return true; } catch (IOException e) { e.printStackTrace(); return false; } } public static class MyThread extends Thread{ BufferedReader bf; public MyThread(InputStream input) { bf = new BufferedReader(new InputStreamReader(input)); } public void run() { String line; try { line = bf.readLine(); while (line != null) { System.out.println(line); line = bf.readLine(); } } catch (IOException e) { e.printStackTrace(); } } } }

 
주의사항:
1. 각 path 경 로 를 정확하게 설정 합 니 다.
2. channelFlag 의 값 은 strings. xml 에서 channelname 의 value 가 일치 합 니 다.
3. 자바 파일 을 실행 하 는 것 은 안 드 로 이 드 프로젝트 를 먼저 실행 하여 빈 디 렉 터 리 에 최신 apk 가 있 는 지 확인 하 는 것 입 니 다.
4. 실행 중 수 동 으로 멈 추 지 마 십시오. 수 동 으로 멈 추 면 다시 실행 할 때 strings. xml 에서 channel 을 확인 하 십시오.name 의 value 값, app 이 아 닌 경우채널
5. error: Error parsing XML: not well - formed (invalid token) 와 유사 한 오류 가 있 으 면 문자 인 코딩 설정 에 주의 하 십시오.

좋은 웹페이지 즐겨찾기