aapt在處理png文件的時候,會斷定文件類型,若是不是png,將會拋出此錯誤。出現這個問題的緣由是咱們不少時候憑感受手動將jpeg之類的其餘文件後綴名強制修改成png,這個時候看圖軟件仍然可以識別圖片。可是aapt卻不識別,致使編譯失敗。java
使用as正向構建android工程的時候,能夠設置aapt參數忽略png。android
可是使用apkTool回編的時候,沒有設置入口,由於只要有此問題發送,其命令行返回類型就是1(非正常退出)。apache
在執行aapt命令的時候,先行修復全部存在此問題的png文件,避免aapt阻斷。方案以下:app
package brut.util; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; /** * Created by virjar on 2017/8/30. 修復png文件格式 * * <pre> * libpng error: Not a PNG fileERROR: Failure processing PNG image /Users/virjar/Desktop/9candroid/com.china3s.android_635/res/drawable/xprod_arrow_green.png * </pre> * * 該錯誤會致使aapt命令返回1(非正常返回值),致使apk阻斷。本工具讀取全部.png結尾的圖片,若是發現他不是png,則嘗試轉化爲png格式文件 */ public class PNGRepair { public static void repair(File file) { if (file == null) { return; } if (!file.exists()) { return; } if (file.isDirectory()) { File[] files = file.listFiles(); if (files == null) { return; } for (File subFile : files) { repair(subFile); } return; } if (!StringUtils.endsWithIgnoreCase(file.getPath(), ".png")) { // 不是png不處理 return; } ImageTypeBufferedInputStream imageTypeBufferedInputStream = null; try { imageTypeBufferedInputStream = new ImageTypeBufferedInputStream(new FileInputStream(file)); if (StringUtils.equalsIgnoreCase(imageTypeBufferedInputStream.mType, "png")) { return;// 自己就是png文件,忽略處理 } System.out.println( "file: " + file.getPath() + " is a " + imageTypeBufferedInputStream.mType + " transfer to png"); BufferedImage bufferedImage = ImageIO.read(imageTypeBufferedInputStream); IOUtils.closeQuietly(imageTypeBufferedInputStream);// close stream advance ImageIO.write(bufferedImage, "png", file); } catch (IOException e) { e.printStackTrace();// ignore } finally { // make sure stream is closed IOUtils.closeQuietly(imageTypeBufferedInputStream); } } private static class ImageTypeBufferedInputStream extends InputStream { private InputStream delegate; private byte[] type = new byte[4]; private byte cursor = 0; private String mType; ImageTypeBufferedInputStream(InputStream delegate) throws IOException { this.delegate = delegate; int read = delegate.read(type, 0, type.length); if (read < 4) { mType = "unknown"; return; } String s = bytesToHexString(type).toUpperCase(); if (StringUtils.equals(s, "FFD8FFE1")) { mType = "jpg"; } else if (StringUtils.equals(s, "89504E47")) { mType = "png"; } else if (StringUtils.equals(s, "47494638")) { mType = "gif"; } else if (StringUtils.equals(s, "424D0890")) { mType = "bmp"; } else { mType = "unknown"; } } private static String bytesToHexString(byte[] src) { StringBuilder stringBuilder = new StringBuilder(); if (src == null || src.length <= 0) { return ""; } for (byte aSrc : src) { int v = aSrc & 0xFF; String hv = Integer.toHexString(v); if (hv.length() < 2) { stringBuilder.append(0); } stringBuilder.append(hv); } return stringBuilder.toString(); } @Override public int read() throws IOException { if (cursor < 4) { return type[cursor++]; } return delegate.read(); } @Override public long skip(long n) throws IOException { return delegate.skip(n + 4 - cursor); } @Override public int available() throws IOException { return delegate.available() + cursor - 4; } @Override public void close() throws IOException { delegate.close(); } @Override public synchronized void mark(int readlimit) { delegate.mark(readlimit); } @Override public synchronized void reset() throws IOException { delegate.reset(); } @Override public boolean markSupported() { return delegate.markSupported(); } } }
public void aaptPackage(File apkFile, File manifest, File resDir, File rawDir, File assetDir, File[] include) throws AndrolibException { boolean customAapt = false; String aaptPath = apkOptions.aaptPath; List<String> cmd = new ArrayList<String>(); //convert png file //TODO add switch LOGGER.info("convert png file, to avoid \"libpng error: Not a PNG fileERROR\" from aapt"); PNGRepair.repair(resDir);//在這裏加入修復代碼 // path for aapt binary if (! aaptPath.isEmpty()) { File aaptFile = new File(aaptPath); if (aaptFile.canRead() && aaptFile.exist .....
流程方法全稱爲:brut.androlib.res.AndrolibResources#aaptPackage
ide
以後,編譯便可通關工具