Goal
To pass around images (it fills a quarter of the screen, so it's quite big) for the activities/fragments.
What I tried to do
Instead of passing around BitMaps, I was researched/ was advised to pass the images Uri. The problem is, whenever I click the "Preview Button", which will launch the HomeDescActivity
, an Out of Memory Exception
will occur.
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 (will cause Out of Memory Exception when launched)
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));
}
}
}
}
Update
Stack Trace
android.teamtreehouse.com.airbnb E/AndroidRuntime: FATAL EXCEPTION: main Process: googleplayservices.samples.android.teamtreehouse.com.airbnb, PID: 12434 java.lang.OutOfMemoryError: Failed to allocate a 207360012 byte allocation with 13482248 free bytes and 76MB until OOM at dalvik.system.VMRuntime.newNonMovableArray(Native Method) at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method) at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:609) at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:444) at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:988) at android.content.res.Resources.loadDrawableForCookie(Resources.java:2474) at android.content.res.Resources.loadDrawable(Resources.java:2381) at android.content.res.TypedArray.getDrawable(TypedArray.java:749) at android.widget.ImageView.(ImageView.java:146) at android.widget.ImageView.(ImageView.java:135) at android.support.v7.widget.AppCompatImageView.(AppCompatImageView.java:57) at android.support.v7.widget.AppCompatImageView.(AppCompatImageView.java:53) at android.support.v7.app.AppCompatViewInflater.createView(AppCompatViewInflater.java:106) at android.support.v7.app.AppCompatDelegateImplV9.createView(AppCompatDelegateImplV9.java:1013) at android.support.v7.app.AppCompatDelegateImplV9.onCreateView(AppCompatDelegateImplV9.java:1072) at android.support.v4.view.LayoutInflaterCompatHC$FactoryWrapperHC.onCreateView(LayoutInflaterCompatHC.java:47) at android.view.LayoutInflater$FactoryMerger.onCreateView(LayoutInflater.java:180) at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:725) at android.view.LayoutInflater.rInflate(LayoutInflater.java:806) at android.view.LayoutInflater.rInflate(LayoutInflater.java:809) at android.view.LayoutInflater.rInflate(LayoutInflater.java:809) at android.view.LayoutInflater.rInflate(LayoutInflater.java:809) at android.view.LayoutInflater.rInflate(LayoutInflater.java:809) at android.view.LayoutInflater.inflate(LayoutInflater.java:504) at 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) at android.support.v4.app.Fragment.performCreateView(Fragment.java:2189) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1299) at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1528) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1595) at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:757) at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2355) at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2146) at android.support.v4.app.FragmentManagerImpl.optimizeAndExecuteOps(FragmentManager.java:2098) at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2008) at android.support.v4.app.FragmentController.execPendingActions(FragmentController.java:388) at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:607) at android.support.v7.app.AppCompatActivity.onStart(AppCompatActivity.java:178) at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1236) at android.app.Activity.performStart(Activity.java:6006) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2288) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387) at android.app.ActivityThread.access$800(ActivityThread.java:151) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303) at android.os.Handler.dispatchMessage(Handler.java:102)
Show us the stacktrace.
Give us details about the image that is causing the exception, what's the width and height of it, how much memory does it take?
I'm guessing you're trying to load a stupidly high resolution image like 6000x6000, which is causing the exception, but without more information, i can't say more.
You should use a library like "Glide" to load the images for you, as it will scale the image down when shown to the user if it's too big. It's also extremely efficient at using the least amount of memory to handle images.