Java.lang.OutOfMemoryErrorを取得しているときは、ploadActivity.Java
行番号176は:
Bitmap bm = BitmapFactory.decodeFile(strPath);
ログの表示:
12-07 17:57:10.585: E/AndroidRuntime(16708): FATAL EXCEPTION: main
12-07 17:57:10.585: E/AndroidRuntime(16708): Java.lang.OutOfMemoryError
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.graphics.BitmapFactory.decodeStream(BitmapFactory.Java:650)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.graphics.BitmapFactory.decodeFile(BitmapFactory.Java:389)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.graphics.BitmapFactory.decodeFile(BitmapFactory.Java:449)
12-07 17:57:10.585: E/AndroidRuntime(16708): at com.example.camera.UploadActivity$ImageAdapter.getView(UploadActivity.Java:176)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.widget.AbsListView.obtainView(AbsListView.Java:2465)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.widget.ListView.makeAndAddView(ListView.Java:1775)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.widget.ListView.fillDown(ListView.Java:678)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.widget.ListView.fillFromTop(ListView.Java:739)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.widget.ListView.layoutChildren(ListView.Java:1628)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.widget.AbsListView.onLayout(AbsListView.Java:2300)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.view.View.layout(View.Java:14063)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.view.ViewGroup.layout(ViewGroup.Java:4607)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.widget.RelativeLayout.onLayout(RelativeLayout.Java:948)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.view.View.layout(View.Java:14063)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.view.ViewGroup.layout(ViewGroup.Java:4607)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.widget.FrameLayout.onLayout(FrameLayout.Java:448)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.view.View.layout(View.Java:14063)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.view.ViewGroup.layout(ViewGroup.Java:4607)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.widget.LinearLayout.setChildFrame(LinearLayout.Java:1655)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.widget.LinearLayout.layoutVertical(LinearLayout.Java:1513)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.widget.LinearLayout.onLayout(LinearLayout.Java:1426)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.view.View.layout(View.Java:14063)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.view.ViewGroup.layout(ViewGroup.Java:4607)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.widget.FrameLayout.onLayout(FrameLayout.Java:448)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.view.View.layout(View.Java:14063)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.view.ViewGroup.layout(ViewGroup.Java:4607)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.view.ViewRootImpl.performLayout(ViewRootImpl.Java:1996)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.view.ViewRootImpl.performTraversals(ViewRootImpl.Java:1817)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.view.ViewRootImpl.doTraversal(ViewRootImpl.Java:1114)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.Java:4520)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.view.Choreographer$CallbackRecord.run(Choreographer.Java:725)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.view.Choreographer.doCallbacks(Choreographer.Java:555)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.view.Choreographer.doFrame(Choreographer.Java:525)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.Java:711)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.os.Handler.handleCallback(Handler.Java:615)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.os.Handler.dispatchMessage(Handler.Java:92)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.os.Looper.loop(Looper.Java:137)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.app.ActivityThread.main(ActivityThread.Java:4921)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Java.lang.reflect.Method.invokeNative(Native Method)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Java.lang.reflect.Method.invoke(Method.Java:511)
12-07 17:57:10.585: E/AndroidRuntime(16708): at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:1036)
12-07 17:57:10.585: E/AndroidRuntime(16708): at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:803)
12-07 17:57:10.585: E/AndroidRuntime(16708): at dalvik.system.NativeStart.main(Native Method)
ploadActivity.Java:-
public class ImageAdapter extends BaseAdapter
{
private Context context;
public ImageAdapter(Context c)
{
// TODO Auto-generated method stub
context = c;
}
public int getCount() {
// TODO Auto-generated method stub
return ImageList.size();
}
public Object getItem(int position) {
// TODO Auto-generated method stub
return position;
}
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
public View getView(final int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = inflater.inflate(R.layout.list_upload, null);
}
// ColImgName
TextView txtName = (TextView) convertView.findViewById(R.id.ColImgName);
strPath = ImageList.get(position).toString();
// Get File Name
fileName = strPath.substring( strPath.lastIndexOf('/')+1, strPath.length() );
File file = new File(strPath);
@SuppressWarnings("unused")
long length = file.length();
txtName.setText(fileName);
// Image Resource
ImageView imageView = (ImageView) convertView.findViewById(R.id.ColImgPath);
Bitmap bm = BitmapFactory.decodeFile(strPath);
imageView.setImageBitmap(bm);
// ColStatus
final ImageView txtStatus = (ImageView) convertView.findViewById(R.id.ColStatus);
txtStatus.setImageResource(R.drawable.bullet_button);
// progressBar
final ProgressBar progress = (ProgressBar) convertView.findViewById(R.id.progressBar);
progress.setVisibility(View.GONE);
//btnUpload
final ImageButton btnUpload = (ImageButton) convertView.findViewById(R.id.btnUpload);
btnUpload.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Upload
btnUpload.setEnabled(false);
startUpload(position);
}
});
return convertView;
}
}
Bitmapオブジェクトをリサイクルする必要があります。
Bitmap bm = BitmapFactory.decodeFile(strPath);
imageView.setImageBitmap(bm);
Getビューの上記のコード行の後に、以下に記述されたコードを追加するだけです////今ビットマップをリサイクルすることで、すべての反復でメモリが解放されます
if(bm!=null)
{
bm.recycle();
bm=null;
}
この後、同じエラーが発生している場合も、
以下のコードを置換
Bitmap bm = BitmapFactory.decodeFile(strPath);
imageView.setImageBitmap(bm);
と
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 8;
Bitmap bm = BitmapFactory.decodeFile(strPath,options);
imageView.setImageBitmap(bm);
InSampleSizeを使用して、スケールビットマップをメモリにロードします。 inSampleSizeの値に2のべき乗を使用すると、デコーダーでより高速で効率的になります。ただし、サイズを変更したバージョンをメモリまたはディスクにキャッシュする場合は、通常、スペースを節約するために最適な画像サイズにデコードする価値があります。
詳細については、「読み込み 効率的な大きなビットマップ 」を参照してください
Applicationタグのマニフェストファイルでこれを使用します
Android:largeHeap="true"
ビットマップを呼び出す前bm = BitmapFactory.decodeFile(strPath);
これを呼び出します。Bitmap bm = decodeSampledBitmapFromResource(strPath、reqWidth、reqHeight);
再度Java.lang.OutOfMemoryErrorが発生した場合はお知らせください
public static int calculateInSampleSize(BitmapFactory.Options options,
int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and
// keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
public static Bitmap decodeSampledBitmapFromResource(String strPath,int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(strPath, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options,reqWidth,
reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(strPath, options);;
}
これは、アプリケーションの最適化の問題です。 BitmapFactory.decodeFile(strPath)Android=はそのビットマップにメモリを割り当てようとしているため、システムが割り当てる十分な空き容量を見つけられないため、OutOfMemoryErrorが発生しています。このエラーが発生しています。
コードからわかるように、ImageAdapterを使用して画像のリストを表示しようとしています。その場合、imageviewは実際の画像よりも小さい幅と高さでなければなりません。
より一般化されたアイデアを提供するために、ここで何が起こっているのかを示します。
このシナリオでは、imageviewのwidth-heightは100 * 100ですが、背景として800 * 800の画像を設定しようとしています。そして、これは間違いなく効率的な方法ではありません。なぜなら、システムは800 * 800ピクセルの画像にメモリを割り当てるのに対し、100 * 100はそうだからです。
そのため、ビットマップのデコードを行う前に、ビットマップをサンプリングして、100 * 100相当のメモリのみが割り当てられるようにする必要があります。
この説明のより詳細なバージョンがあります here
同じ問題がありました。上記のすべての提案を取り入れましたが、Java.lang.outOfMemoryErrorの問題がまだありました。多くの調整を行った後、最終的に機能したのは画像のサイズ(およびサイズ)の縮小でした。もともと、800 x 1000の次元の画像がありました。私はそれらを約60 x 80に再スケーリングし(それが必要だったので)、それはうまくいきました!
したがって、この問題についてstackoverflowや他のサイトで得られるすべてのアドバイスに従うことに加えて、画像のサイズと寸法の草の根チェックも行ってください。頭痛の種を大幅に減らします。