Android的内存泄漏,没有静态变量 [英] Android Memory Leak, no static variables

查看:126
本文介绍了Android的内存泄漏,没有静态变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是一个开始,Android开发,并作为一个练习项目,我试图让和活动,可以拍摄一张照片,将其保存到外部存储,并在ImageView的显示。几乎所有的东西似乎是工作,但是,我似乎有内存泄漏。

当屏幕方向的变化,我相信活动被破坏,然后重建。为了继续显示所述图像,我存储路径到图像中的字符串中的onSaveInstanceState束和复位在onResotreInstanceState图像。拍摄500万像素的照片,我可以旋转屏幕一次,然后在第二旋转,应用程序崩溃,并且LogCat中报告了内存不足的错误。分辨率较低的图像,我得到更多的轮换,但应用程序仍最终崩溃,我也得到了同样的错误。

我已经读了Android的内存泄漏,一切似乎是说不能用静态的可绘,它可以有引用视图,prevent从释放内存的虚拟机。据我所知,我没有做这样,将继续保持引用任何东西。如果任何人能帮助我找到我的错误,我真的AP preciate它。这里是code:

 公共类CameraTestsActivity延伸活动{

私人乌里了fileURI;

/ **第一次创建活动时调用。 * /
@覆盖
公共无效的onCreate(包savedInstanceState){
    super.onCreate(savedInstanceState);
    的setContentView(R.layout.main);
}

公共无效takePicture(查看视图){
    意向意图=新的意图(MediaStore.ACTION_IM​​AGE_CAPTURE);

    了fileURI = getOutputImageFileUri();
    intent.putExtra(MediaStore.EXTRA_OUTPUT,了fileURI);

    startActivityForResult(意向,0);
}

私有静态乌里getOutputImageFileUri(){
    返回Uri.fromFile(getOutputImageFile());
}

私有静态文件getOutputImageFile(){
    Log.d(CameraTestsActivity,存储状态:+ Environment.getExternalStorageState());
    如果(Environment.getExternalStorageState()。等于(安装)){
        文件mediaStorageDirs =新的文件(Environment.getExternalStorageDirectory()getAbsolutePath()+/图片+/ CameraTestsActivity);
        如果(!mediaStorageDirs.exists()){
            如果(!mediaStorageDirs.mkdirs()){
                Log.d(CameraTestsActivity,无法创建目录);
                mediaStorageDirs = NULL;
                返回null;
            }
        }

        字符串的timeStamp =新的SimpleDateFormat(YYYYMMDD_HHMMSS)格式(新的Date())。
        文件镜像文件=新的文件(mediaStorageDirs.getPath()+文件分割符+IMG_+的timeStamp +.JPG);
        mediaStorageDirs = NULL;
        返回镜像文件;


    }
    Log.d(CameraTestsActivity,存储状态不好);
    返回null;
}



@覆盖
保护无效onActivityResult(INT申请code,INT结果code,意图数据){
    如果(结果code == RESULT_OK){
        如果(要求code == 0){
            setImage();
        }
    }
    其他{
        super.onActivityResult(要求code,因此code,数据);
    }
}

@覆盖
保护无效onRestoreInstanceState(包savedInstanceState){
    了fileURI = Uri.parse(savedInstanceState.getString(URI));
    setImage();
    super.onRestoreInstanceState(savedInstanceState);
}

@覆盖
保护无效的onSaveInstanceState(包outState){
    outState.putString(URI,fileUri.toString());
    super.onSaveInstanceState(outState);
}

私人无效setImage(){
    ImageView的形象=(ImageView的)findViewById(R.id.imageView1);
    档案文件=新的文件(fileUri.toString()子(7)。);
    如果(!file.exists())
        Log.d(CameraTestsActivity,文件+ fileUri.toString()子(7)+不存在。);
    image.setImageURI(了fileURI);
}

}
 

解决方案

当显示位图,我们应该小心,它的大小不超过堆大小或者说虚拟经济。 虽然你没有任何内存泄漏,但是当你改变你的方向则可能是其花一些时间来清理pviously加载位图等你拿内存溢出错误$ P $。 为了避免这种错误,请阅读此如何显示位图有效

I'm a beginning Android developer, and as a practice project, I'm trying to make and activity which can take a picture, save it to the external storage, and display it in an ImageView. Almost everything seems to be working, however, I appear to have a memory leak.

When the screen orientation changes, I believe the activity is destroyed, then recreated. In order to continue displaying the image, I am storing the path to the image as a string in a bundle in onSaveInstanceState and resetting the image in onResotreInstanceState. Taking 5mp pictures, I can rotate the screen once, and then on the second rotation, the app crashes, and LogCat reports an out of memory error. With lower resolution images, I get more rotations, but the app still eventually crashes and I get the same error.

I've been reading up on android memory leaks, and everything seems to say not to use static Drawables, which can have references to the view, and prevent the vm from releasing the memory. As far as I can tell, I'm not doing anything like this that would keep holding references. If any one can help me locate my error, I'd really appreciate it. Here is the code:

public class CameraTestsActivity extends Activity {

private Uri fileUri;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
}

public void takePicture(View view){
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

    fileUri = getOutputImageFileUri();
    intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);

    startActivityForResult(intent, 0);
}

private static Uri getOutputImageFileUri() {
    return Uri.fromFile(getOutputImageFile());
}

private static File getOutputImageFile(){
    Log.d("CameraTestsActivity", "Storage state: " + Environment.getExternalStorageState());
    if (Environment.getExternalStorageState().equals("mounted")){
        File mediaStorageDirs = new File (Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures" + "/CameraTestsActivity");
        if (! mediaStorageDirs.exists()){
            if (! mediaStorageDirs.mkdirs()){
                Log.d("CameraTestsActivity", "Failed to create directories");
                mediaStorageDirs = null;
                return null;
            }
        }

        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        File imageFile = new File(mediaStorageDirs.getPath() + File.separator + "IMG_" + timeStamp + ".jpg");
        mediaStorageDirs = null;
        return imageFile;


    }
    Log.d("CameraTestsActivity", "Storage state bad");
    return null;
}



@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode == RESULT_OK){
        if (requestCode == 0){
            setImage();
        }
    }
    else{
        super.onActivityResult(requestCode, resultCode, data);
    }
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    fileUri = Uri.parse(savedInstanceState.getString("uri"));
    setImage();
    super.onRestoreInstanceState(savedInstanceState);
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    outState.putString("uri", fileUri.toString());
    super.onSaveInstanceState(outState);
}

private void setImage(){
    ImageView image = (ImageView)findViewById(R.id.imageView1);
    File file = new File(fileUri.toString().substring(7));
    if (!file.exists())
        Log.d("CameraTestsActivity", "File " + fileUri.toString().substring(7) + "does not exist");
    image.setImageURI(fileUri);
}

}

解决方案

While displaying bitmap we should be careful that its size does not exceed the Heap size or say VM Budget. Although you do not have any memory leak but when you have changing your orientation then may be its taking some time to clean previously loaded bitmap so you get memory overflow error. For avoiding this error please read this How to display bitmap efficiently

这篇关于Android的内存泄漏,没有静态变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