zoukankan      html  css  js  c++  java
  • 自动编译.9.png文件

    .9.png文件是一种可以被android系统利用的可拉伸图片,可以使用draw9patch.bat工具处理普通的png文件来生成.9.png文件,这种经过处理的文件被称为.9.png的“源文件”,此时用图片浏览工具打开该文件可以看到图片的周围是一圈单像素,呈现黑色的像素点就是我们使用draw9patch.bat工具画上去的,当我们把图片放在res/drawable文件夹后,使用android编译之后,解压apk包,可以看到虽然res/drawable下的.9.png文件仍然存在,但是使用图片浏览工具打开的时候,它周围的一圈单像素点已经没有,此时的.9.png文件可以称为“编译文件”,有时候为了获取编译后的.9.png文件只能采用这种方法,先用draw9patch.bat处理,然后编译,最后解压apk包,最后拷出编译好的.9.png文件,其实完全可以使用程序模拟这一过程,这样使用的时候就可以直接导入.9.png图片,然后自动生成编译好的.9.png图片。

    程序的设计很简单,调用系统的aapt.ext工具对包含png的程序进行处理,生成一个临时的apk包,然后使用zip解压,抽取编译好的.9.png图片,最后删除生成的临时文件。

    程序源码如下:

    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.util.Enumeration;
    import java.util.Iterator;
    import java.util.Map;
    import java.util.zip.ZipEntry;
    import java.util.zip.ZipFile;
    
    import javax.swing.filechooser.FileSystemView;
    
    
    public class Compile {
    
    	private static String ninepngPath = "";
    	private static String command;
    	private static String deskTop = FileSystemView.getFileSystemView().getHomeDirectory().getAbsolutePath();
    	private static File tempFile = new File(deskTop + "\\temp");//拷贝成功后删除
    	private static File compiledFile = new File(deskTop + "\\compiled");//拷贝成功后删除
    	
    	public static void main(String[] args) {
    		if(!AccessAapt()) {
    			System.out.println("不能访问aapt命令!");
    			return;
    		}
    		if(args.length == 0){
    			
    		}else{
    			ninepngPath = args[0];
    		}
    		File manifest = new File("AndroidManifest.xml");
    		File android = new File("android.jar");
    		File resource = new File("res");
    		File ninepngFile = new File(ninepngPath);
    		
    		try{
    			if(ninepngPath.trim().length() == 0 || !ninepngFile.exists()){
    				System.out.println("您输入的参数有错误!");
    			}else{
    				//将.9.png文件复制到res/下
    				copyFile(ninepngFile,resource.getAbsolutePath() + "\\drawable\\" + ninepngFile.getName());
    				command = "aapt";
    				command += " package";
    				command += " -M " + manifest.getAbsolutePath();
    				command += " -S " + resource.getAbsolutePath();
    				command += " -I " + android.getAbsolutePath();
    				command += " -F " + deskTop + "\\temp";
    			}
    			Runtime.getRuntime().exec(command);
    			Thread.sleep(3000);
    			if(tempFile.exists()){
    				unZip(tempFile.getAbsolutePath(),compiledFile.getAbsolutePath());
    				File srcFile = new File(compiledFile.getAbsolutePath() + "\\res\\drawable\\" + ninepngFile.getName()); 
    				copyFile(srcFile,deskTop + "\\" + ninepngFile.getName());
    			}else{
    				System.out.println("没有获取到zip文件");
    			}
    		}catch(Exception e){
    			System.out.println("命令执行错误!");
    			e.printStackTrace();
    		}
    		System.out.println("文件输出到桌面!");
    		//删除临时文件
            deleteTempFile(tempFile);
            //Runtime.getRuntime().exec("");
            deleteTempFile(compiledFile);
    	}

       //解压zip文件,只需要抽取我们想要的.9.png文件即可 private static void unZip(String zipfile, String destDir) { destDir = destDir.endsWith( "\\" ) ? destDir : destDir + "\\" ; //System.out.println(destDir); byte b[] = new byte [1024]; int length; ZipFile zipFile; try { zipFile = new ZipFile( new File(zipfile)); Enumeration enumeration = zipFile.entries(); ZipEntry zipEntry = null ; while (enumeration.hasMoreElements()) { zipEntry = (ZipEntry) enumeration.nextElement(); if(!zipEntry.getName().endsWith("png")){ continue; } File loadFile = new File(destDir + zipEntry.getName()); //System.out.println(":"+loadFile.getAbsolutePath()); if (zipEntry.isDirectory()) { // 这段都可以不要,因为每次都貌似从最底层开始遍历的 loadFile.mkdirs(); } else { if (!loadFile.getParentFile().exists()) loadFile.getParentFile().mkdirs(); OutputStream outputStream = new FileOutputStream(loadFile); InputStream inputStream = zipFile.getInputStream(zipEntry); while ((length = inputStream.read(b)) > 0) outputStream.write(b, 0, length); inputStream.close(); outputStream.close(); } } zipFile.close(); System.out.println( "文件解压成功!" ); } catch (IOException e) { e.printStackTrace(); } } //测试系统中是否可以访问aapt.ext文件,注意配置好环境变量 private static boolean AccessAapt(){ Map<String,String> envs = System.getenv(); Iterator<Map.Entry<String,String>> iter = envs.entrySet().iterator(); while(iter.hasNext()){ Map.Entry<String,String> entry = iter.next(); String value = entry.getValue(); String[] values = value.split(";"); for(int i = 0; i < values.length; i++){ String str = values[i]; File f = new File(str); if(f.isDirectory()){ String[] fileNames = f.list(); for(int j = 0; j < fileNames.length; j++){ if(fileNames[j].trim().equals("aapt.exe")){ return true; } } } } } return false; } private static boolean copyFile(File srcFile,String descPath){ try{ FileInputStream fis = new FileInputStream(srcFile); File desc = new File(descPath); if(!desc.exists()){ desc.createNewFile(); } FileOutputStream fos = new FileOutputStream(desc); byte[] buffer = new byte[1024]; int length = 0; while((length = fis.read(buffer)) != -1){ fos.write(buffer, 0, length); } fos.flush(); fos.close(); fis.close(); fos = null; fis = null; System.out.println("拷贝成功~!"); //srcFile.delete(); return true; }catch(Exception e){ e.printStackTrace(); } return false; } private static void deleteTempFile(File file){ if(!file.canWrite()) try { Thread.sleep(2000); System.out.println("等待两秒"); } catch (InterruptedException e1) { e1.printStackTrace(); } if(!file.exists()){ System.out.println("文件已经不存在了!"); }else{ if(file.isFile()){ //file.delete(); try { Runtime.getRuntime().exec("cmd /c del /q " + file.getAbsolutePath()); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }else{ try { Runtime.getRuntime().exec("cmd /c rd /s /q " + file.getAbsolutePath()); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } System.out.println("临时文件删除成功!"); } }

    此外,需要注意的是,为了让aapt.ext正常工作,需要手动构造它的执行参数,由于aapt工具需要加载android.jar和AndroidManifest.xml,因此可以考虑把他们放在程序包中,下边是上边程序的目录结构:

  • 相关阅读:
    线程高级应用-心得2-同步锁讲解及面试题案例分析
    线程高级应用-心得1-传统线程和定时器讲解及案例分析
    Map拷贝 关于对象深拷贝 浅拷贝的问题
    HashMap对象的深层克隆
    java Collections.sort()实现List排序自定义方法
    java中观察者模式Observable和Observer
    mysql字符串函数(转载)
    CSS的三种样式表和优先级
    Android之微信支付
    Android之扫描二维码和根据输入信息生成名片二维码
  • 原文地址:https://www.cnblogs.com/sunzhenxing19860608/p/2085414.html
Copyright © 2011-2022 走看看