在调用startActivity时,在Intent中发送Parcelable会显示白屏

时间:2017-06-30 10:28:02

标签: java android performance parcelable

我正在使用parcelable在活动之间传递数据(请不要说这是错误的方法,因为有很多关于此的讨论)。

这是我拍摄图片的方式:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, REQUEST_IMAGE_CAPTURE);

        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if (intent.resolveActivity(getPackageManager()) != null) {
            startActivityForResult(intent, REQUEST_IMAGE_CAPTURE);
        }
    }

@Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        switch (requestCode) {
            case 30: {

                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                } else {

                    Toast.makeText(CameraCapture.this, "Permission denied to read your External storage", Toast.LENGTH_SHORT).show();
                }
                return;
            }
        }
    }



@Override
    protected void onActivityResult(int requestCode, int resultCode, final Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        dateTimer = getTime();

        Log.d("codig",String.valueOf(requestCode));

        if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
            Log.d("resultOK","resultOK");
            CropImage.activity(data.getData())
                    .setAspectRatio(1,1)
                    .setInitialCropWindowPaddingRatio(0)
                    .setActivityTitle("Corte a foto")
                    .setActivityMenuIconColor(R.color.nephritis)
                    .start(this);
        }
        if (requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE) {
            CropImage.ActivityResult result = CropImage.getActivityResult(data);
            Log.d("pict12","here");
            if (resultCode == RESULT_OK) {
                Log.d("pict12","here2");
                Uri uri = result.getUri();
                Bitmap pic = null;
                try {
                    pic = MediaStore.Images.Media.getBitmap(this.getContentResolver(), uri);
                } catch (IOException e) {
                    e.printStackTrace();
                }

                image = encodeImage(pic);
                showDetailsDialog(data);
            } else if (resultCode == CropImage.CROP_IMAGE_ACTIVITY_RESULT_ERROR_CODE) {
                Exception error = result.getError();
                Log.d("pict12",error.toString());
            }
        }
    }

当我捕获图像时,我启动一个构建器来使用simpleCropView lib来剪切图像,之后它返回到第二个onactivityResult,并显示如下的详细信息对话框:

 private void showDetailsDialog(final Intent data) {
        final CharSequence[] items = {"Tem fruto?","É arbusto","É árvore?","Tem flor?","Tem espinhos?"};
// arraylist to keep the selected items
        final ArrayList seletedItems=new ArrayList();

        AlertDialog dialog = new AlertDialog.Builder(this)
                .setTitle("Detalhes da fotografia")
                .setMultiChoiceItems(items, null, new DialogInterface.OnMultiChoiceClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int indexSelected, boolean isChecked) {
                        if (isChecked) {
                            // If the user checked the item, add it to the selected items
                            seletedItems.add(indexSelected);
                        } else if (seletedItems.contains(indexSelected)) {
                            // Else, if the item is already in the array, remove it
                            seletedItems.remove(Integer.valueOf(indexSelected));
                        }
                    }
                }).setPositiveButton("OK", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int id) {
                        hasFruit = seletedItems.contains(0);
                        isBush = seletedItems.contains(1);
                        isTree = seletedItems.contains(2);
                        hasFlower = seletedItems.contains(3);
                        hasThorns = seletedItems.contains(4);
                        if(seletedItems.contains(3)){
                            dialog.dismiss();
                            colorDialog(data);
                        }
                        else{
                            startSimiliarActivity();
                        }
                    }

                }).setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int id) {
                        Log.d("RECREATE","recria");
                        dialog.dismiss();
                        CameraCapture.this.recreate();
                    }
                }).create();
        dialog.show();
    }

如果在这个详细信息对话框中,我检查它发送给另一个对话框的花,以更改花的颜色,如果我不检查它,请将我发送到similiarActivityMethod,在那里我将用户发送到我所拥有的acitvity空白布局。

基本上我传递的是一个带有byte []填充的对象和其他数据,我认为不是那么大,当我调用显示空白的活动时,我会传递这样的parcelable:

 public void startSimiliarActivity(){
        Log.d("HELLWOR","HELLOWOR");
        Intent intent = new Intent(CameraCapture.this,SimiliarPhotos.class);
        if(location.getAltitude() != 0.0){
            altitude = location.getAltitude() - 50;
        }
        Photo photo = new Photo(image,altitude,location.getLongitude(),location.getAltitude(),dateTimer);

        intent.putExtra("photo",photo);
        startActivity(intent);
    }

我将其设置为:

package com.example.afcosta.inesctec.pt.android.models;

import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;

import java.io.Serializable;
import java.net.URI;

/**
 * Created by FilipeCosta on 25/05/2017.
 */

public class Photo implements Parcelable {
    private int id;
    private Uri image;
    private byte[] cropedImage;
    private String path;
    private Double lat;
    private Double lon;
    private Double alt;
    private String time;

    public Photo() {
    }


    @Override
    public int describeContents() {
        return 0;
    }

    public Photo(byte[] cropedImage,Double lat, Double lon, Double alt, String time) {
        this.cropedImage = cropedImage;
        this.lat = lat;
        this.lon = lon;
        this.alt = alt;
        this.time = time;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(this.id);
        dest.writeParcelable(this.image, flags);
        dest.writeByteArray(this.cropedImage);
        dest.writeString(this.path);
        dest.writeValue(this.lat);
        dest.writeValue(this.lon);
        dest.writeValue(this.alt);
        dest.writeString(this.time);
    }

    protected Photo(Parcel in) {
        this.id = in.readInt();
        this.image = in.readParcelable(Uri.class.getClassLoader());
        this.cropedImage = in.createByteArray();
        this.path = in.readString();
        this.lat = (Double) in.readValue(Double.class.getClassLoader());
        this.lon = (Double) in.readValue(Double.class.getClassLoader());
        this.alt = (Double) in.readValue(Double.class.getClassLoader());
        this.time = in.readString();
    }

    public static final Creator<Photo> CREATOR = new Creator<Photo>() {
        @Override
        public Photo createFromParcel(Parcel source) {
            return new Photo(source);
        }

        @Override
        public Photo[] newArray(int size) {
            return new Photo[size];
        }
    };

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public Uri getImage() {
        return image;
    }

    public void setImage(Uri image) {
        this.image = image;
    }

    public byte[] getCropedImage() {
        return cropedImage;
    }

    public void setCropedImage(byte[] cropedImage) {
        this.cropedImage = cropedImage;
    }

    public String getPath() {
        return path;
    }

    public void setPath(String path) {
        this.path = path;
    }

    public Double getLat() {
        return lat;
    }

    public void setLat(Double lat) {
        this.lat = lat;
    }

    public Double getLon() {
        return lon;
    }

    public void setLon(Double lon) {
        this.lon = lon;
    }

    public Double getAlt() {
        return alt;
    }

    public void setAlt(Double alt) {
        this.alt = alt;
    }

    public String getTime() {
        return time;
    }

    public void setTime(String time) {
        this.time = time;
    }

我认为这个问题与parcelable有关,因为当我评论Line我在哪里实现照片效果很好,但我需要实例:/

对此有何帮助?

1 个答案:

答案 0 :(得分:0)

您可以在Intent中发送的数据大小有限(大约500Kb)。照片很可能超过了这个限制。

有几种可能的解决方案,最简单的可能是将数据写入(临时)File而不是在Intent中发送(并在接收时读取File Activity)。

或者只是确保照片不超过限制(例如通过调整大小)。