用图像传递图像' Uri仍会导致内存不足异常

时间:2017-07-15 21:42:25

标签: android out-of-memory android-image android-bitmap

目标

传递图像(它占据屏幕的四分之一,因此它非常大)用于活动/片段。

我尝试做什么

我没有绕过BitMaps,而是被研究/建议传递图像Uri。问题是,每当我点击"预览按钮",它将启动HomeDescActivity时,就会出现Out of Memory Exception

GalleryFragment

public class GalleryFragment extends Fragment {
    private static final int SELECT_PICTURE = 1;
    public static final String IMAGE_URI_ARRAY_LIST = "IMAGE_URI_ARRAY_LIST";
    private ArrayList<String> mImageUriArrayList = new ArrayList<>();
    RecyclerView recyclerView;
    GalleryAdapter galleryAdapter;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.profile_tab_become_a_host_set_the_scene_gallery_fragment, container, false);
        return view;
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        //convert string uri to uri object
        Uri imageUri = Uri.parse(getArguments().getString(PhotoFragment.IMAGE_URI));


        recyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
        galleryAdapter = new GalleryAdapter();
        galleryAdapter.addImage(imageUri);
        mImageUriArrayList.add(imageUri.toString());


        GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(), 2);
        recyclerView.setLayoutManager(gridLayoutManager);

        view.findViewById(R.id.ivAddPhoto).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent();
                //Launch Gallery
                intent.setType("image/*");
                intent.setAction(Intent.ACTION_GET_CONTENT);
                startActivityForResult(Intent.createChooser(intent,
                        "Select Picture"), SELECT_PICTURE);
            }
        });

        view.findViewById(R.id.bPreview).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(getContext(), HomeDescActivity.class);
                intent.putStringArrayListExtra(IMAGE_URI_ARRAY_LIST, mImageUriArrayList);
                startActivity(intent);
            }
        });
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK) {
            if (requestCode == SELECT_PICTURE) {
                //get selected image from gallery
                Uri imageUri = data.getData();
                galleryAdapter.addImage(imageUri);
                mImageUriArrayList.add(imageUri.toString());
                //refresh adapter
                recyclerView.setAdapter(galleryAdapter);

            }
        }
    }
}

HomeDescActivity (启动时会导致Out of Memory异常)

public class HomeDescActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.explore_tab_home_desc_activity);

        HomeDescFragment homeDescFragment = new HomeDescFragment();

//        Get images (uri) from GalleryFragment + PhotoFragment
        if(getIntent().getExtras().getStringArrayList(GalleryFragment.IMAGE_URI_ARRAY_LIST) != null){
                Bundle bundle = new Bundle();
            bundle.putStringArrayList(GalleryFragment.IMAGE_URI_ARRAY_LIST,
                    getIntent().getExtras().getStringArrayList(GalleryFragment.IMAGE_URI_ARRAY_LIST));

            homeDescFragment.setArguments(bundle);
            getSupportFragmentManager().beginTransaction().replace(R.id.rootLayout, homeDescFragment).commit();
        }

    }

}

HomeDescFragment

public class HomeDescFragment extends Fragment {
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.explore_tab_home_desc_fragment, container, false);

        return view;
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        //convert strng uri to uri object
        if(getArguments().getStringArrayList(GalleryFragment.IMAGE_URI_ARRAY_LIST) != null){
            ArrayList<String> uriArrayList = getArguments().getStringArrayList(GalleryFragment.IMAGE_URI_ARRAY_LIST);
            ImageView ivHomePhoto = (ImageView) view.findViewById(R.id.ivHomePhoto);

            for(String uriString : uriArrayList){
               ivHomePhoto.setImageURI(Uri.parse(uriString));
            }
        }

    }
}

更新

堆栈跟踪

  

