码迷,mamicode.com
首页 > 移动开发 > 详细

安卓使用Intent开启照相机拍照时闪退的处理

时间:2015-06-30 20:27:00      阅读:182      评论:0      收藏:0      [点我收藏+]

标签:安卓   调用   intent-相机   应用   

1.现象

在使用安卓手机的一些应用调用照相机时,我们会发现有时候当我们拍照完毕时,程序会出现闪退,非常影响用户体验。目前项目中也有类似的拍照上传功能,当使用米3手机测试时,拍照上传功能可以正常使用,当我们换上红米或者其他一些比较早或者比较低端的手机时,就出现了闪退的问题。

1.1开启相机的intent

/* mPictureCachePath为当前照相相片的存储路径 */
pictureCachePath = Utility.getExternalCacheDir(this)+...;
intent.putExtra(MediaStore.EXTRA_OUTPUT,
        Uri.fromFile(new File(mPictureCachePath)));
startActivityForResult(intent, REQUEST_CODE_TAKE_PHOTO);

1.2onActivityResult接收intent返回值并获取bitmap

File file = new File(mPictureCachePath);
if (file.exists()) {            
    Bitmap bitmap = BitmapUtils.convertToBitmap(
            mPictureCachePath, width, height);
}

2.分析问题

经过debug我们可以发现,如果程序发生闪退,此时mPictureCachePath值为null,可是我们在一开始已经为这个变量赋值,为什么当从相机程序返时,mPictureCachePath这个全局变量会变为null?

那我们给mPictureCachePath赋个初始值看看,结果当程序返回时,这个变量的值不是我们赋值过的路径,而是那个初始值。这样,我推测当前所在的Activity在相机程序返回时应该是被重新创建了。

通过调试,我们发现如果使用米3手机,程序不闪退,相机程序在返回我们的Actvity时没有执行onCreate方法,而使用红米手机,程序闪退时,此时我们的Actvity执行了onCreate,也就是说用红米时,当我们开启相机程序时,我们自己的Activity已经被销毁了! 所以当相机程序返回我们的Activity时,这个Activity是刚刚创建的,我们刚刚为图片创建的路径记录变量此时其实并没有被赋值。

3.解决方式

既然变量有可能丢,那么我们就可以把这个变量记录下来,可以使用sp等。假如我们的程序中还需要记录一些其他的变量,比如一些我们自定义的比较复杂的类,sp就没办法满足存储的需要。

此时我们可以使用如下两个方法

protected void onSaveInstanceState(Bundle outState)
protected void onRestoreInstanceState(Bundle savedInstanceState)

这两个方法并不是Activity每次都会调用的,我们注意到onCreate和onRestoreInstanceState都有个Bundle类型的参数,那么这个参数是谁传来的呢?肯定是onSaveInstanceState传来的。

当我们的Activity在未经我们自己finish的情况下被结束(没有被回收也会执行onSaveInstanceState),onSaveInstanceState方法就会被调用。此时我们就可以利用outState参数来存储我们的数据,当onCreate或者onRestoreInstanceState(只有Activity被真正回收后才调用)时,将这些数据拿出来重新赋值给我们的成员变量,这样,就算是Activity被销毁了,我们依然可以重新获得相关变量的值。

    /**
     * 保存相册参数
     * 说明:对于配置低的手机,开启照相机时,当前activity会被回收,导致再次返回该activity时,原先保存
     * 的变量被重新初始化,导致程序无法运行,造成崩溃。此处需要记录相关变量信息,如果activity异常退出,
     * 再次进入时调用onRestoreInstanceState函数就可以恢复这些变量的值。
     */
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        Log.i(TAG, "onSaveInstanceState");
    /* 保存相片路径 */
    outState.putString("mCurrentSelectPictureCachePath", mCurrentSelectPictureCachePath);   
    }


    /**
     * 恢复相册参数
     */
    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {

        super.onRestoreInstanceState(savedInstanceState);
        Log.i(TAG, "onRestoreInstanceState");
        /* 恢复当前相片存储路径 */
        mPictureCachePath = savedInstanceState.getString("mCurrentSelectPictureCachePath", mCurrentSelectPictureCachePath);

    ......
    }

这样,mPictureCachePath的值就可以被保存下来,当程序返回时,如果Activity没有被回收,则不会执行onRestoreInstanceState方法,如果被回收了,就调用onRestoreInstanceState方法对变量值进行恢复。

版权声明:本文为博主原创文章,未经博主允许不得转载。

安卓使用Intent开启照相机拍照时闪退的处理

标签:安卓   调用   intent-相机   应用   

原文地址:http://blog.csdn.net/lidec/article/details/46699111

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!