zip4j的正确使用方式

网上有方法去获取zip4j的进度 的方式有缺陷 ,如果是在后台线程解压, 会有解压到中间一直到不了100%问题, 查看代码.


public void extractAll(final UnzipParameters unzipParameters, final String outPath, final ProgressMonitor progressMonitor, boolean runInThread) throws ZipException {
    CentralDirectory centralDirectory = this.zipModel.getCentralDirectory();
    if(centralDirectory != null && centralDirectory.getFileHeaders() != null) {
        final ArrayList fileHeaders = centralDirectory.getFileHeaders();
        progressMonitor.setCurrentOperation(1);
        progressMonitor.setTotalWork(this.calculateTotalWork(fileHeaders));
        progressMonitor.setState(1);
        if(runInThread) {
            Thread thread = new Thread("Zip4j") {
                public void run() {
                    try {
                        Unzip.this.initExtractAll(fileHeaders, unzipParameters, progressMonitor, outPath);
                        progressMonitor.endProgressMonitorSuccess();
                    } catch (ZipException var2) {
                        ;
                    }

                }
            };
            thread.start();
        } else {
            this.initExtractAll(fileHeaders, unzipParameters, progressMonitor, outPath);
        }

    } else {
        throw new ZipException("invalid central directory in zipModel");
    }
}

------------------
progressMonitor.endProgressMonitorSuccess();
之后执行
this.reset();
this.result = 0;
这样就把进度设置为0.导致外部线程读到的一直都是0

正确的做法

/**
 * Created by caosh on 2018-2-27.
 */

public class UnZipfile {

    private final static String TAG = "UnZipfile";
    private boolean isUnZip = false;
    private static UnZipfile instance;
    private int curpercent = 0;
    private UnzipFileListener mUnzipFileListener;
    private static  Thread thread;
    private Context mContext;
    private UnZipfile(Context context) {
        mContext = context;
    }
    public UnzipFileListener getmUnzipFileListener() {
        return mUnzipFileListener;
    }

    public void setmUnzipFileListener(UnzipFileListener mUnzipFileListener) {
        this.mUnzipFileListener = mUnzipFileListener;
    }

    final public static UnZipfile getInstance(Context context) {
        if (instance == null) {
            synchronized (UnZipfile.class) {
                if (instance == null) {
                    instance = new UnZipfile(context);
                }
            }
        }
        return instance;
    }

    public void unZip(String zipFilePath) {

        if (zipFilePath == null || zipFilePath.equals("")) {
            Log.d(TAG, "此解决路径错误:" + zipFilePath);
            Toast.makeText(mContext, mContext.getString(R.string.zip_file_path_err) + zipFilePath,Toast.LENGTH_LONG).show();
            return;
        }

        // 防止重复解压缩一个文件,造成系统异常
        if (!isUnZip()) {
            File zipfile = new File(zipFilePath);
            if (zipfile.exists()) {

                try {
                    // 由于系统的原因,此处不允许删除源文件,否则会造成解压缩不全
//             File file =new File(getDefaultPath(EstickerApp.getAppContext()));
//             if (!file.exists()){
//                file.mkdir();
//             }
                    unZip(zipfile, SourceUtil.getDataResourcePath(mContext)+ SourceUtil.SHOW_MODE + "_" + SourceUtil.getSoftVersion(), zipHandler,
                            false, false);
                } catch (ZipException e) {
                    e.printStackTrace();
                }

            } else {
                Log.d(TAG, zipFilePath + " 文件不存在");
                if(mContext!=null) {
                    Toast.makeText(mContext, zipFilePath + mContext.getString(R.string.zip_file_path_err),Toast.LENGTH_LONG).show();
                }
            }
        }
    }

    private Handler zipHandler = new Handler() {

        @Override
        public void handleMessage(Message msg) {

            Bundle bundle = msg.getData();

            switch (msg.what) {
                case CompressStatus.START:
                    Log.d(TAG, "unzip start");
                    if (mUnzipFileListener!=null){
                        mUnzipFileListener.onUnzipStart();
                    }
                    curpercent = 0;
                    setUnZip(true);
                    break;
                case CompressStatus.HANDLING: {
                    if (bundle != null) {

                        int percnt = bundle.getInt(CompressStatus.PERCENT);
                        if (curpercent != percnt) {
                            curpercent = percnt;
                            if (mUnzipFileListener!=null){
                                mUnzipFileListener.onUnziping(curpercent);
                            }
                            Log.d(TAG, "unzip persent =" + percnt);
                        }

                    }
                    break;
                }
                case CompressStatus.COMPLETED: {
                    if (mUnzipFileListener!=null){
                        mUnzipFileListener.onUnzipComplet();
                    }
                    Log.d(TAG, "unzip completed");
                    setUnZip(false);
                    break;
                }
                case CompressStatus.ERROR: {
                    if (bundle != null) {
                        if (mUnzipFileListener!=null){
                            mUnzipFileListener.onUnzipError();
                        }
                        Log.d(TAG, "unzip error msg =" + bundle.getString(CompressStatus.ERROR_COM));
                    }
                    curpercent = 0;
                    setUnZip(false);
                    break;
                }
                default:
                    break;
            }

            super.handleMessage(msg);
        }

    };
    /**
     * 封装不同的解压状态
     *
     **/
    public static class CompressStatus {
        public final static int START = 10000;
        public final static int HANDLING = 10001;
        public final static int COMPLETED = 10002;
        public final static int ERROR = 10003;

