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);   
    }

したがって、私のクラスフィールドでは、バイトではなくビットマップを取得します。読み取りに時間がかかる理由の 1 つは、おそらくビットマップです。ペイントでテストを行いました。2 つの等しい画像を 1 つは BMP で、もう 1 つは JPG で保存しました。JPG画像は2,87KB、BMPは420KB!

上記のコードで、私が得ている結果はありますか? そして、おそらく解決策の1つは次のとおりです

皆さんはどう思いますか?ありがとう。


編集:私は検索していて、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) の解決策よりもさらに、私が抱えていた問題の 1 つは、画像の問題でした。それで、私はそれらを見始め、2000x1800 と 300kb とそれ以上の画像を見て、ここに問題があることをすぐに発見しました。

というわけで、PHPのWebサービスで、画像を半分にリサイズして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";

}

このソリューションにより、47 個のアイテムを1 秒間でロードする時間が大幅に短縮されました!!

4

2 に答える 2

0

この質問の反対側から支援するのは少し難しいですが、いくつかの一般的なヒント:

  1. なんらかのプロファイリングを使用して、速度が低下している部分を特定します。それは問題である実際のカーソルをロードしていますか? それともバイト変換ですか?測定しない限り、それを言うのは難しいです。測定しないと、速度を落とさないものを最適化するために多くの時間を浪費する可能性があります。最も単純なプロファイリングの例:

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

    マーフィー氏がコメントで述べたように、このタスクを支援するツールもあります。Android 開発者サイトには、SDK に含まれている traceview の使用方法を示す素晴らしい投稿があります。

  2. 一般的な知恵は、回避できる場合はデータベースに画像を保存しないことです。代わりにファイルパスを保存してファイルを保存すると、デバッグと作業 (およびシステムのロード) がはるかに簡単になります。

  3. Android の BitmapFactory は JPEG を処理できる必要があります。JPGを使いたい方はご自由にどうぞ

  4. 何かが修正不可能なほど遅い場合は、UI スレッドで実行しないでください。のようなものを使用AsyncTaskして遅い操作を行い、ロードされたときに結果を 1 つずつユーザーに表示します。これは、ユーザーが混乱して待っている間に停止する操作よりも常に望ましい方法です。

于 2013-10-04T16:37:55.963 に答える