Java operations ant compression and decompression files and bulk packaging anroid application _android

Source: Internet
Author: User
Tags readline stringbuffer

Implementation of Zip/tar compression and decompression

Java actually provides support for compressed formats such as ZIP, but why is ant used here?

There are two main reasons:
1. Java-provided classes for include Chinese characters in the path, file name support is not good enough, you use other third-party software to decompress when there will be garbled. Ant.jar supports file names or paths that include Chinese characters.
2. Ant.jar provides a powerful tool class, which is more convenient for us to compress and decompress operations.
Precautions:
1. First of all, on the skin or similar to the skin of the zip package, in fact, the company may, according to their own requirements or requirements, the custom compression package file end, in fact, most of the ZIP package format. The specific part of the processing is generally the same, so no longer repeat, the example given in this article already has the ZIP package and the TAR package uncompressed.
2. It is also to be noted that here for the promotion of understanding, so add Zip/tar compression, decompression of the interface, the actual application of this part without a separate interface to show (decompression requires a certain amount of time, then to enhance the user experience, add a hint box and progress bar), please write their own decompression management class for logical judgment processing respectively.
3. The test needs to speak to unpack the package import SDcard directory (if for other directories, please modify the path in the code)

Program main interface and decompression interface:

The next step is to decompress the core code:
Layout file: Antzip.xml:

<?xml version= "1.0" encoding= "Utf-8"?> <relativelayout xmlns:android= "http://schemas.android.com/apk/res/" 
    Android "Android:layout_width=" Fill_parent "android:layout_height=" fill_parent "> <linearlayout android:orientation= "vertical" android:layout_width= "fill_parent" android:layout_height= "Wrap_content" Android: 
      gravity= "center" android:padding= "20dip" android:layout_centerinparent= "true" > <radiogroup Android:layout_width= "Wrap_content" android:layout_height= "wrap_content" android:orientation= "Horizontal" > <radiobutton android:layout_width= "wrap_content" android:layout_height= "Wrap_content" and Roid:id= "@+id/radiozip" android:checked= "true" android:text= "ZIP"/> <radiobutton 
        Droid:layout_width= "Wrap_content" android:layout_height= "wrap_content" android:id= "@+id/radioTar" 
       android:text= "TAR" android:layout_marginleft= "10dip"/> </RadioGroup> <button android:text= "Compressed android:id=" @+id/  Button1 "android:layout_width=" Fill_parent "android:layout_height=" wrap_content "android:paddingleft=" 30dip " android:paddingright= "30dip" ></Button> <button android:text= "decompression" android:id= "@+id/button2" Androi D:layout_width= "Fill_parent" android:layout_height= "wrap_content" android:paddingleft= "30dip" Android: paddingright= "30dip" android:layout_margintop= "20dip" ></Button> </LinearLayout> </rel 

 Ativelayout>

Antzipactivity:

public class Antzipactivity extends activity {public static final String type = ' type '; 
  public static final int type_zip =-1; 
   
