【问题标题】:Intent started in onCreate called multiple times在 onCreate 中启动的 Intent 被多次调用
【发布时间】:2014-07-10 17:34:03
【问题描述】:

我正在制作一个使用相机的应用程序,我希望在应用程序打开后立即打开默认相机。我目前在主要活动的 onCreate 方法中开始我的图像捕获意图。有时这工作得很好,但有时相机意图会连续启动 3 次。

public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mImageView = (ImageView) findViewById(R.id.imageView1);
        mImageBitmap = null;

        Button picBtn = (Button) findViewById(R.id.pictureButton);
        setBtnListenerOrDisable(
                picBtn,
                mTakePicOnClickListener,
                MediaStore.ACTION_IMAGE_CAPTURE
        );

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) {
            mAlbumStorageDirFactory = new FroyoAlbumDirFactory();
        } else {
            mAlbumStorageDirFactory = new BaseAlbumDirFactory();
        }
        dispatchTakePictureIntent(ACTION_TAKE_PHOTO_B);
    }

private void dispatchTakePictureIntent(int actionCode) {

        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        File f;
        try {
            f = setUpPhotoFile();
            mCurrentPhotoPath = f.getAbsolutePath();
            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
        } catch (IOException e) {
            e.printStackTrace();
            mCurrentPhotoPath = null;
        }

        startActivityForResult(takePictureIntent, actionCode);
    }

 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == RESULT_OK) {
            handleBigCameraPhoto();
        }
    }

private void handleBigCameraPhoto() {

        if (mCurrentPhotoPath != null) {
            setPic();
            galleryAddPic();
            lastPhotoPath = mCurrentPhotoPath;
            mCurrentPhotoPath = null;
        }

    }

 private void setPic() {

        /* There isn't enough memory to open up more than a couple camera photos */
        /* So pre-scale the target bitmap into which the file is decoded */

        /* Get the size of the ImageView */
        int targetW = mImageView.getWidth();
        int targetH = mImageView.getHeight();

        /* Get the size of the image */
        BitmapFactory.Options bmOptions = new BitmapFactory.Options();
        bmOptions.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
        int photoW = bmOptions.outWidth;
        int photoH = bmOptions.outHeight;

        /* Figure out which way needs to be reduced less */
        int scaleFactor = 1;
        if ((targetW > 0) || (targetH > 0)) {
            scaleFactor = Math.min(photoW / targetW, photoH / targetH);
        }

        /* Set bitmap options to scale the image decode target */
        bmOptions.inJustDecodeBounds = false;
        bmOptions.inSampleSize = scaleFactor;
        bmOptions.inPurgeable = true;

        /* Decode the JPEG file into a Bitmap */
        Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);

        /* Associate the Bitmap to the ImageView */
        mImageView.setImageBitmap(bitmap);
        mImageView.setVisibility(View.VISIBLE);
    }

【问题讨论】:

    标签: android android-intent android-camera android-lifecycle oncreate


    【解决方案1】:

    我认为 Nathaniel 给了你很好的建议,将你的相机意图转移到 onResume 中。

    但是,您需要区分 onResume 是您的第一次开始的活动,以及由于您的活动在相机意图完成后恢复而正在发生的活动。如果你不这样做,你会得到你看到的循环。

    为此,您可以更改您的onActivityResult() 以在您的活动中设置一个名为isResumingFromCaptureIntent 的成员变量。当 resultCode 与您用于启动相机意图的内容匹配时,在 onActivityResult 中将其设置为 true。然后,在您的 onResume 中,检查 isResumingFromCaptureIntent,如果为 true,您知道您不需要启动相机意图并且可以设置为 false 并继续您的活动需要执行的任何其他操作。

    【讨论】:

    • 这是否比执行 onCreate 并检查是否已调用 onCreate 更好?
    • 是的,因为不能保证在从捕获活动返回时调用 onCreate。操作系统可能会选择在启动相机活动(或用户导航到其他活动)时保留您的活动,前提是它有足够的可用内存来保持您的活动常驻。 onResume 总是会被调用。
    • 我会做出改变谢谢你的解释!
    【解决方案2】:

    看这里:

    Android: onCreate() getting called multiple times (and not by me)

    我可以提供的一条指导是尝试将调用转移到

    public void onResume(){
    
    }
    

    您将获得所需的自动进入相机的行为,但这可能会减少一些额外的调用,因为它仅在实际向用户显示活动时发生(包括从其他应用程序返回等) ..)。

    【讨论】:

    • 我之前试过把它放在onStart中,我一定会试试看的,谢谢
    • 没问题,让我知道它是否有效,我会进一步研究。
    • 它没有用。在 onResume 方法中启动相机意图会创建一个循环。一旦相机意图完成,它就会重新启动
    【解决方案3】:

    在 onCreate 方法中,我添加了检查是否之前调用过 onCreate 的逻辑。我通过检查传入的捆绑包是否为空来做到这一点

    public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
    
            mImageView = (ImageView) findViewById(R.id.imageView1);
            mImageBitmap = null;
    
            Button picBtn = (Button) findViewById(R.id.pictureButton);
            setBtnListenerOrDisable(
                    picBtn,
                    mTakePicOnClickListener,
                    MediaStore.ACTION_IMAGE_CAPTURE
            );
    
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) {
                mAlbumStorageDirFactory = new FroyoAlbumDirFactory();
            } else {
                mAlbumStorageDirFactory = new BaseAlbumDirFactory();
            }
    
            if(savedInstanceState == null)
                dispatchTakePictureIntent(ACTION_TAKE_PHOTO_B);
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多