【问题标题】:Correct use of Android SQLiteStatement's simpleQueryForBlobFileDescriptor()正确使用Android SQLiteStatement的simpleQueryForBlobFileDescriptor()
【发布时间】:2011-10-26 05:10:43
【问题描述】:

Android 的 SQLiteStatement 中的 simpleQueryForBlobFileDescriptor() 函数对我来说是个谜。而且似乎没有人在任何地方使用它。似乎这对于单个 blob 访问来说是一种快速的方法,并且在性能方面(如果要相信文档),当用于从数据库中流式传输 blob 数据时,SQLiteStatement 和 Parcel 的组合应该会产生非常快的结果.我不知道,因为我无法让这个东西工作,所以我可以测试......任何关于这个或见解的帮助将不胜感激:

SQLiteStatement get = mDb.compileStatement(
    "SELECT blobColumn" + 
    " FROM tableName" +
    " WHERE _id = 1" +
    " LIMIT 1"
);

ParcelFileDescriptor result = get.simpleQueryForBlobFileDescriptor();
// now what?

我可能应该注意到我正在使用并且只真正关心 Honeycomb (3.2),并提前感谢您的任何见解。

【问题讨论】:

    标签: android sqlite android-3.0-honeycomb


    【解决方案1】:
    SQLiteStatement get = mDb.compileStatement(
        "SELECT blobColumn" + 
        " FROM tableName" +
        " WHERE _id = 1" +
        " LIMIT 1"
    );
    
    ParcelFileDescriptor result = get.simpleQueryForBlobFileDescriptor();
    FileInputStream fis = new FileInputStream(result.getFileDescriptor()); // read like any other
    

    我可以验证这对于我的用例来说非常快。

    我发现这特别有用的地方(如果您需要像我一样创建自己的自定义离线 webview 文件缓存)是在内容提供者的 openFile 覆盖中,您可以直接返回描述符(或者理想情况下覆盖 openTypedAssetFile( ))

    示例: files 是一个 DB 助手,getFileDescriptor(String) 类似于上面的代码

    public AssetFileDescriptor openTypedAssetFile(Uri uri, String mimeTypeFilter, android.os.Bundle opts) throws FileNotFoundException {
        ParcelFileDescriptor pfd = files.getFileDescriptor(uri.toString());
        if (pfd != null) {
            return new AssetFileDescriptor(pfd, 0, AssetFileDescriptor.UNKNOWN_LENGTH);
        }
        return null;
    }
    

    或类似问题的另一个很好的用途: (您希望将自定义文件从 db 提供给 webview)

    private WebViewClient webViewClient = new WebViewClient() {
        @Override
        public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
    
            ParcelFileDescriptor pfd = files.getFileDescriptor(url);
            if (pfd != null) {
                return new WebResourceResponse(null, null, new FileInputStream(pfd.getFileDescriptor()));
            }
    
            return null; 
        }
    

    【讨论】:

    • 祝贺解决方案。如果有能力,请将您的答案标记为“已接受”,以便其他人可以从您的成功中学习。干杯~
    • “我可以验证这对于我的用例来说非常快。”。我做了一些测试,我认为它比使用带有 c.getBlob() 的简单游标要慢;在stackoverflow.com/questions/21915552/…中查看我的测试
    • @user1344545 尝试在不使用simpleQueryForBlobFileDescriptor() 的情况下执行我演示的操作,结果大约慢了 5-10 倍,事实上,没有它的版本基本上无法使用,至少在我写这篇文章的时候...
    猜你喜欢
    • 1970-01-01
    • 2014-03-21
    • 1970-01-01
    • 1970-01-01
    • 2015-03-15
    • 2013-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多