  public static final int type_tar = 1; 
  public static final String suffix_zip = ". ZIP"; 
  public static final String Suffix_tar = ". TAR"; /** called the activity is a. 
  * * Private Button btndocompress; 
   
  Private Button btndecompress; 
  Private RadioButton Radiozip; 
   
  Private RadioButton Radiotar; 
  Private Boolean iszip = true; 
    @Override public void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate); 
    Setcontentview (R.layout.antzip); 
    Radiozip = (RadioButton) Findviewbyid (r.id.radiozip); 
    Iszip = true; 
    Radiozip.setchecked (TRUE); Radiozip.setoncheckedchangelistener (New Oncheckedchangelistener () {@Override public void Oncheckedc Hanged (Compoundbutton Buttonview, Boolean ischecked) {System.out.println ("Radiozip:" +ischeckeD); 
        if (ischecked) {iszip = true; 
    } 
      } 
    }); 
    Radiotar = (RadioButton) Findviewbyid (R.id.radiotar); Radiotar.setoncheckedchangelistener (New Oncheckedchangelistener () {@Override public void Oncheckedc 
        Hanged (Compoundbutton Buttonview, Boolean ischecked) {System.out.println ("Radiotar:" +ischecked); 
        if (ischecked) {iszip = false; 
    } 
      } 
    }); 
    Btndocompress = (Button) Findviewbyid (R.id.button1); 
        Btndocompress.setonclicklistener (New Onclicklistener () {@Override public void OnClick (View v) { 
        Enter the compression interface Intent i = new Intent (antzipactivity.this,dozipactivity.class); I.putextra (TYPE, iszip?) 
        Type_zip:type_tar); 
      AntZipActivity.this.startActivity (i); 
    } 
    }); 
    Btndecompress = (Button) Findviewbyid (R.id.button2); Btndecompress.setonclicklistener (New Onclicklistener () {@OvErride public void OnClick (View v) {//Enter the Decompression interface Intent i = new Intent (antzipactivity.this,unzipact 
        Ivity.class); I.putextra (TYPE, iszip?) 
        Type_zip:type_tar); 
      AntZipActivity.this.startActivity (i); 
  } 
    }); 

 } 
}

Dozipactivity:

public class Dozipactivity extends activity implements onclicklistener{private EditText Etpath; 
  Private EditText etdest; 
  Private Button Btndozip; 
   
  Private TextView Tvtip; 
  Private String Srcpath; 
   
  Private String zipdest; 
  private int type; 
  private String suffix; 
    @Override public void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate); 
    Settitle ("ant-compression"); 
    Type = Getintent (). Getintextra (Antzipactivity.type, antzipactivity.type_zip); suffix = type==antzipactivity.type_zip? 
    AntZipActivity.SUFFIX_ZIP:AntZipActivity.SUFFIX_TAR; 
    Setcontentview (R.layout.dozip); 
    Etpath = (edittext) Findviewbyid (R.ID.EDITTEXT1); 
    Etdest = (edittext) Findviewbyid (R.ID.EDITTEXT2); 
    Set some default function Etpath.settext ("/sdcard/antzip"); 
    Etdest.settext ("/sdcard/antzip" +suffix); 
    Btndozip = (Button) Findviewbyid (R.id.button); 
    Tvtip = (TextView) Findviewbyid (R.id.tv_tip); Btndozip.setonclicklistener (this); 
    @Override public void OnClick (View v) {Srcpath = Etpath.geteditabletext (). toString (); 
      if (Textutils.isempty (Srcpath)) {Toast.maketext (this, specify a path, Toast.length_short). Show (); 
    Return 
    } File Srcfile = new file (Srcpath); 
      if (!srcfile.exists ()) {Toast.maketext (this, "The specified compression package does not exist", toast.length_short). Show (); 
    Return 
    } zipdest = Etdest.geteditabletext (). toString (); 
    if (Textutils.isempty (zipdest)) {//If the user does not enter a destination file, a default zipdest = Srcfile.getparent () is generated; 
    } System.out.println ("Zip name:" +zipdest); If this is the/end, it is proved that the user entered a directory, which requires a filename if (Zipdest.endswith (File.separator)) {zipdest+=srcfile.getname () +su 
    Ffix; else {//If the compressed file name does not end with Zip/tar, then add the suffix if (!zipdest.endswith (suffix)) {zipdest +=su 
      Ffix; }///If the user chooses ZIP, Ziputil is used to compress if (type = = Antzipactivity.type_zip) {Ziputil zipp = new Ziputil (); 
    Zipp.dozip (Srcpath, zipdest); 
      ///If the user chooses tar, use Tarutil to compress else {tarutil tarr = new Tarutil (); 
    Tarr.dotar (Srcpath, zipdest); 
    //compression is completed or prompts the user tvtip.settext ("Compressed file path:" +zipdest); 
  Toast.maketext (This, "compress complete", Toast.length_short). Show (); 

 } 
}

Extract Tool class Ziputil:

public class Ziputil {private ZipFile zipfile;   Private Zipoutputstream zipout;  Compressed zip private int bufsize;  
 
  Size of bytes private byte[] buf;  
    Public Ziputil () {//To initialize our buffer this.bufsize = 1024*4 in the constructor function;  
  This.buf = new Byte[this.bufsize];  /** * Compression of incoming directories or files * @param srcfile directories or files that need to be compressed * @param the path to the DestFile compressed file * * public void 
    Dozip (String srcfile, String destfile) {//Zipdirectorypath: folder name file ZipFile = new file (srcfile) that needs to be compressed; try {//Generate zipoutputstream that all the compressed content will be output through this output stream, and finally write to the compressed file to This.zipout = new Zipoutputstream (New Bufferedoutput 
      Stream (New FileOutputStream (DestFile)); 
      Set the compressed annotation zipout.setcomment ("comment"); 
      Set the compression encoding, if you want to compress the path in Chinese, use the following encoding zipout.setencoding ("GBK");  
 
      Enable compression Zipout.setmethod (zipoutputstream.deflated);  
       
    Compression level is the strongest compression, but time to spend a little bit more zipout.setlevel (deflater.best_compression);  Handlefile (ZipFile, This.zipout, ""); 
    Close our output stream This.zipOut.close () upon completion of processing; 
    catch (IOException IoE) {ioe.printstacktrace (); }/** * Called by Dozip, recursive completion of directory file reads * @param zipfile * @param zipout * @param dirname This is a directory that is primarily used to record compressed files Hierarchical * @throws IOException/private void Handlefile (File zipfile, Zipoutputstream zipout,string dirname) thr 
    oWS IOException {System.out.println ("Traverse file:" +zipfile.getname ()); 
 
      If it is a directory, then traverse if (Zipfile.isdirectory ()) {file[] files = zipfile.listfiles (); 
        if (Files.length = = 0) {//If the directory is empty, it is created separately. 
        Just put the name of the empty directory This.zipOut.putNextEntry (new ZipEntry (Dirname+zipfile.getname () +file.separator)); 
      This.zipOut.closeEntry (); else {//If the directory is not empty, enter recursion, process the next level of file for (file file:files) {//Enter recursion, process the next level of file Handlefile 
        , ZipOut, Dirname+zipfile.getname () +file.separator); }}//If it is a file, compress directly
    else {FileInputStream Filein = new FileInputStream (ZipFile); 
      Put in a zipentry this.zipOut.putNextEntry (new ZipEntry (Dirname+zipfile.getname ())); 
      int length = 0; 
      Stream while putting the compressed file (length = Filein.read (this.buf)) > 0) {this.zipOut.write (this.buf, 0, length); 
    ///close ZipEntry, complete a file compression this.zipOut.closeEntry ();  /** * Extract the specified zip file * @param the path of the Unzipfile compressed file * @param destfile the directory to extract * */public void 
    UnZip (String unzipfile, String destfile) {//unzipfilename the ZIP file name that needs to be unzipped FileOutputStream fileout; 
    File file; 
 
    InputStream InputStream; 
      try {//Generate a ZIP file This.zipfile = new ZipFile (unzipfile); Iterate through all the entities in the ZipFile and unzip them out for (@SuppressWarnings ("unchecked") enumeration<zipentry> entries = This.zi Pfile.getentries (); Entries. hasMoreElements ();) 
        {ZipEntry entry = entries.nextelement (); Healthinto a file that they unzipped (Destfile+file.separator+entry.getname ()); 
        if (Entry.isdirectory ()) {file.mkdirs (); 
          else {//If the directory for the specified file does not exist, create it. 
          File parent = File.getparentfile (); 
          if (!parent.exists ()) {parent.mkdirs (); 
 
          //Get the input stream InputStream = Zipfile.getinputstream (entry) of the compressed entity; 
          Fileout = new FileOutputStream (file); 
          int length = 0; Writes the entity to the local file while (length = Inputstream.read (this.buf)) > 0) {fileout.write (this.buf, 0, le 
          Ngth); 
          } fileout.close (); 
        Inputstream.close (); 
    } this.zipFile.close (); 
    catch (IOException IoE) {ioe.printstacktrace (); 

 } 
  } 
}

ANT implements bulk pack Android apps
as the company's operational needs and applications need to add the application of the statistics, often to correspond to twenty or thirty channels, according to a normal method to generate a different channel package application, not only wasted time, but also greatly reduced efficiency.
The previous article describes the use of ant for Zip/tar package decompression, in fact, the Ant tool is not only such a function, it is more powerful in the automation of the call program to complete the project, packaging, testing and so on. A batch task similar to the make script in C language that completes these tasks. Unlike Makefile, Ant is written in pure Java and therefore has a very good cross-platform nature.

Here I will focus on how to automatically build tools ant, bulk packaging applications to generate applications that correspond to different markets:

First look at the Java Engineering anttest for packaging and the Android architecture that needs to be packaged for release:

Market.txt Store the market identification that needs to be packaged, such as:

Youmeng Gfan .....

In this file, you add the channel name to your needs.

Then take a look at the implementation of the bulk packaging Anttest class content:
Note: The Red callout section needs to be modified:

Package com.cn.ant; 
Import Java.io.BufferedReader; 
Import Java.io.BufferedWriter; 
Import Java.io.File; 
Import Java.io.FileReader; 
Import Java.io.FileWriter; 
Import java.io.IOException; 
Import Java.text.SimpleDateFormat; 
 
Import Java.util.Calendar; 
Import Org.apache.tools.ant.DefaultLogger; 
Import Org.apache.tools.ant.Project; 
 
Import Org.apache.tools.ant.ProjectHelper; 
 
  public class Anttest {private Project project; 
 
    public void init (string _buildfile, String _basedir) throws Exception {Project = new project (); 
 
    Project.init (); 
    Defaultlogger Consolelogger = new Defaultlogger (); 
    Consolelogger.seterrorprintstream (System.err); 
    Consolelogger.setoutputprintstream (System.out); 
    Consolelogger.setmessageoutputlevel (Project.msg_info); 
 
    Project.addbuildlistener (Consolelogger); Set the base directory. 
    If none is given, '. ' is used. 
 
    if (_basedir = = null) _basedir = new String ("."); Project.setbasedir (_basedir); 
 
    if (_buildfile = = null) _buildfile = new String (Projectbasepath + file.separator + "Build.xml"); 
    Projecthelper.getprojecthelper (). Parse (project, new//File (_buildfile)); <span style= "color: #FF0000;" 
  >//Key Code </span> projecthelper.configureproject (Project, New File (_buildfile)); public void Runtarget (String _target) throws Exception {//Test if the project exists if (project = = nul L) throw new Exception ("No target can be launched because" project has not been initialized. 
    Please call the ' init ' method: 
    If no target is specified, run the default one. 
 
    if (_target = = null) _target = Project.getdefaulttarget (); 
 
  Run the target project.executetarget (_target); } <span style= "color: #FF0000;" >private final static String Projectbasepath = "d:\\android\\workspace3\\xxx";//the project root to be packaged private final static Strin G Copyapkpath = "d:\\aNdroid\\apktest "//Save package APK root directory private final static String signapk =" xxx-release.apk ";//the filename here must be the exact name of the project! Private final static string renameapk = "xxx_";//renamed project name prefix (map item not to be changed) private final static string placeholder = "@market 
    @ "//Where the manifest file needs to be modified (placeholder) </span> public static void Main (String args[]) {long starttime = 0L; 
    Long endtime = 0L; 
    Long totaltime = 0L; 
    Calendar date = Calendar.getinstance (); 
    SimpleDateFormat SDF = new SimpleDateFormat ("Yyyy-mm-dd:hh:mm:ss"); 
      try {System.out.println ("---------Ant bulk Automation packaging start----------"); 
      StartTime = System.currenttimemillis (); 
      Date.settimeinmillis (starttime); 
 
      System.out.println ("Start time is:" + Sdf.format (Date.gettime ())); 
      BufferedReader br = new BufferedReader (New FileReader ("Market.txt")); 
      String flag = null; while ((flag = Br.readline ())!= null) {//First modify manifest file: Read @market@ in temporary file to market ID, then write to Manifest.xml St Ring TempFilePath = projEctbasepath + file.separator + "AndroidManifest.xml.temp"; 
        String FilePath = projectbasepath + file.separator + "Androidmanifest.xml"; 
        Write (FilePath, read (TempFilePath, Flag.trim ())); 
        Execute Package Command Anttest mytest = new Anttest (); 
        Mytest.init (Projectbasepath + file.separator + "Build.xml", Projectbasepath); 
        Mytest.runtarget ("clean"); 
        Mytest.runtarget ("release"); Perform a rename and copy operation after the package is finished (file File = new file (Projectbasepath + file.separator + "bin" + File.separator + s) 
            IGNAPK)//bin directory signed apk file RenameFile = new file (Copyapkpath + file.separator + renameapk 
        + Flag + ". apk"); 
        Boolean renametag = File.renameto (renamefile); 
        SYSTEM.OUT.PRINTLN ("rename------>" +renametag); 
        SYSTEM.OUT.PRINTLN ("file------>" +file.getabsolutepath ()); SYSTEM.OUT.PRINTLN ("rename------>" +renamefile.getabsolutepath ()); 
      System.out.println ("---------ant bulk Automation packaging End----------"); 
      Endtime = System.currenttimemillis (); 
      Date.settimeinmillis (Endtime); 
      System.out.println ("End time:" + Sdf.format (Date.gettime ())); 
      TotalTime = Endtime-starttime; 
 
    SYSTEM.OUT.PRINTLN ("Time consuming:" + getbeapartdate (totaltime)); 
      catch (Exception e) {e.printstacktrace (); 
      System.out.println ("---------exception----------in ant Batch Automation packaging"); 
      Endtime = System.currenttimemillis (); 
      Date.settimeinmillis (Endtime); 
      System.out.println ("Abnormal time is:" + Sdf.format (Date.gettime ())); 
      TotalTime = Endtime-starttime; 
    SYSTEM.OUT.PRINTLN ("Time consuming:" + getbeapartdate (totaltime)); }/** * According to the number of seconds, calculate the time difference and the * * * * * * * * seconds return * * @param d1 * @param d2 * @return * * Public stat 
    IC String getbeapartdate (long m) {m = m/1000; 
    String beapartdate = ""; 
    int nday = (int) m/(24 * 60 * 60); int nhour = (int) (M-nday * 24 *60 * 60)/(60 * 60); 
    int nminute = (int) (M-nday * 60-nhour * 60 * 60)/60; 
    int nsecond = (int) m-nday * 60-nhour * 60-nminute * 60; 
 
    Beapartdate = Nday + "Days" + Nhour + "hours" + nminute + "min" + nsecond + "seconds"; 
  return beapartdate; 
    public static string Read (string FilePath, String replacestr) {BufferedReader br = null; 
    String line = null; 
 
    StringBuffer buf = new StringBuffer (); 
 
      try {//create buffered input stream based on file path BR = new BufferedReader (new FileReader (FilePath)); 
        Iterate through each row of the file, modifying the rows that need to be modified, and putting them in the buffered object while (line = Br.readline ())!= null) {//Here Modify the contents of some rows according to actual needs 
          if (line.contains (placeholder)) {line = Line.replace (placeholder, replacestr); 
        Buf.append (line); 
        else {buf.append (line); 
      } buf.append (System.getproperty ("Line.separator")); 
  } catch (Exception e) {e.printstacktrace ();  Finally {//close stream if (br!= null) {try {br.close (); 
        catch (IOException e) {br = NULL; 
  }} return buf.tostring (); /** * Writes the content back to the file * * @param filePath * @param content/public static void write (String file 
 
    Path, String content) {BufferedWriter bw = null; 
      try {//create buffered output stream from file path bw = new BufferedWriter (new FileWriter (FilePath)); 
    Writes the content to the file Bw.write (content); 
    catch (Exception e) {e.printstacktrace (); 
        Finally {//close stream if (BW!= null) {try {bw.close (); 
        catch (IOException e) {bw = NULL; 

 } 
      } 
    } 
  } 
}


Then there is the part of the Android project that needs to be modified:

1. Modify the SDK root directory in Local.properties:

  Sdk.dir=d:\\android\\android-sdk-windows-r17\\android-sdk-windows-r17

2. Modify the path and password of the signed file in Ant.properties (if required)

  Key.store=d:\\android\\mykeystore
  key.store.password=123456
  key.alias=mykey
  key.alias.password= 123456

3. Modify AndroidManifest.xml.temp
Copy androidmanifest.xml, named AndroidManifest.xml.temp
Change the place you want to replace to a placeholder, consistent with the placeholder constant in the package engineering Anttest
such as: <meta-data android:value= "@market @" android:name= "Umeng_channel"/>
4. In Build.xml:
<project name= "XXX" default= "help" >,xxx must be the Android project name.

If the machine does not have an ant environment variable configured, you can configure it according to the following steps:

Ant environment variable settings:

There are 2 main environment variables used by Windows ANT, Ant_home, PATH.

Set the ant_home to point to Ant's installation directory.

To set the method:

Ant_home = d:/apache_ant_1.7.0

Will%ant_home%/bin; %ant_home%/lib is added to the path of the environment variable.

To set the method:

 
 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.