안 드 로 이 드 멀 티 채널 패키지 APK
11219 단어 android파일 흐름다 중 채널 패키지 APKapk 패키지 서명
다음은 구체 적 인 내용 이다.
안 드 로 이 드 응용 이 업 로드 될 때 모든 채널 을 구분 해 야 합 니 다.일반적으로 설정 파일 에서 채널 id 를 변경 합 니 다. 여러 채널 이 있 으 면 수 동 으로 apk 를 수정 하고 생 성 하면 매우 번 거 롭 고 오류 확률 이 증가 합 니 다.
포장 도구 종 류 를 공유 합 니 다.
우리 프로젝트 에서 사용 하 는 umeng 은 통계 분석 도 구 를 만 듭 니 다. umeng 은 채널 별로 포장 할 때 manifest. xml 의 것 을 수정 해 야 합 니 다.
이 값 은 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) 와 유사 한 오류 가 있 으 면 문자 인 코딩 설정 에 주의 하 십시오.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin의 기초 - 2부지난 글에서는 Kotlin이 무엇인지, Kotlin의 특징, Kotlin에서 변수 및 데이터 유형을 선언하는 방법과 같은 Kotlin의 기본 개념에 대해 배웠습니다. 유형 변환은 데이터 변수의 한 유형을 다른 데이터...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.