Android 打造自己的个性化应用(五):仿墨迹天气实现续--> 使用Ant实现zip/tar的压缩与解压
上一篇中提到对于Zip包的解压和压缩需要借助Ant 实现,我经过参考了其他的资料,整理后并加上了一些自己的看法:
这里就具体地讲下如何使用Ant进行解压缩及其原因:
java中实际是提供了对 zip等压缩格式的支持,但是为什么这里会用到ant呢?
原因主要有两个:
1. java提供的类对于包括有中文字符的路径,文件名支持不够好,你用其它第三方软件解压的时候就会存在乱码。而ant.jar就支持文件名或者路径包括中文字符。
2. ant.jar提供了强大的工具类,更加方便于我们对压缩与解压的操作。
注意事项:
1. 首先说明一下,关于皮肤或者类似于皮肤的Zip包,实际上公司可能会根据自己的规定或需求,自定义压缩包文件的结尾,实际上大多还是Zip包的格式. 具体部分的处理大致上是一样的,因此不再复述, 本文给出的例子已经有Zip包和Tar包的解压缩.
2. 还有要注意的是,此处为提升理解,因此加入zip/tar压缩,解压的界面,实际应用中此部分无需单独的界面展示(解压缩需要一定时间的话,则为加强用户体验,加入提示框与进度条),请自行编写解压缩管理类进行逻辑判断分别处理.
3. 测试时需要讲要解压缩的包导入sdcard目录下(若为其他目录,请修改代码中路径)
首先看一下工程目录:
程序主界面及解压缩的界面:
接下来是解压缩核心的代码:
布局文件: 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"
- android:id="@+id/radioZip"
- android:checked="true"
- android:text="ZIP"/>
- <RadioButton android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:id="@+id/radioTar"
- android:text="TAR"
- android:layout_marginLeft="10dip"/>
- </RadioGroup>
- <Button android:text="压缩" android:id="@+id/button1"
- android:layout_width="fill_parent" android:layout_height="wrap_content"
- android:paddingLeft="30dip" android:paddingRight="30dip"></Button>
- <Button android:text="解压" android:id="@+id/button2"
- android:layout_width="fill_parent" android:layout_height="wrap_content"
- android:paddingLeft="30dip" android:paddingRight="30dip"
- android:layout_marginTop="20dip"></Button>
- </LinearLayout>
- </RelativeLayout>
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 when the activity is first created. */
- 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 onCheckedChanged(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 onCheckedChanged(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) {
- //进入压缩界面
- 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) {
- //进入解压界面
- Intent i = new Intent(AntZipActivity.this,UnzipActivity.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-压缩");
- 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);
- //设置一些默认的函数
- 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, "请指定一个路径", Toast.LENGTH_SHORT).show();
- return;
- }
- File srcFile = new File(srcPath);
- if(!srcFile.exists())
- {
- Toast.makeText(this, "指定的压缩包不存在", Toast.LENGTH_SHORT).show();
- return;
- }
- zipDest = etDest.getEditableText().toString();
- if(TextUtils.isEmpty(zipDest))
- {
- //如果用户没有输入目标文件,则生成一个默认的
- zipDest = srcFile.getParent();
- }
- System.out.println("zip name:"+zipDest);
- //如果是以/结尾的,则证明用户输入的是一个目录 ,需要在后面加上文件名
- if(zipDest.endsWith(File.separator))
- {
- zipDest+=srcFile.getName()+suffix;
- }
- else
- {
- //如果压缩文件名不是以zip/tar结尾,则加上后缀后
- if(!zipDest.endsWith(suffix))
- {
- zipDest +=suffix;
- }
- }
- //如果用户选择的是zip,则用 zipUtil进行压缩
- if(type == AntZipActivity.TYPE_ZIP)
- {
- ZipUtil zipp = new ZipUtil();
- zipp.doZip(srcPath, zipDest);
- }
- //如果用户选择的是tar,则用 tarUtil进行压缩
- else
- {
- TarUtil tarr = new TarUtil();
- tarr.doTar(srcPath, zipDest);
- }
- //压缩完成后还是提示用户
- tvTip.setText("压缩文件路径:"+zipDest);
- Toast.makeText(this, "压缩完成", Toast.LENGTH_SHORT).show();
- }
- }
解压缩工具类ZipUtil:
- public class ZipUtil {
- private ZipFile zipFile;
- private ZipOutputStream zipOut; //压缩Zip
- private int bufSize; //size of bytes
- private byte[] buf;
- public ZipUtil(){
- //要构造函数中去初始化我们的缓冲区
- this.bufSize = 1024*4;
- this.buf = new byte[this.bufSize];
- }
- /**
- * 对传入的目录或者是文件进行压缩
- * @param srcFile 需要 压缩的目录或者文件
- * @param destFile 压缩文件的路径
- */
- public void doZip(String srcFile, String destFile) {// zipDirectoryPath:需要压缩的文件夹名
- File zipFile = new File(srcFile);
- try {
- //生成ZipOutputStream,会把压缩的内容全都通过这个输出流输出,最后写到压缩文件中去
- this.zipOut = new ZipOutputStream(new BufferedOutputStream(
- new FileOutputStream(destFile)));
- //设置压缩的注释
- zipOut.setComment("comment");
- //设置压缩的编码,如果要压缩的路径中有中文,就用下面的编码
- zipOut.setEncoding("GBK");
- //启用压缩
- zipOut.setMethod(ZipOutputStream.DEFLATED);
- //压缩级别为最强压缩,但时间要花得多一点
- zipOut.setLevel(Deflater.BEST_COMPRESSION);
- handleFile(zipFile, this.zipOut,"");
- //处理完成后关闭我们的输出流
- this.zipOut.close();
- } catch (IOException ioe) {
- ioe.printStackTrace();
- }
- }
- /**
- * 由doZip调用,递归完成目录文件读取
- * @param zipFile
- * @param zipOut
- * @param dirName 这个主要是用来记录压缩文件的一个目录层次结构的
- * @throws IOException
- */
- private void handleFile(File zipFile, ZipOutputStream zipOut,String dirName) throws IOException {
- System.out.println("遍历文件:"+zipFile.getName());
- //如果是一个目录,则遍历
- if(zipFile.isDirectory())
- {
- File[] files = zipFile.listFiles();
- if (files.length == 0) {// 如果目录为空,则单独创建之.
- //只是放入了空目录的名字
- this.zipOut.putNextEntry(new ZipEntry(dirName+zipFile.getName()+File.separator));
- this.zipOut.closeEntry();
- } else {// 如果目录不为空,则进入递归,处理下一级文件
- for (File file : files) {
- // 进入递归,处理下一级的文件
- handleFile(file, zipOut, dirName+zipFile.getName()+File.separator);
- }
- }
- }
- //如果是文件,则直接压缩
- else
- {
- FileInputStream fileIn = new FileInputStream(zipFile);
- //放入一个ZipEntry
- this.zipOut.putNextEntry(new ZipEntry(dirName+zipFile.getName()));
- int length = 0;
- //放入压缩文件的流
- while ((length = fileIn.read(this.buf)) > 0) {
- this.zipOut.write(this.buf, 0, length);
- }
- //关闭ZipEntry,完成一个文件的压缩
- this.zipOut.closeEntry();
- }
- }
- /**
- * 解压指定zip文件
- * @param unZipfile 压缩文件的路径
- * @param destFile 解压到的目录
- */
- public void unZip(String unZipfile, String destFile) {// unZipfileName需要解压的zip文件名
- FileOutputStream fileOut;
- File file;
- InputStream inputStream;
- try {
- //生成一个zip的文件
- this.zipFile = new ZipFile(unZipfile);
- //遍历zipFile中所有的实体,并把他们解压出来
- for (@SuppressWarnings("unchecked")
- Enumeration<ZipEntry> entries = this.zipFile.getEntries(); entries
- .hasMoreElements();) {
- ZipEntry entry = entries.nextElement();
- //生成他们解压后的一个文件
- file = new File(destFile+File.separator+entry.getName());
- if (entry.isDirectory()) {
- file.mkdirs();
- } else {
- // 如果指定文件的目录不存在,则创建之.
- File parent = file.getParentFile();
- if (!parent.exists()) {
- parent.mkdirs();
- }
- //获取出该压缩实体的输入流
- inputStream = zipFile.getInputStream(entry);
- fileOut = new FileOutputStream(file);
- int length = 0;
- //将实体写到本地文件中去
- while ((length = inputStream.read(this.buf)) > 0) {
- fileOut.write(this.buf, 0, length);
- }
- fileOut.close();
- inputStream.close();
- }
- }
- this.zipFile.close();
- } catch (IOException ioe) {
- ioe.printStackTrace();
- }
- }
- }
Android 打造自己的个性化应用(五):仿墨迹天气实现续--> 使用Ant实现zip/tar的压缩与解压的更多相关文章
- Android 打造自己的个性化应用(四):仿墨迹天气实现-->自定义扩展名的zip格式的皮肤
在这里谈一下墨迹天气的换肤实现方式,不过首先声明我只是通过反编译以及参考了一些网上其他资料的方式推测出的换肤原理, 在这里只供参考. 若大家有更好的方式, 欢迎交流. 墨迹天气下载的皮肤就是一个zip ...
- Android 打造自己的个性化应用(一):应用程序换肤主流方式的分析与概述
Android平台api没有特意为换肤提供一套简便的机制,这可能是外国的软件更注重功能和易用,不流行换肤.系统不提供直接支持,只能自行研究. 换肤,可以认为是动态替换资源(文字.颜色.字体大小.图片. ...
- android与服务端通讯时使用到的GZIP压缩及解压
为了减小android项目与服务端进行通讯时的数据流量,我们可以使用GZIP对服务端传输的数据进行压缩,在android客户端解压.或在客户端压缩,在服务端解压.代码如下: android客户端的GZ ...
- Android 打造自己的个性化应用(三):应用程序的插件化
在android的项目开发中,都会遇到后期功能拓展增强与主程序代码变更的现实矛盾,也就是程序的灵活度. 由于linux平台的安全机制,再加上dalvik的特殊机制,各种权限壁垒,使得开发一个灵活多变的 ...
- Android 打造自己的个性化应用(二):应用程序内置资源实现换肤功能
通过应用程序内置资源实现换肤,典型的应用为QQ空间中换肤的实现. 应用场景为: 应用一般不大,且页面较少,风格相对简单,一般只用实现部分资源或者只用实现背景的更换. 此种换肤方式实现的思路: 1. 把 ...
- Android -- 压缩与解压文件
我在做一个项目中,工程文件中有一个功能需要很多图片,图片与app一起打包下来的话有30+M,那么我们就考虑另外下载压缩包,我们将图片取出,工程就只有4+M了,哈哈哈哈,呵呵,真恐怖.那么这样就涉及到另 ...
- Android多种格式的异步解压/压缩解决方案
前言 最近由于项目需要,需要我谅解一下关于在移动平台的解压功能,在移动平台解压,我个人感觉是没有太大必要的,毕竟手机的性能有限.但是,不口否认,移动端的解压功能又是必备的,因为如果对于一些资源管理器类 ...
- Android 打造炫目的圆形菜单 秒秒钟高仿建行圆形菜单
原文:Android 打造炫目的圆形菜单 秒秒钟高仿建行圆形菜单 转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/43131133, ...
- Android特效专辑(十二)——仿支付宝咻一咻功能实现波纹扩散特效,精细小巧的View
Android特效专辑(十二)--仿支付宝咻一咻功能实现波纹扩散特效,精细小巧的View 先来看看这个效果 这是我的在Only上添加的效果,说实话,Only现在都还只是半成品,台面都上不了,怪自己技术 ...
随机推荐
- 注意:"AspNetPager”的控件“AspNetPager1”必须放在具有 runat=server 的窗体标记内
应加: <form id="form1" runat="server"> </form> 否则一开始什么也不显示,页面控件看不见,加上a ...
- android 隔几秒再执行
今天做项目,需要前面的方法执行完等待2秒在关闭当前页面.之前使用的是Thread.sleep(2000)发现根本没有作用.经过多次尝试,发现需要使用以下方法才能实现: new Thread(){ pu ...
- MySQL percona-toolkit工具包的使用教程
percona-toolkit工具包的使用教程之介绍和安装http://blog.chinaunix.net/uid-20639775-id-3206802.htmlpercona-toolkit工具 ...
- mysql配置文件my.cnf解析转载
basedir = path 使用给定目录作为根目录(安装目录). character-sets-dir = path 给出存放着字符集的目录. datadir = path 从给定目录读取数据库文件 ...
- Maybe I go too extreme
昨天拖着一个没睡好的身体去面试了2家公司 被问到Collection的子集的时候顿时傻了一会,明明很简单的问题一时就想不起来了,哈哈.果然做it的人身体要顾好,状态太差了. 发现了一个问题,其实也是早 ...
- CF 8D Two Friends 【二分+三分】
三个地点构成一个三角形. 判断一下两个人能否一起到shop然后回家,如果不能: 两个人一定在三角形内部某一点分开,假设沿着直线走,可以将问题简化. 三分从电影院出来时候的角度,在对应的直线上二分出一个 ...
- c#利用HttpWebRequest获取网页源代码
c#利用HttpWebRequest获取网页源代码,搞了好几天终于解决了,直接获取网站编码进行数据读取,再也不用担心乱码了! 命名空间:Using System.Net private static ...
- 百度UEditor编辑器关闭抓取远程图片功能(默认开启)
这个坑娘的功能,开始时居然不知道如何触发,以为有个按钮,点击一下触发,翻阅了文档,没有发现,然后再网络上看到原来是复制粘贴非白名单内的图片到编辑框时触发,坑娘啊............... 问题又来 ...
- Strange Grid
def main(): r,c = map(int, raw_input().split(' ')) if r % 2 != 0: base = 5*(r-1) else: base = 5*(r-2 ...
- HoG feature for human detection(HoG 行人识别)
本文大部分内容总结于其他文章 1.介绍 HOG(Histogram of Oriented Gradient)是2005年CVPR会议上,法国国家计算机科学及自动控制研究所的Dalal等人提出的一种解 ...