android.teamtreehouse.com.airbnb E / AndroidRuntime:FATAL EXCEPTION:main                                                                                                                流程:googleplayservices.samples.android.teamtreehouse.com.airbnb,PID:12434                                                                                                                java.lang.OutOfMemoryError:无法分配207360012字节分配13482248个空闲字节和76MB直到OOM                                                                                                                    at dalvik.system.VMRuntime.newNonMovableArray(Native Method)                                                                                                                    在android.graphics.BitmapFactory.nativeDecodeAsset(本机方法)                                                                                                                    在android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:609)                                                                                                                    在android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:444)                                                                                                                    在android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:988)                                                                                                                    在android.content.res.Resources.loadDrawableForCookie(Resources.java:2474)                                                                                                                    在android.content.res.Resources.loadDrawable(Resources.java:2381)                                                                                                                    在android.content.res.TypedArray.getDrawable(TypedArray.java:749)                                                                                                                    在android.widget.ImageView。(ImageView.java:146)                                                                                                                    在android.widget.ImageView。(ImageView.java:135)                                                                                                                    在android.support.v7.widget.AppCompatImageView。(AppCompatImageView.java:57)                                                                                                                    在android.support.v7.widget.AppCompatImageView。(AppCompatImageView.java:53)                                                                                                                    在android.support.v7.app.AppCompatViewInflater.createView(AppCompatViewInflater.java:106)                                                                                                                    在android.support.v7.app.AppCompatDelegateImplV9.createView(AppCompatDelegateImplV9.java:1013)                                                                                                                    在android.support.v7.app.AppCompatDelegateImplV9.onCreateView(AppCompatDelegateImplV9.java:1072)                                                                                                                    在android.support.v4.view.LayoutInflaterCompatHC $ FactoryWrapperHC.onCreateView(LayoutInflaterCompatHC.java:47)                                                                                                                    在android.view.LayoutInflater $ FactoryMerger.onCreateView(LayoutInflater.java:180)                                                                                                                    在android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:725)                                                                                                                    在android.view.LayoutInflater.rInflate(LayoutInflater.java:806)                                                                                                                    在android.view.LayoutInflater.rInflate(LayoutInflater.java:809)                                                                                                                    在android.view.LayoutInflater.rInflate(LayoutInflater.java:809)                                                                                                                    在android.view.LayoutInflater.rInflate(LayoutInflater.java:809)                                                                                                                    在android.view.LayoutInflater.rInflate(LayoutInflater.java:809)                                                                                                                    在android.view.LayoutInflater.inflate(LayoutInflater.java:504)                                                                                                                    在android.view.LayoutInflater.inflate(LayoutInflater.java:414)                                                                                                                    at googleplayservices.samples.android.teamtreehouse.com.airbnb.ExploreTab.HomeDescFragment $ override.onCreateView(HomeDescFragment.java:29)                                                                                                                    at googleplayservices.samples.android.teamtreehouse.com.airbnb.ExploreTab.HomeDescFragment $ override.access $ dispatch(HomeDescFragment.java)                                                                                                                    at googleplayservices.samples.android.teamtreehouse.com.airbnb.ExploreTab.HomeDescFragment.onCreateView(HomeDescFragment.java:0)                                                                                                                    在android.support.v4.app.Fragment.performCreateView(Fragment.java:2189)                                                                                                                    在android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1299)                                                                                                                    在android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1528)                                                                                                                    在android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1595)                                                                                                                    在android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:757)                                                                                                                    在android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2355)                                                                                                                    在android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2146)                                                                                                                    在android.support.v4.app.FragmentManagerImpl.optimizeAndExecuteOps(FragmentManager.java:2098)                                                                                                                    在android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2008)                                                                                                                    在android.support.v4.app.FragmentController.execPendingActions(FragmentController.java:388)                                                                                                                    在android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:607)                                                                                                                    在android.support.v7.app.AppCompatActivity.onStart(AppCompatActivity.java:178)                                                                                                                    在android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1236)                                                                                                                    在android.app.Activity.performStart(Activity.java:6006)                                                                                                                    在android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2288)                                                                                                                    在android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)                                                                                                                    在android.app.ActivityThread.access $ 800(ActivityThread.java:151)                                                                                                                    在android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1303)                                                                                                                    在android.os.Handler.dispatchMessage(Handler.java:102)

1 个答案:

答案 0 :(得分:1)

向我们展示堆栈跟踪。

向我们提供有关导致异常的图像的详细信息,它的宽度和高度是多少,需要多少内存?

我猜你正在尝试加载一个像6000x6000那样愚蠢的高分辨率图像,导致异常,但没有更多信息,我不能说更多。

您应该使用像“Glide”这样的库来为您加载图像,因为如果图像太大,它会向用户显示缩小图像。使用最少的内存来处理图像也非常有效。