如何将文件打包在/data/data/PackageName/files 文件夹内,如何突破UNCOMPRESS_DATA_MAX 的限制

本文介绍了解决Android APK中大于1MB文件打包的问题,通过将文件如SQLite数据库重命名为预压缩格式(如.jpg),并提供了复制文件的具体实现代码。

android可供打包的资源文件,在项目开发时有:assets,不过据说不能写入。

如果希望将需要用到的文件打入apk,比如SQLite的db文件,现在的方法是,在项目中,把文件先存在assets里,然后在程序第一次启动时,将assets中的文件拷贝到/data/data中。

需要注意的是,如果直接使用db做为文件后缀,在拷贝大于1M的文件时时将会出现:

DEBUG/asset(725): Data exceeds UNCOMPRESS_DATA_MAX (1662976 vs 1048576)



出现这个问题的原因是,assetsManager 无法处理大于1M的文件的压缩和解压。

但以下文件类型,因为是已经压缩过的,不会进行压缩处理,如下:

/* these formats are already compressed, or don't compress well */

static const char* kNoCompressExt[] = {

    ".jpg", ".jpeg", ".png", ".gif",

    ".wav", ".mp2", ".mp3", ".ogg", ".aac",

    ".mpg", ".mpeg", ".mid", ".midi", ".smf", ".jet",

    ".rtttl", ".imy", ".xmf", ".mp4", ".m4a",

    ".m4v", ".3gp", ".3gpp", ".3g2", ".3gpp2",

    ".amr", ".awb", ".wma", ".wmv"

};

参考:http://ponystyle.com/blog/2010/03/26/dealing-with-asset-compression-in-android-apps/

 

所以,现在的思路是:将Sqlite db文件,先改名为.jpg文件,放在assets中,然后在程序第一次启动时,改名拷贝到/data/data中。

参考代码如下:

import android.content.Context;
import android.content.res.AssetManager;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import android.util.Log;


public class InitResources {
    private Context _context;
    public InitResources(Context context) {
        _context = context;
    }

 

public void CopyAssets(String dirname, String renFrom, String renTo) {
        AssetManager assetManager = _context.getAssets();
        String[] files = null;
        try {
            files = assetManager.list(dirname);
        } catch (IOException e) {
            Log.e("tag", e.getMessage());
        }
        InputStream in = null;
        OutputStream out = null;
        for(int i=0; i<files.length; i++) {
            try {
              in = assetManager.open(dirname + "/" + files[i]);
              out = new FileOutputStream(_context.getFilesDir().getAbsolutePath() +"/"+ rename(files[i],renFrom,renTo));
              copyFile(in, out);
              in.close();
              in = null;
              out.flush();
              out.close();
              out = null;
            } catch(IOException e) {
                    Log.e("tag",files[i]);
                    Log.e("tag",e.toString());
            }
        }
    }
    private void copyFile(InputStream in, OutputStream out) throws IOException {
        byte[] buffer = new byte[1024];
        int read;
        while((read = in.read(buffer)) != -1){
          out.write(buffer, 0, read);
        }
    }
    private String rename(String filename,String renFrom,String renTo)
    {
            return filename.replaceAll(renFrom,renTo);
    }

}

 

在编译或链接FFmpeg相关代码时,若遇到与TIFF解码相关的LZMA函数(如`lzma_stream_decoder`、`lzma_code`、`lzma_end`)未定义的引用错误,通常表明FFmpeg在构建时未能正确链接到LZMA库(即XZ库,liblzma)。 此类问题的根本原因可能包括: - 编译FFmpeg时未启用LZMA支持,或者在系统中未安装liblzma开发库; - 编译配置未正确指定依赖库路径或链接参数; - 源码中调用的LZMA API函数版本不匹配或未被正确声明。 ### 解决方法如下: 1. **确保系统中安装了liblzma开发库** 在基于Debian的Linux系统(如Ubuntu)上,可以通过以下命令安装: ```bash sudo apt-get install liblzma-dev ``` 在基于Red Hat的系统(如Fedora、CentOS)上,使用: ```bash sudo dnf install xz-devel ``` 2. **检查FFmpeg的配置是否启用了LZMA** 在配置FFmpeg编译时,确保`--enable-liblzma`选项被包含在内。例如: ```bash ./configure --enable-liblzma --enable-shared ``` 若未启用该选项,则TIFF解码器中涉及LZMA的部分将无法正确链接。 3. **确认TIFF解码器的依赖关系** FFmpeg中的TIFF解码器(`libavcodec/tiff.c`)在启用LZMA压缩支持时,会调用`liblzma`中的函数如`lzma_stream_decoder`、`lzma_code`和`lzma_end`。确保这些函数在所使用的liblzma版本中存在且声明正确。通常,这些函数在`lzma/stream.h`中声明。 4. **检查头文件包含和链接器参数** 确保`tiff.c`中正确包含了`lzma.h`或其他相关头文件,并且在链接阶段`liblzma`被正确链接。例如,在Makefile中链接命令应包含`-llzma`。 5. **清理并重新编译FFmpeg** 在修改配置后,执行以下步骤重新编译以确保更改生效: ```bash make clean make sudo make install ``` 6. **验证FFmpeg是否识别liblzma** 使用以下命令检查FFmpeg是否已正确识别并集成liblzma: ```bash ffmpeg -version ``` 输出中应包含`liblzma`相关信息,表明该库已被启用。 若以上步骤仍无法解决链接错误,建议检查FFmpeg源码与liblzma版本的兼容性,或参考官方文档和社区讨论获取更详细的调试信息。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值