안드로이드 개발 질문/답변
(글 수 45,052)
package kp.apptime.school;
import java.io.File; import java.io.FileOutputStream; import java.text.SimpleDateFormat; import java.util.GregorianCalendar;
import android.app.Activity; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.Bitmap.CompressFormat; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.provider.MediaStore; import android.util.Log; import android.view.View; import android.view.Window; import android.widget.Button; import android.widget.ImageView;
public class MyWrite extends Activity {
private static final String TAG = "PunchPunch"; Bitmap bitmap; String nowTime = ""; private int yh = 0; String url = ""; private static final int PICK_FROM_CAMERA = 0; private static final int PICK_FORM_ALBUM = 1; private static final int CROP_FROM_CAMERA = 2; private Uri imgUri; ImageView imgview;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.write);
imgview = (ImageView)findViewById(R.id.imgview);
imgview.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
v.setVisibility(View.INVISIBLE);
}
});
Button btncamera=(Button)findViewById(R.id.btncamera);
btncamera.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
//onActivityResult(REQ_CODE_PICK_PICTURE, REQ_CODE_PICK_PICTURE, cameraIntent);
// Intent intent = new Intent(CallPhotoActivity.this,BeforeGameActivity.class);
// intent.putExtra("select", 1);
// startActivity(intent);
doTakePhotoAction();
GregorianCalendar cal = new GregorianCalendar();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMHHmmss");
nowTime= dateFormat.format(cal.getTime());
url = nowTime + ".jpg";
// writeBitmap(bitmap);
// imgview.setVisibility(View.VISIBLE);
}
});
Button btnalbum=(Button)findViewById(R.id.btnalbum);
btnalbum.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v){
//onActivityResult(REQ_CODE_PICK_PICTURE, REQ_CODE_PICK_PICTURE,intent);
// Intent intent1 = new Intent(CallPhotoActivity.this,BeforeGameActivity.class);
// intent1.putExtra("select", 2);
// startActivity(intent1);
doTakeAlbumAction();
GregorianCalendar cal = new GregorianCalendar();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMHHmmss");
nowTime= dateFormat.format(cal.getTime());
url = nowTime + ".jpg";
// writeBitmap(bitmap);
// imgview.setVisibility(View.VISIBLE);
}
});
}
private void doTakePhotoAction(){
String DirPath = "";
DirPath = Environment.getExternalStorageDirectory().toString();
DirPath = DirPath + "/punchpunch/";
File cameraDir = new File(DirPath);
if( !cameraDir.exists() ){
cameraDir.mkdirs();
}
imgUri = Uri.fromFile(new File(DirPath, url));
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, imgUri );
intent.putExtra("return-data", true);
startActivityForResult(intent, PICK_FROM_CAMERA);
}
private void doTakeAlbumAction(){
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType(android.provider.MediaStore.Images.Media.CONTENT_TYPE);
startActivityForResult(intent, PICK_FORM_ALBUM);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(resultCode != RESULT_OK){
return;
}
switch(requestCode){
case CROP_FROM_CAMERA :
final Bundle extras = data.getExtras();
if(extras != null){
Bitmap photo = extras.getParcelable("data");
imgview.setImageBitmap(photo);
}
imgview.setDrawingCacheEnabled(true);
bitmap = imgview.getDrawingCache();
writeBitmap(bitmap);
imgview.setVisibility(View.VISIBLE);
Log.v(TAG, "test : " + bitmap);
break;
case PICK_FORM_ALBUM :
imgUri = data.getData();
case PICK_FROM_CAMERA :
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(imgUri, "image/*");
intent.putExtra("outputX", 290);
intent.putExtra("outputY", 390);
intent.putExtra("aspectX", 290);
intent.putExtra("aspectY", 390);
intent.putExtra("scale", true);
intent.putExtra("return-data", true);
startActivityForResult(intent, CROP_FROM_CAMERA);
break;
}
Log.v(TAG, "경로 : " + url);
}
public void writeBitmap( Bitmap bitmap )
{
GregorianCalendar cal = new GregorianCalendar();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMHHmmss");
nowTime= dateFormat.format(cal.getTime());
url = nowTime + ".jpg";
FileOutputStream out = null;
String DirPath = "";
File f = null;
try{
DirPath = Environment.getExternalStorageDirectory().toString();
DirPath = DirPath + "/punchpunch/";
File foodDir = new File(DirPath);
if( !foodDir.exists() ){
foodDir.mkdirs();
}
f = new File(foodDir, url);
url= f.getAbsolutePath();
out = new FileOutputStream( f );
bitmap.compress(CompressFormat.JPEG, 100, out);
}catch (Exception e){
Log.w(TAG, "error : " + e);
}
finally{
try{
out.close();
}catch ( Exception e){}
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
Uri.parse("file://" +f.getAbsolutePath() )));
}
}
}
로그켓입니다
11-16 17:14:58.549: D/skia(21595): SHAPER: stream created /data/data/com.jungle.app.fonts/tmp/SJbangu.ttf.. 0x129E40
11-16 17:15:05.989: E/dalvikvm-heap(21595): 214265524-byte external allocation too large for this process.
11-16 17:15:06.029: E/GraphicsJNI(21595): VM won't let us allocate 214265524 bytes
11-16 17:15:06.029: D/skia(21595): --- decoder->decode returned false
11-16 17:15:06.029: W/dalvikvm(21595): threadid=1: thread exiting with uncaught exception (group=0x40018560)
11-16 17:15:06.049: E/AndroidRuntime(21595): FATAL EXCEPTION: main
11-16 17:15:06.049: E/AndroidRuntime(21595): java.lang.RuntimeException: Unable to start activity ComponentInfo{kp.apptime.school/kp.apptime.school.MyWrite}: android.view.InflateException: Binary XML file line #23: Error inflating class <unknown>
11-16 17:15:06.049: E/AndroidRuntime(21595): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1647)
11-16 17:15:06.049: E/AndroidRuntime(21595): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
11-16 17:15:06.049: E/AndroidRuntime(21595): at android.app.ActivityThread.access$1500(ActivityThread.java:117)
11-16 17:15:06.049: E/AndroidRuntime(21595): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
11-16 17:15:06.049: E/AndroidRuntime(21595): at android.os.Handler.dispatchMessage(Handler.java:99)
11-16 17:15:06.049: E/AndroidRuntime(21595): at android.os.Looper.loop(Looper.java:130)
11-16 17:15:06.049: E/AndroidRuntime(21595): at android.app.ActivityThread.main(ActivityThread.java:3683)
11-16 17:15:06.049: E/AndroidRuntime(21595): at java.lang.reflect.Method.invokeNative(Native Method)
11-16 17:15:06.049: E/AndroidRuntime(21595): at java.lang.reflect.Method.invoke(Method.java:507)
11-16 17:15:06.049: E/AndroidRuntime(21595): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:864)
11-16 17:15:06.049: E/AndroidRuntime(21595): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:622)
11-16 17:15:06.049: E/AndroidRuntime(21595): at dalvik.system.NativeStart.main(Native Method)
11-16 17:15:06.049: E/AndroidRuntime(21595): Caused by: android.view.InflateException: Binary XML file line #23: Error inflating class <unknown>
11-16 17:15:06.049: E/AndroidRuntime(21595): at android.view.LayoutInflater.createView(LayoutInflater.java:518)
11-16 17:15:06.049: E/AndroidRuntime(21595): at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:56)
11-16 17:15:06.049: E/AndroidRuntime(21595): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:568)
11-16 17:15:06.049: E/AndroidRuntime(21595): at android.view.LayoutInflater.rInflate(LayoutInflater.java:623)
11-16 17:15:06.049: E/AndroidRuntime(21595): at android.view.LayoutInflater.inflate(LayoutInflater.java:408)
11-16 17:15:06.049: E/AndroidRuntime(21595): at android.view.LayoutInflater.inflate(LayoutInflater.java:320)
11-16 17:15:06.049: E/AndroidRuntime(21595): at android.view.LayoutInflater.inflate(LayoutInflater.java:276)
11-16 17:15:06.049: E/AndroidRuntime(21595): at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:231)
11-16 17:15:06.049: E/AndroidRuntime(21595): at android.app.Activity.setContentView(Activity.java:1657)
11-16 17:15:06.049: E/AndroidRuntime(21595): at kp.apptime.school.MyWrite.onCreate(MyWrite.java:42)
11-16 17:15:06.049: E/AndroidRuntime(21595): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
11-16 17:15:06.049: E/AndroidRuntime(21595): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
11-16 17:15:06.049: E/AndroidRuntime(21595): ... 11 more
11-16 17:15:06.049: E/AndroidRuntime(21595): Caused by: java.lang.reflect.InvocationTargetException
11-16 17:15:06.049: E/AndroidRuntime(21595): at java.lang.reflect.Constructor.constructNative(Native Method)
11-16 17:15:06.049: E/AndroidRuntime(21595): at java.lang.reflect.Constructor.newInstance(Constructor.java:415)
11-16 17:15:06.049: E/AndroidRuntime(21595): at android.view.LayoutInflater.createView(LayoutInflater.java:505)
11-16 17:15:06.049: E/AndroidRuntime(21595): ... 22 more
11-16 17:15:06.049: E/AndroidRuntime(21595): Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget
11-16 17:15:06.049: E/AndroidRuntime(21595): at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
11-16 17:15:06.049: E/AndroidRuntime(21595): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:460)
11-16 17:15:06.049: E/AndroidRuntime(21595): at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:336)
11-16 17:15:06.049: E/AndroidRuntime(21595): at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:697)
11-16 17:15:06.049: E/AndroidRuntime(21595): at android.content.res.Resources.loadDrawable(Resources.java:1709)
11-16 17:15:06.049: E/AndroidRuntime(21595): at android.content.res.TypedArray.getDrawable(TypedArray.java:601)
11-16 17:15:06.049: E/AndroidRuntime(21595): at android.view.View.<init>(View.java:1958)
11-16 17:15:06.049: E/AndroidRuntime(21595): at android.view.View.<init>(View.java:1899)
11-16 17:15:06.049: E/AndroidRuntime(21595): at android.view.ViewGroup.<init>(ViewGroup.java:286)
11-16 17:15:06.049: E/AndroidRuntime(21595): at android.widget.RelativeLayout.<init>(RelativeLayout.java:173)
11-16 17:15:06.049: E/AndroidRuntime(21595): ... 25 more
머가잘못된걸까요 ...
2011.11.16 17:32:23
CompressFormat.JPEG는 파일명이 아니고 상수입니다. ㄷㄷㄷㄷ
보통 이러면 찍은 사진이 크던가.... 아니면 찍은 사진을 복제하는 과정에서
복제본을 너무 많이 만들고 recycle을 안해서 죽는겁니다.
넥원, 겔S 부터 그 이후의 폰들은 사진 촬영후 원본크기로 메모리에 3~4개정도 들고 있으면 그냥 죽습니다.
크기를 줄이던가 객체를 관리를 잘하시던가 둘중 하나입니다.
2011.11.17 17:28:33
지금 상황에 대한 설명도 부족하고, 그냥 코드와 로그만 올려두고 정확한 해결책을 제시해달라고 하시는건 약간 무리라고 봅니다.
해당 오류의 재현경로와 횟수, 그리고 그 당시 어플을 진입하기전에 진행했었던 경로 등을 파악하시고,
각 진행 부분에서 NativeHeap 증가를 체크해서 어느부분에서 메모리릭이 있었는지, 아니면 어느 이미지 하나가 어마어마하게
커서 생긴 문제인지 등을 확인해야하는 문제입니다.
한마디로 해결하기 위해서는 코드뿐만 아니라 리소스까지 모든 걸 다 가지고 하나하나 체크해야한다는 소리입니다.
근데 다들 자기 일이 있는 상황에서 그런걸 하는건 힘들겠죠
일단 원인은 메모리 이슈이고, Bitmap의 경우, Native Heap을 사용하기 때문에 그 부분을 체크해야한다는 정도.
이 정도가 다른 분들이 도와드릴 수 있는 영역이고, 나머지는 본인이 스스로 시간을 들여 해결해야하는 부분입니다.




Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget ... 리소스 중 하나가 너무 큰가본데요