Android:使用setImageURI时导致OOM的内存泄漏

时间:2011-12-14 08:05:04

标签: java android imageview out-of-memory bitmapfactory

我只用java编程了几天所以要温柔......:P

我的应用程序使用SQLite数据库来保存需要用户提供的文本,照片和位置的不同“项目”。问题是,在浏览某些项目时,加载

时会发生Out of Memory-exception
  

myImage.setImageURI(Uri.parse(msavePicture));

第五次第四次。使用DDMS时,您可以看到每个新负载分配的内存增加约0.2Mbyte。我已经搜索了问题,并尝试使用

  

myImage.setImageDrawable(空);

但问题仍然存在。我也尝试将代码更改为

  myBitmap = BitmapFactory.decodeFile(msavePicture);
  ImageView myImage = (ImageView) this.findViewById(R.id.camera_preview);
  myImage.setImageBitmap(myBitmap);   

所以我可以使用.recycle();但是图片doesent load,它返回null。 msavePicture是一个如下所示的字符串:

  

文件:///mnt/sdcard/MyCameraApp/IMG_2011-12-09-01-49.jpg

我已经包括

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

在清单中,我知道图片存在,因为使用setImageURI时它可以工作。

所以问题是:我做错了什么导致内存泄漏,如何真正破坏ImageView,或者为什么Bitmapfactory不能解码我的字符串,文件位置是错误的?

为了以防万一,我已经包含了很多活动。关于此的任何解决方案或链接将不胜感激!

提前致谢!

