[Unity]Unity调用Java解压zip文件

        之前有说过,Unity中StreamingAssets文件数量超过250个,使用Gradle打包会失败(只有安卓有这个问题,Unity版本是2017.4.7f1)。因此采用的解决方案是将StreamingAssets中的文件打成一个zip包,再解压到持久化目录中,之前临时使用的方案是拷贝文件。项目急需这个需求,只好放下手头不急的事,花了一天的时间来处理。

        一开始就不打算用c#来处理,www加载效率低而且占内存,因此这边测试用Java来解压,发现效率不错,200M的文件解压好机子大概只需要2秒,最烂的机子10秒,按最烂的机子来算,每秒也有20M的速度。这边另外一个项目是用www解压的,用最好的机子,650M的文件解压时间为1分30秒多,每秒7M的速度。所以说很多文章说Unity对www加载优化了,其实测一下就知道效率的问题了。

        还是在之前写的安卓通用类上加了个解压的接口。先看c#这边的调用:

/// <summary>
    /// 调用:  AndroidUtility.UnZipFile("test.zip", Application.persistentDataPath + "/Test/");
    /// </summary>
    /// <param name="zipFile"></param>
    /// <param name="newPath"></param>
    public static bool UnZipFile(string zipFile, string newPath)
    {
#if UNITY_ANDROID && !UNITY_EDITOR
        System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
        stopwatch.Start(); //  开始监视代码
        var activity = new AndroidJavaClass("com.unity3d.player.UnityPlayer").GetStatic<AndroidJavaObject>("currentActivity");
        var assetManager = activity.Call<AndroidJavaObject>("getAssets");
        var javaClass = new AndroidJavaClass("com.zp.utility.api");
        var javaObject = javaClass.CallStatic<AndroidJavaObject>("instance");
        
        var result = javaObject.Call<bool>("UnZipFile", assetManager, zipFile, newPath);
        stopwatch.Stop(); //  停止监视
        System.TimeSpan timeSpan = stopwatch.Elapsed; //  获取总时间
        Debug.LogError("解压总时间为: " + timeSpan.TotalSeconds);
        return result;
#endif
        return false;
    }

        Java这边的是:

/**
     * 从StreamingAssets解压文件到持久化目录
     * @param object AssetManager: Unity获取并传过来的
     * @param zipFile zipFile:StreamingAssets下的zip文件
     * @param newPath
     * @return
     */
    public boolean UnZipFile(Object object, String zipFile, String newPath)
    {
        Log.v("ZP", "111111111111111");
        AssetManager assetManager = (AssetManager)object;
        boolean bIsNull = assetManager == null;
        if(bIsNull) {
            Log.v("ZP", "AssetManager Is Null");
            return false;
        }
        File desDir = new File(newPath);
        if (!desDir.exists())
        {
            desDir.mkdirs();
        }
        InputStream input = null;

        try
        {
            input = assetManager.open(zipFile);
            if(input == null)
                return false;
            ZipInputStream zipinputstream = new ZipInputStream(input);
            if(null == zipinputstream)
                return false;

            ZipEntry ze = null;
            byte[] buf = new byte[1024];

            while((ze = zipinputstream.getNextEntry()) != null){
                String dirstr = newPath + ze.getName();
                if(ze.isDirectory()){//是文件夹
                    dirstr = new String(dirstr.getBytes("8859_1"), "GB2312");
                    File f = new File(dirstr);
                    if (!f.exists())
                        f.mkdirs();

                    zipinputstream.closeEntry();
                    continue;
                }
                //是文件
                dirstr = new String(dirstr.getBytes("8859_1"), "GB2312");
                //Log.v("ZP", "dirstr: "+ dirstr);
                File newFlie = new File(dirstr);
                if(!newFlie.exists()){
                    File fileParentDir = newFlie.getParentFile();
                    if (!fileParentDir.exists()) {
                        fileParentDir.mkdirs();
                    }
                    newFlie.createNewFile();
                }
                else//重复文件不解压
                {
                    zipinputstream.closeEntry();
                    continue;
                }
                OutputStream os = new BufferedOutputStream(new FileOutputStream(dirstr));
                int len=0;
                while ((len = zipinputstream.read(buf, 0, 1024)) != -1) {
                    os.write(buf, 0, len);
                }
                zipinputstream.closeEntry();
                os.close();
            }
            zipinputstream.close();
            Log.d("ZP", "finishssssssssssssssssssss");
            return false;
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
        return false;
    }

        具体的就不解释了,代码很简单。需要注意的是用File和ZipFile是读取不到StreamingAssets中给的文件。而且这个功能也有个缺点就是不好做loading条,因为不好计算文件大小和数量,如果计算的话会有开销不值得,所以做个假的进度条。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值