3

我正在寻找解决方案,从 SQLite 加载 20 个项目的速度超过 5 秒(这是我现在正在加载的秒数。) - 首先,我使用的是自定义 Listview 适配器。

我在 1 秒内加载了 5 个项目。我尝试加载 20 个项目,并在 5 秒内加载它们。这是我从数据库中检索的字段:int、String、String、int、Bytes、float、int。

您可能会想,在获取字节后,我将它们转换为位图。

Bitmap image = convertBlobToImage(cursor.getBlob(4));
// Using this function:
  public Bitmap convertBlobToImage(byte[] value){
        byte[] new_value = Base64.decode(value, 0);
        return BitmapFactory.decodeByteArray(new_value, 0, new_value.length);   
    }

因此,在我的类字段中,他们将获得的不是字节,而是位图。阅读时间长的原因之一可能是位图。我刚刚对Paint进行了测试。我保存了两个相同的图像,一个在 BMP 中,另一个在 JPG 中。JPG 图像大小为 2,87KB,BMP 大小为420KB!!

使用上面的代码,我得到的结果是什么?可能的解决方案之一可能是:http ://www.mkyong.com/java/how-to-convert-byte-to-bufferedimage-in-java/ ?

你们有什么感想?谢谢。


编辑:我在搜索,发现关于 onDestroy()。我也没有实现“runOnUiThread”,我就是这样说的。但我认为这并没有给我带来更好的结果。你怎么看?这能提高性能吗?

  @Override
    protected void onDestroy() {
        super.onDestroy();
        listView.setAdapter(null);
    }
// And I also tried to put runOnUiThread:
runOnUiThread(new Runnable() {
             @Override
             public void run() {
                 Bundle extras = getIntent().getExtras();
                 if (extras != null) {
                     DatabaseHandler db = new DatabaseHandler(Produtos.this);
                     display_products = db.get_all_oc_product(extras.getString("category_id"));

                     listView = (ListView) findViewById(R.id.product_listview);
                     inputSearch = (EditText) findViewById(R.id.product_inputSearch);

                     adapter = new itemAdapter(Produtos.this,R.layout.row, display_products);
                     listView.setAdapter(adapter);
                 }
             }
         });

编辑(2):我设法将显示 20 个项目的时间减少了 3 秒。我通过在查询后关闭与数据库的所有连接来实现这一点。我没有正确地做到这一点。正确方法:

cursor db.query(...)
try{
 // Code
} finally {
  cursor.close();
  db.close();
}

编辑(3):除了编辑(2)的解决方案之外,我遇到的问题之一是图像问题。所以,我开始看它们,我看到了 2000x1800 和 300kb 甚至更大的图像,我很快发现问题就在这里。

因此,在 PHP 网络服务中,我开发了一个函数来将图像大小调整为一半并将它们转换为 jpg。

function resize($filePath){
    list($width, $height) = getimagesize($filePath);

    $percent = 0.5;

        $newwidth = $width * $percent;
        $newheight = $height * $percent;

        $thumb = imagecreatetruecolor($newwidth, $newheight);

        $ext = pathinfo($filePath, PATHINFO_EXTENSION);
        $source = null;

        if($ext == "png"){
            $source = imagecreatefrompng($filePath);
        }else if($ext == "jpg" || $ext == "jpeg"){
            $source = imagecreatefromjpeg($filePath);
        }

        // Resize
        imagecopyresized($thumb, $source, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);

        // Output
        $temporary = "C:\\xampp\\htdocs\\MyExample\\images\\temporary\\" . basename($filePath);
        imagejpeg($thumb, $temporary . ".jpg", 50);
        ImageDestroy($thumb);

        return $temporary . ".jpg";

}

使用这个解决方案,我减少了惊人的 1 秒加载 47 个项目的时间!!

4

2 回答 2

0

我建议您检查其中一个java.nio.*包以加载您的图像。NIO是非阻塞的,这意味着您可以异步加载图像,从而每次完成更多的工作。

NIO还使用了系统上的本机缓冲区(在 jvm 之外),因此它可以防止 java 必须将内容读入它的堆,这再次使事情变得更快(本机)。在这里使用还有很多好处NIO

于 2013-10-04T16:46:23.570 回答
0

好吧,从这个问题的另一面提供帮助有点困难,但有一些通用提示:

  1. 使用某种类型的分析来确定哪个部分让你放慢了速度。是否加载实际的光标是一个问题?还是字节转换?除非您进行测量,否则很难说 - 否则您可能会浪费大量时间优化不会减慢您速度的东西。最简单的分析示例:

    long startTime = SystemClock.elapsedRealTime();
    suspectedSlowFunctionCall();
    long endTime = SystemClock.elapsedRealTime();
    Log.d(TAG, "Method duration: " + (endTime - startTime));
    

    正如 Murphy 先生在评论中提到的,还有一些工具可以帮助您完成这项任务。android 开发者网站有一篇很棒的文章展示了如何使用包含在 SDK 中的 traceview。

  2. 如果可以避免的话,一般的智慧是不要将图像存储在数据库中。如果您存储文件路径并保存文件,则调试和使用(以及系统加载)会容易得多。

  3. Android 的 BitmapFactory 应该能够处理 JPEG。如果您想使用 JPG,请随意

  4. 如果某些事情非常缓慢,请不要在 UI 线程上执行此操作!使用类似 an 的东西AsyncTask来执行缓慢的操作,并在加载时将结果一一显示给用户。这总是比在用户等待困惑时停止的操作更可取。

于 2013-10-04T16:37:55.963 回答