BitmapのOutOfMemoryErrorと戦った

画像処理はできるようになったので次はSDから画像を読み込んで画像処理をしたいなと思って挑戦


AndroidにはGalleryってのがあって端末に含まれている画像を収集して一覧として表示してくれる機能がある
そこからインテントを受け取ればどの画像が選択されたか簡単に分かるはずなのだが・・・
※Galleryについてはこちら
http://www.conit.co.jp/labs/index.php?e=255

package com.tkado.sdtest;

import java.io.*;
/*省略*/

public class SD_test extends Activity {
	final int REQUEST_PICK_CONTACT=99;
	Bitmap mBitmap;
	ImageView image;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        image=(ImageView)findViewById(R.id.ImageView01);
        String inputname="/sdcard/test2.txt";
        try{
	        byte[] buf = new byte[ (int) new File( inputname ).length() ];
	        BufferedInputStream f = new BufferedInputStream( new FileInputStream( inputname ) );
	        f.read( buf );
	        f.close();
	        TextView txt=(TextView)findViewById(R.id.TextView01);
	        String s=new String(buf, "SJIS");
	        txt.setText(s);
        }
        catch( IOException e){
        	TextView txt=(TextView)findViewById(R.id.TextView01);
			txt.setText("ERROR:"+inputname);
        }
        Button button1=(Button)findViewById(R.id.Button01);
        button1.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				// TODO 自動生成されたメソッド・スタブ
				// インテント設定
				Intent intent = new Intent(Intent.ACTION_PICK);
				// とりあえずストレージ内の全イメージ画像を対象
				intent.setType("image/*");
				// ギャラリー表示
				startActivityForResult(intent, REQUEST_PICK_CONTACT);
			}
		});

    }
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    	// TODO Auto-generated method stub
    	super.onActivityResult(requestCode, resultCode, data);
    	Log.d("tag","onActivity");
    	if(requestCode == REQUEST_PICK_CONTACT){
	    	//Content Providerとは、全てのアプリケーションからデータの読み書きが可能なオブジェクトで、パッケージ間でデータ共有を行う唯一の手段
    		Log.d("tag","inif");
	    	Uri photoUri = data.getData();
	    	ContentResolver cont_reslv = getContentResolver();
	    	if (photoUri != null) {
		    	try {
		    		if(mBitmap!=null){
		    			mBitmap.recycle();
		    			mBitmap=null;
		    		}
		    		mBitmap = MediaStore.Images.Media.getBitmap(cont_reslv, photoUri);

		    		image.setImageBitmap(mBitmap);
		    	} catch (Exception e) {
		    		e.printStackTrace();
		    	}
	    	}
    	}

    }
}


このコードのキモはここ

if(mBitmap!=null){
 	mBitmap.recycle();
	mBitmap=null;
}

これがないとOutOfMemoryErrorが出てきてどうしようもなかった


ここらへんがかなり参考になった
http://groups.google.com/group/android-group-japan/browse_thread/thread/fa40fe4d250541f5
http://mtnk.org/down/PDF/OutOfMemoryError.pdf

なんとか画像の切り替えができるようになったので
次は画像処理をしてSDへの保存、カメラアプリとの連動、メールアプリとの連動辺りをやりたいな
実はOutOfMemoryErrorもネイティブコードを使えば簡単に回避できるらしいね