1

画像を開いて再生し、保存するプロジェクトに取り組んでいます。画像はカメラの写真のように非常に巨大な画像になる可能性があるため、OutOfMemory 例外が発生しないようにするためにいくつかのことを行っています (基本的にここに表示されるものhttp://developer.android.com/training/displaying-bitmaps/load- bitmap.html ):

  • 以下を使用して、実際に画像を開かずに、画像の幅と高さのすべての測定を実行します。
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(image_path, options);
  • 既にサイズ変更済み ( inSampleSize ) で、 (ピクセルあたり 4B Bitmap.Config.RGB_565) に加えて (ピクセルあたり 2B ) を使用している画像を開きます。Bitmap.Config.ARGB_8888

  • 一時ファイルを使用して、メモリに多くのビットマップを持たないようにします(実際には、ほとんどの場合、マスクを適用する場合は最大2つしかありません)。

  • 使用後のすべてのビットマップのリサイクル

  • 結果を で表示する場合は、ImageView既に画面サイズに合わせて拡大縮小して開きます。

しかし、場合によっては、特定の作業 (画像の回転、サイズ変更の微調整、マスクの適用など) を行うために一度に 1 つのビットマップのみをロードすることが不可能な場合や、主に中距離または古いデバイスで、私はOutOfMemory Exceptionを取得します。

次のようなものを使用して、バックグラウンド ジョブで動作するすべての画像を追加し始めました (わかりました、私は初心者です)。

ProgressDialog dialog = ProgressDialog.show(this, null, "Please wait", true, false);
new Thread(new BackgroundJob(this, new Runnable() {
    public void run() {
        ImageHelper.ImageManipulation(image_path); 
    }
}, dialog, new Handler())).start();

この新しいスレッドで完全にメモリの空き領域を確保して画像操作タスクを実行したいと思っていましたが、同じ理由で同じポイントでアプリがクラッシュすることがわかりました。スレッドは子プロセスとして作成されます (ok) が、最大ヒープと現在使用されているメモリを共有しています ...

スレッドを開いて、より多くのメモリを使用して画像操作を実行する方法はありますか (たとえば、別のスレッドであるため、アクティビティ自体で使用されているメモリを解放します)。

どうもありがとうございました。

4

2 に答える 2

3

Android デバイスでのメモリ管理に関しては、多くの落とし穴があります。特に、さまざまなデバイスを混在させる場合はそうです。昨年、私が作成したさまざまな Android アプリでメモリ管理をいじって無駄にしましたが、Android-BitmapCache プロジェクトを見つけるまで、大きな進歩はありませんでした。

Android メモリ管理に関心のあるすべての人に、Android-BitmapCache プロジェクトをダウンロードして調べることをお勧めします。このプロジェクトには優れたコードが含まれているため、最初のステップとしてそれを行ってください。

2 番目のステップとして、Google I/O: Memory Management for Android Apps を主に見て、アプリケーションがメモリをどれだけ使用しているかを正確にテストし、正確にメモリ使用量が増加し始めた場所を追跡することをお勧めします。それについて言えば、「新しいスレッドで完全にメモリの空き領域が得られる」と考える理由がわかりません.Androidアプリから生成するすべてのスレッドは同じプロセスの下にあるため、どのスレッドが正確であるかは問題ではありませんメモリ使用量に関しては、スレッドが何らかのタスクを実行しています。

最後に、 android:largeHeap="true"を使用して問題を一時的に修正できますが、より堅牢なソリューションを目指すべきだと思います。一部のデバイスでは、アプリが機能しない可能性があることに注意してください (24MB ヒープで、3000x3000 の画像をロードしたい場合) はるかに良くなります。

于 2013-03-10T10:44:32.073 に答える
1

プールスレッドを使用して複数のスレッドを実行できます。これは、スレッドごとに新しい Thread オブジェクトを作成するよりも「費用がかからない」方法です。

このガイドが役立つかもしれません: http://developer.android.com/training/multiple-threads/create-threadpool.html

または、この http://android-developers.blogspot.com/2009/05/painless-threading.html

于 2013-03-10T10:44:00.680 に答える