        public final static String PERCENT = "PERCENT";
        public final static String ERROR_COM = "ERROR";
    }

    public boolean isUnZip() {
        return isUnZip;
    }

    public void setUnZip(boolean isUnZip) {
        this.isUnZip = isUnZip;
    }
    /**
     * 无密码解压
     *
     * @param zipFile
     *            源文件
     * @param filePath
     *            解压文件路径
     * @param handler
     *            进度回调
     * @param isDeleteZip
     *            是否删除源文件
     * @param isEncryption
     *            文件是否加密
     * @throws ZipException
     */
    public static void unZip(final File zipFile, String filePath, final Handler handler, final boolean isDeleteZip,
                             boolean isEncryption) throws ZipException {
        unZip(zipFile, filePath, handler, isDeleteZip, "", isEncryption);
    }
    /**
     * 解压
     *
     * @param zipFile
     *            源文件
     * @param filePath
     *            解压文件路径
     * @param handler
     *            进度回调
     * @param isDeleteZip
     *            是否删除源文件
     * @param password
     *            解压密码
     * @param isEncryption
     *            文件是否加密
     * @throws ZipException
     */
    private static void unZip(final File zipFile, String filePath, final Handler handler, final boolean isDeleteZip,
                              String password, boolean isEncryption) throws ZipException {

        if (isEncryption) {
            final File decodeFile = new File(zipFile.getParentFile(), "test");
            try {
                // 解密
                decodeFile(zipFile, decodeFile, true);
            } catch (Exception e) {
                e.printStackTrace();
            }

            Log.d(TAG, "开始解压");
            ZipFile zFile = new ZipFile(decodeFile);
            zFile.setFileNameCharset("GBK");

            if (!zFile.isValidZipFile()) {
                throw new ZipException("exception!");
            }
            File destDir = new File(filePath); // 解压目录文件
            if (destDir.isDirectory() && !destDir.exists()) {
                destDir.mkdir();
            }
            if (zFile.isEncrypted()) {
                zFile.setPassword(password); // 设置解压密码
            }

            final ProgressMonitor progressMonitor = zFile.getProgressMonitor();

            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    Bundle bundle = null;
                    Message msg = null;
                    int percent = 0;
                    try {
                        Log.d(TAG,"try start");
                        int precentDone = 0;
                        if (handler == null) {
                            return;
                        }

                        boolean isUzipStart = false;
                        while (true) {
                            // 每隔50ms,发送一个解压进度出去
                            Thread.sleep(50);
                            int starState = progressMonitor.getState();
                            Log.d(TAG,"starState = "+starState);
                            if(starState == ProgressMonitor.STATE_BUSY){
                                Log.d(TAG,"isUzipStart = true");
                                isUzipStart = true;
                            }
                            precentDone = progressMonitor.getPercentDone();
                            Log.d(TAG,"precentDone = "+precentDone);
                            if (percent != precentDone) {
                                percent = precentDone;
                                // System.out.println(precentDone);
                                bundle = new Bundle();
                                bundle.putInt(CompressStatus.PERCENT, precentDone);
                                msg = new Message();
                                msg.what = CompressStatus.HANDLING;
                                msg.setData(bundle);
                                handler.sendMessage(msg); // 通过 Handler将进度扔出去
                            }
                            Log.d(TAG,"isUzipStart"+isUzipStart+"progressMonitor.getState()"+progressMonitor.getState());
                            if (precentDone >=100||(isUzipStart==true&& progressMonitor.getState()==ProgressMonitor.STATE_READY)) {

                                break;
                            }
                        }
                        Log.d(TAG,"handler CompressStatus.COMPLETED");
                        handler.sendEmptyMessage(CompressStatus.COMPLETED);
                    } catch (InterruptedException e) {
                        bundle = new Bundle();
                        bundle.putString(CompressStatus.ERROR_COM, e.getMessage());
                        msg = new Message();
                        msg.what = CompressStatus.ERROR;
                        msg.setData(bundle);
                        handler.sendMessage(msg);
                        e.printStackTrace();
                    } finally {
                        if (isDeleteZip) {
                            decodeFile.delete();// 将原压缩文件删除
                        }
                    }
                }
            });
            Log.d(TAG,"Thread start");
            thread.start();
            zFile.setRunInThread(true); // true 在子线程中进行解压 , false主线程中解压
            zFile.extractAll(filePath); // 将压缩文件解压到filePath中...
        } else {
            Log.d(TAG, "开始解压");
            ZipFile zFile = new ZipFile(zipFile);
            zFile.setFileNameCharset("GBK");

            if (!zFile.isValidZipFile()) {
                throw new ZipException("exception!");
            }
            File destDir = new File(filePath); // 解压目录文件
            if (destDir.isDirectory() && !destDir.exists()) {
                destDir.mkdir();
            }
            if (zFile.isEncrypted()) {
                zFile.setPassword(password); // 设置解压密码
            }

            final ProgressMonitor progressMonitor = zFile.getProgressMonitor();
            thread = new Thread(new Runnable() {

                @Override
                public void run() {
                    Bundle bundle = null;
                    Message msg = null;
                    int percent = 0;
                    try {
                        Log.d(TAG,"try start");
                        int precentDone = 0;
                        if (handler == null) {
                            return;
                        }
                        boolean isUzipStart = false;
                        while (true) {
                            // 每隔50ms,发送一个解压进度出去
                            Thread.sleep(50);
                            precentDone = progressMonitor.getPercentDone();
                            int starState = progressMonitor.getState();
                            Log.d(TAG,"starState = "+starState);
                            if(starState == ProgressMonitor.STATE_BUSY){
                                isUzipStart = true;
                                Log.d(TAG,"isUzipStart = true");
                            }
                            Log.d(TAG,"precentDone = "+precentDone);
                            // System.out.println(precentDone);
                            if (percent != precentDone) {
                                percent = precentDone;
                                bundle = new Bundle();
                                bundle.putInt(CompressStatus.PERCENT, precentDone);
                                msg = new Message();
                                msg.what = CompressStatus.HANDLING;
                                msg.setData(bundle);
                                handler.sendMessage(msg); // 通过 Handler将进度扔出去
                            }
                            Log.d(TAG,"progressMonitor.getResult() = "+progressMonitor.getResult());
                            progressMonitor.getResult();
                            Log.d(TAG,"progressMonitor.getState() = "+progressMonitor.getState());
                            Log.d(TAG,"progressMonitor.getWorkCompleted() = "+progressMonitor.getWorkCompleted());
                            Log.d(TAG,"progressMonitor.getCurrentOperation() "+progressMonitor.getCurrentOperation()) ;
                            Log.d(TAG,"isUzipStart"+isUzipStart+"progressMonitor.getState()"+progressMonitor.getState());
                            if (precentDone >= 100||(isUzipStart==true&& progressMonitor.getState()==ProgressMonitor.STATE_READY)) {
                                break;
                            }
                        }
                        Log.d(TAG,"handler CompressStatus.COMPLETED");
                        handler.sendEmptyMessage(CompressStatus.COMPLETED);
                    } catch (InterruptedException e) {
                        bundle = new Bundle();
                        bundle.putString(CompressStatus.ERROR_COM, e.getMessage());
                        msg = new Message();
                        msg.what = CompressStatus.ERROR;
                        msg.setData(bundle);
                        handler.sendMessage(msg);
                        e.printStackTrace();
                    } finally {
                        if (isDeleteZip) {
                            zipFile.delete();// 将原压缩文件删除
                        }
                    }
                }

            });
            Log.d(TAG,"Thread start");


            Log.d(TAG," handler.sendEmptyMessage(CompressStatus.START);");
            handler.sendEmptyMessage(CompressStatus.START);
            thread.start();
            zFile.setRunInThread(true); // true 在子线程中进行解压 ,
            // false主线程中解压
            zFile.extractAll(filePath); // 将压缩文件解压到filePath中...


        }

    }
    /**
     * 解密文件
     *
     * @param sourceFile
     *            加密文件
     * @param decodeFile
     *            解密文件
     * @param b
     *            是否删除加密文件
     */
    public static void decodeFile(File sourceFile, File decodeFile, boolean b) {
        byte[] bs = new byte[1024];
        BufferedInputStream in = null;
        BufferedOutputStream out = null;
        try {
            in = new BufferedInputStream(new FileInputStream(sourceFile));
            out = new BufferedOutputStream(new FileOutputStream(decodeFile, false));
            while ((in.read(bs)) != -1) {
                for (int i = 0; i < bs.length; i++) {
                    out.write(bs[i] - 1);
                }
            }
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        } finally {
            try {
                out.flush();
                in.close();
                out.close();
            } catch (Exception e2) {
                // TODO: handle exception
                e2.printStackTrace();
            }
            if (b) {
                sourceFile.delete();
            }
        }

    }
    public  void stopUnzipFile(){
        if (thread!=null){
            thread.stop();
        }
    }
}



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值