(PS:如果有人知道如何将SQLite数据库保存到服务器以便您可以使用它来更新其他手机,那么也非常感谢!=):DS)

  public class Page3 extends Activity {
private static final int ACTIVITY_CREATE = 0;
public static Long Row = (long) 40;
public static String summarydec = "FAIL";
public static String msavePicture;
public static Location loc;
private EditText mgps_lati;
private EditText mgps_long;
static String gps_long;
static String gps_lati;
private TodoDbAdapter mDbHelper;
public Location myLocation;
public static Bitmap myBitmap;
public Uri uBitmap;


@Override
protected void onCreate(Bundle bundle) {
    super.onCreate(bundle);
    mDbHelper = new TodoDbAdapter(this);
    mDbHelper.open();
    setContentView(R.layout.camera);


        if(msavePicture == null){
        msavePicture = "";
    }
 //     myBitmap = BitmapFactory.decodeFile(msavePicture);
 //     ImageView myImage = (ImageView) this.findViewById(R.id.camera_preview);
 //     myImage.setImageBitmap(myBitmap);       

    ImageView myImage = (ImageView) this.findViewById(R.id.camera_preview);
    myImage.setImageURI(Uri.parse(msavePicture));

    mgps_long = (EditText) findViewById(R.id.gps_long); 
    mgps_lati = (EditText) findViewById(R.id.gps_lati);
    mgps_lati.setText("Latitude:  "+gps_lati);
    mgps_long.setText("Longitude: "+gps_long);
    ////////////////////////////////////////////////////////////
    ///// G P S  -  L Y S S N A R E ////////////////////////////
    ////////////////////////////////////////////////////////////    
    MyLocation myLocation = new MyLocation();
    myLocation.getLocation(this, locationResult);

    Button gps = (Button) findViewById(R.id.gps);
    gps.setOnClickListener(new View.OnClickListener() {
        public void onClick(View view) {

            if (gps_lati != null && gps_long != null) {
                mgps_lati.setText("Latitude:  " +gps_lati);
                mgps_long.setText("Longitude: " +gps_long);
                TodoDetails.save_gps_long = gps_long;
                TodoDetails.save_gps_lati = gps_lati;
                Page1.save_gps_long = gps_long;
                Page1.save_gps_lati= gps_lati;
                Page2.save_gps_long = gps_long;
                Page2.save_gps_lati= gps_lati;
                } else {
                    String Latitude = "Fel vid GPS-hanteringen, arra det!";
                    String Longitude = "Fel vid GPS-hanteringen, arra det!";
                    mgps_lati.setText(Latitude);
                    mgps_long.setText(Longitude);
                }
        }});
    ////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////

    Button camera = (Button) findViewById(R.id.camera);
    camera.setOnClickListener(new View.OnClickListener() {
        public void onClick(View view) {                
            createCamera();
        }});

    Button confirmButton = (Button) findViewById(R.id.todo_edit_button);
    confirmButton.setOnClickListener(new View.OnClickListener() {
        public void onClick(View view) {                
            setResult(RESULT_OK);
            TodoDetails.mPIC = msavePicture;
            Page1.mPIC = msavePicture;
            Page2.mPIC = msavePicture;
            ImageView myImage = (ImageView) findViewById(R.id.camera_preview);
            myImage.setImageDrawable(null);
 //             myBitmap.recycle();
            cancelTimer();
            finish();
        }

    });
}
protected void onPause() {
    super.onPause();
    cancelTimer();
    ImageView myImage = (ImageView) findViewById(R.id.camera_preview);
    myImage.setImageDrawable(null);

}
protected void cancelTimer()
{
    MyLocation myLocation = new MyLocation();
    myLocation.cancelTimer();   
}
protected void onActivityResult(int requestCode, int resultCode,
        Intent intent) {
    super.onActivityResult(requestCode, resultCode, intent);
    cancelTimer();  
    ImageView myImage = (ImageView) findViewById(R.id.camera_preview);
    myImage.setImageURI(Uri.parse(msavePicture));

 //     ImageView myImage = (ImageView) this.findViewById(R.id.camera_preview);
 //     myBitmap = BitmapFactory.decodeFile(msavePicture);
 //     myImage.setImageBitmap(myBitmap);

}
public void onBackPressed (){
    cancelTimer();  
    ImageView myImage = (ImageView) findViewById(R.id.camera_preview);
    myImage.setImageDrawable(null);
 //     Bitmap myBitmap = Page3.myBitmap;
//      myBitmap.recycle();
    finish();
}
////////////////////////////////////////////////////
////////////// A L L A   V Y E R ///////////////////
////////////////////////////////////////////////////
private void createPage1() {
    Intent b = new Intent(this, Page1.class);
    startActivityForResult(b, ACTIVITY_CREATE);
    setResult(RESULT_OK, b);
    finish();
}
private void createPage2() {
    Intent b = new Intent(this, Page2.class);
    startActivityForResult(b, ACTIVITY_CREATE);
    setResult(RESULT_OK, b);
}
private void createTodo() {
    Intent i = new Intent(this, TodoDetails.class);
    startActivityForResult(i, ACTIVITY_CREATE);
    setResult(RESULT_OK, i);
}
private void createCamera() {
    Intent c = new Intent(this, Camera.class);
    startActivityForResult(c, ACTIVITY_CREATE);
    setResult(RESULT_OK, c);
}
//////////////////////////////////////////////////////////
//////// M E N U  T O O L B A R //////////////////////////
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.projektlist, menu);
    return true;
}
public LocationResult locationResult = new LocationResult(){
    @Override
    public void gotLocation(final Location location){
        gps_lati = Double.toString(location.getLatitude());
        gps_long = Double.toString(location.getLongitude());
        }};
 }

1 个答案:

答案 0 :(得分:0)

您应该将位图缩小到ImageView的大小。例如:

int ratio = widhtOriginal / widthImageView;
// Just an example, you should use more sophisticated algorithm

BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = ratio;

InputStream inputStream = context.getContentResolver().openInputStream(uri);
// Will work for Uri's with "content" scheme,
// otherwise use BitmapFactory.decodeFile(String, Options) and so on

Bitmap bitmap = BitmapFactory.decodeStream(inputStream, null, options);