sachin c
sachin c

Reputation: 33

android app has been crashed Out of memory on a 2457616-byte allocation

I am getting this Out of memory on a 2457616-byte allocation error,In my app ,I am using 21 images in linear-layout background in several xml file . and some images access form the sever only for display not set in background ,and I also use fragment in my apps,the App is running fine till first 12 to 13 but after that its show Out of memory error.

please check my xml, java file mention bellow and logcat:

<?xml version="1.0" encoding="utf-8"?>
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation ="vertical"
android:background="@drawable/home_pg_3">


        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp" 
            android:orientation="horizontal"
            android:layout_weight="2">

                        <LinearLayout
                            android:layout_width="0dp"
                            android:layout_height="match_parent"
                            android:layout_weight="1.8" >

                            <Button
                                android:id="@+id/shop"
                                android:layout_width="match_parent"
                                android:layout_height="fill_parent"
                                style="@style/myButton" />

                        </LinearLayout>

                        <LinearLayout
                            android:layout_width="0dp"
                            android:layout_height="match_parent" 
                            android:orientation="vertical"
                            android:layout_weight="1">

                            <Button
                                android:id="@+id/event"
                                android:layout_width="fill_parent"
                                android:layout_height="0dp"
                                style="@style/myButton"
                                android:layout_weight="2" />

                            <Button
                                android:id="@+id/dine"
                                android:layout_width="fill_parent"
                                android:layout_height="0dp"
                                style="@style/myButton"
                                android:layout_weight="4" />

                        </LinearLayout>

        </LinearLayout>


<!-- footer lenear -->      


<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="0dp" 
    android:layout_weight="1">

    <Button
        android:id="@+id/offers"
        android:layout_width="0dp"
        android:layout_height="fill_parent"
        android:layout_weight="1"
        style="@style/myButton" />

    <Button
        android:id="@+id/entertainment"
        android:layout_width="0dp"
        android:layout_height="fill_parent"
        android:layout_weight="1"
        style="@style/myButton" />

    <Button
        android:id="@+id/contacts"
        android:layout_width="0dp"
        android:layout_height="fill_parent"
        android:layout_weight=".85"
        style="@style/myButton" />

</LinearLayout>

MainActivity.java

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


    setContentView(R.layout.home_page);
    //Bundle b = getIntent().getExtras();
    initialize();
    btn1.setOnClickListener(this);
    btn2.setOnClickListener(this);
    btn3.setOnClickListener(this);


//  key1 = b.getInt("key_value");

    // Restore statry{
    if (savedInstanceState != null) {
        // The fragment manager will handle restoring them if we are being
        // restored from a saved state
    }
    // If this is the first creation of the activity, add fragments to it
    else {

        // If our layout has a container for the image selector fragment,
        // add it
        Fragname = (ViewGroup) findViewById(R.id.fragment_place);
        if (Fragname != null) {
            //Log.i(TAG, "onCreate: adding HeaderFragment to MainActivity");

            // Add Header fragment to the activity's container layout
            HomeScreen homescreen1 = new HomeScreen();
            FragmentTransaction fragmentTransaction = getSupportFragmentManager()
                    .beginTransaction();
            fragmentTransaction.replace(Fragname.getId(),
                    homescreen1, HomeScreen.class.getName());

            // Commit the transaction
            fragmentTransaction.commit();
        }
        // If our layout has a container for the selector fragment,
        // add it


        // If our layout has a container for the image selector fragment,
        // add it

    }
}
    private void initialize(){
    btn1 =(Button) findViewById(R.id.btn_home);
    btn2 =(Button) findViewById(R.id.btn_search);
    btn3 =(Button) findViewById(R.id.btn_map);


    }
    @Override
public void onClick(View v) {
    // TODO Auto-generated method stub
     switch(v.getId())
     {
     case R.id.btn_home:
         HomeScreenmet();
         break;
     case R.id.btn_search:
         SearchScreenmet();
         break;
     case R.id.btn_map:
      MapScreenmet();
     break;


     }  
}
    private void MapScreenmet() {
    // TODO Auto-generated method stub
    Fragname = (ViewGroup) findViewById(R.id.fragment_place);
    if (Fragname != null) {
    //  Log.i(TAG, "onCreate: adding HeaderFragment to MainActivity");

        // Add Header fragment to the activity's container layout
        MapScreen mapscreen = new MapScreen();
        FragmentTransaction fragmentTransaction = getSupportFragmentManager()
                .beginTransaction();
        fragmentTransaction.replace(Fragname.getId(),
                mapscreen, HomeScreen.class.getName());

        // Commit the transaction
        fragmentTransaction.addToBackStack( "tag" ).commit();
    }


}

private void SearchScreenmet() {
    // TODO Auto-generated method stub
    Fragname = (ViewGroup) findViewById(R.id.fragment_place);
    if (Fragname != null) {
    //  Log.i(TAG, "onCreate: adding HeaderFragment to MainActivity");

        // Add Header fragment to the activity's container layout
        SearchScreen searchscreen = new SearchScreen();
        FragmentTransaction fragmentTransaction = getSupportFragmentManager()
                .beginTransaction();
        fragmentTransaction.replace(Fragname.getId(),
                searchscreen, HomeScreen.class.getName());

        // Commit the transaction
        fragmentTransaction.addToBackStack( "tag" ).commit();
    }


}

private void HomeScreenmet() {
    // TODO Auto-generated method stub
    Fragname = (ViewGroup) findViewById(R.id.fragment_place);
    if (Fragname != null) {
        //Log.i(TAG, "onCreate: adding HeaderFragment to MainActivity");

        // Add Header fragment to the activity's container layout
        HomeScreen headerFragment = new HomeScreen();
        FragmentTransaction fragmentTransaction = getSupportFragmentManager()
                .beginTransaction();
        fragmentTransaction.replace(Fragname.getId(),
                headerFragment, HomeScreen.class.getName());

        // Commit the transaction
        fragmentTransaction.commit();
    }


}

access server images also check following code : offer.xml,Offer.java ,ImageLoader.java

   <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:orientation="vertical"  
     android:layout_width="fill_parent"  
     android:layout_height="fill_parent"
    android:background="@drawable/offers" >

 <LinearLayout 
     android:layout_width="match_parent"
     android:layout_height="match_parent" 
     android:layout_weight=".3"
     android:orientation="horizontal"
   >

   <ImageView
    android:id="@+id/offer_setimage1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"

    style="@style/image_offer_default"
    android:layout_gravity="center_horizontal"

    />

 </LinearLayout>

 <LinearLayout
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:layout_weight=".7" 
     android:orientation="horizontal">

      <HorizontalScrollView android:layout_width="match_parent"  
    android:layout_height="match_parent"
     >

    <LinearLayout android:id="@+id/offer_linearLayout"  
      android:layout_width="match_parent"  
      android:layout_height="match_parent"  
      android:orientation="horizontal"
      >  

    </LinearLayout>  

  </HorizontalScrollView>  
 </LinearLayout>

offer.java

public class Offers extends Fragment implements OnClickListener{
private static final String TAG = Offers.class.getSimpleName();
private OnViewSelectedListener mParentOnViewSelectedListener;


private ProgressDialog pDialog;
private static String url = "http://www.xyz.com/aaa/test4.json";

//JSON Node names
private static final String TAG_iit = "iit";
private static final String TAG_UPDATE = "update";
private static final String TAG_ID = "id";
private static final String TAG_TITLE = "title";
private static final String TAG_DESCRIPTION = "description";
private static final String TAG_DURATION = "duration";
 private static final String TAG_THUMB_URL = "thumb_url";
 private static final String TAG_PAGE_URL = "page_url";

LinearLayout mainLayout;

 private View cell; 



  ImageLoader imageLoader;
//contacts JSONArray
JSONArray contacts = null;
View view;
LayoutParams params;
    //Hashmap for ListView
     ArrayList<HashMap<String, String>> contactList;

     public void onAttach(Activity activity) {
 super.onAttach(activity);
//Log.v(TAG, "onAttach");

// Check if parent fragment (if there is one) implements the image
// selection interface
Fragment parentFragment = getParentFragment();
if (parentFragment != null
        && parentFragment instanceof OnViewSelectedListener) {
    mParentOnViewSelectedListener = (OnViewSelectedListener) parentFragment;
}
// Otherwise, check if parent activity implements the image
// selection interface
else if (activity != null && activity instanceof OnViewSelectedListener) {
    mParentOnViewSelectedListener = (OnViewSelectedListener) activity;
}
// If neither implements the image selection callback, warn that
// selections are being missed
else if (mParentOnViewSelectedListener == null) {
    Log.w(TAG,
            "onAttach: niether the parent fragment or parent activity  implement OnViewSelectedListener, "
                    + "image selections will not be communicated to other components");
}
}

     public View onCreateView(LayoutInflater inflater,
      ViewGroup container, Bundle savedInstanceState) {
  view =inflater.inflate(
      R.layout.offers, container, false);

  mainLayout = (LinearLayout) view.findViewById(R.id.offer_linearLayout);


    contactList = new ArrayList<HashMap<String, String>>();
    new GetContacts().execute();
   //Inflate the layout for this fragment

   return view;
   } 

    private class GetContacts extends AsyncTask<Void, Void, Void> {

     String[] tt =new String[10];

@Override
protected void onPreExecute() {
    super.onPreExecute();
    // Showing progress dialog
    pDialog = new ProgressDialog(getActivity());
    pDialog.setMessage("Please wait...");
    pDialog.setCancelable(false);
    pDialog.show();

}


     @Override
protected Void doInBackground(Void... arg0) {
    // Creating service handler class instance
    ServiceHandler sh = new ServiceHandler();

    // Making a request to url and getting response
    String jsonStr = sh.makeServiceCall(url, ServiceHandler.GET);

//Log.e(TAG , "> Tag " + jsonStr);

    if (jsonStr != null) {


        try {
            //Log.e("Response: ", "> inside try");
            JSONObject jsonObj = new JSONObject(jsonStr);

            // Getting JSON Array node
            JSONObject object = jsonObj.getJSONObject(TAG_iit);
            //Log.e("Response2 : ", ""+object);
            contacts = object.getJSONArray(TAG_UPDATE);

            // looping through All Contacts
            //Log.e("Response3 : ", ""+contacts.length());
            for (int i = 0; i < contacts.length(); i++) {
                JSONObject c = contacts.getJSONObject(i);
                Log.e("Response4 : ",   ""+contacts.getJSONObject(i));
                String id = c.getString(TAG_ID);
                String title = c.getString(TAG_TITLE);
                String desc = c.getString(TAG_DESCRIPTION);
                String duration = c.getString(TAG_DURATION);
                String image = c.getString(TAG_THUMB_URL);
                String pageurl = c.getString(TAG_PAGE_URL);

                // Phone node is JSON Object
                //JSONObject image_url = c.getJSONObject(TAG_PAGE_URL);

                //String mobile = phone.getString(TAG_PHONE_MOBILE);
            //  String home = phone.getString(TAG_PHONE_HOME);
                //String office = phone.getString(TAG_PHONE_OFFICE);

                // tmp hashmap for single contact
                HashMap<String, String> contact = new HashMap<String, String>();

                // adding each child node to HashMap key => value
                contact.put(TAG_ID, id);
                contact.put(TAG_TITLE, title);
                contact.put(TAG_DESCRIPTION, desc);
                contact.put(TAG_DURATION, duration);
                contact.put(TAG_THUMB_URL, image);
                contact.put(TAG_PAGE_URL, pageurl);

                // adding contact to contact list
                contactList.add(contact);


            }
        } catch (JSONException e) {
            //Log.e("offer catch" , "inside catch ");
            e.printStackTrace();

        }


    } else {


        // img = (ImageView) view.findViewById(R.id.offer_setimage1); 
    //  img.setImageResource(R.drawable.offer1);    

        Log.e("ServiceHandler", "Couldn't get any data from the url");
    }

    return null;
}

@Override
protected void onPostExecute(Void result) {

    super.onPostExecute(result);
    // Dismiss the progress dialog
    if (pDialog.isShowing())
        pDialog.dismiss();
    /**
     * Updating parsed JSON data into ListView
     * */
    if(contactList.size() != 0){
        super.onPostExecute(result);
    imageLoader =new ImageLoader(getActivity());

HashMap<String, String> content1 = contactList.get(0);
    String getImg1 =content1.get(TAG_THUMB_URL).toString();
   ImageView img = (ImageView) view.findViewById(R.id.offer_setimage1); 
    imageLoader.DisplayImage(getImg1,img);

    for (int i = 0; i < (contactList.size()); i++) {  
    HashMap<String, String> content = contactList.get(i);
      final String getImg =content.get(TAG_THUMB_URL).toString();


          tt[i]=getImg;

            //imageView.setImageResource(R.drawable.ic_launcher); 

             // imageLoader.DisplayImage(song.get(TAG_THUMB_URL),imageView);
             cell = getLayoutInflater(null).inflate(R.layout.cell_offer, null);  



             final ImageView  imageView1 = (ImageView) cell.findViewById(R.id.offer_image); 


             imageView1.setOnClickListener(new OnClickListener() {  

                       @Override  
                       public void onClick(View v) {  


                   final ImageView   img = (ImageView) view.findViewById(R.id.offer_setimage1); 

                         BitmapDrawable drawable = (BitmapDrawable)  imageView1.getDrawable();

                      Bitmap bitmap = drawable.getBitmap();  
                         // img.getLayoutParams().width = 480;
                        //  img.getLayoutParams().height = 400;

                         img.setImageBitmap(bitmap);
                        /// img.setBackgroundDrawable(drawable);


                       }  
                  });  
          //   Log.v("images ",""+tt[i]);

             imageLoader.DisplayImage(tt[i],imageView1);
             mainLayout.addView(cell); 
            // unbindDrawables(imageView1);
   }
}
else{


    AlertDialog.Builder alert = new AlertDialog.Builder(getActivity()); 
alert.setTitle("Network Error");

    alert.setMessage("Please Check Internet Connection");

    //alert.setIcon(R.drawable.a1);
    alert.setNegativeButton("Close", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int id) {
            dialog.dismiss();
        }
    });
    alert.show();
    // final ImageView  imageView1 = (ImageView) view.findViewById(R.id.offer_setimage1); 



    // imageView1.setImageResource(R.drawable.offer1);
}

}

}

ImageLoadr.java

     package avignyata.android.event;


    import avignyata.android.mallpacific.R;

    public class ImageLoader {

     MemoryCache memoryCache=new MemoryCache();
     FileCache fileCache;
     private Map<ImageView, String> imageViews=Collections.synchronizedMap(new     WeakHashMap<ImageView, String>());
ExecutorService executorService; 

public ImageLoader(Context context){
    fileCache=new FileCache(context);
    executorService=Executors.newFixedThreadPool(5);
}

final int stub_id = R.drawable.offer1;
public void DisplayImage(String url, ImageView imageView)
{

    imageViews.put(imageView, url);
    Bitmap bitmap=memoryCache.get(url);
    if(bitmap!=null){
       imageView.setImageBitmap(bitmap);
    bitmap.recycle();
    }
    else
    {
       queuePhoto(url, imageView);
       // imageView.setImageResource(stub_id);
    }
}

private void queuePhoto(String url, ImageView imageView)
{
    PhotoToLoad p=new PhotoToLoad(url, imageView);
    executorService.submit(new PhotosLoader(p));
}

private Bitmap getBitmap(String url) 
{
    File f=fileCache.getFile(url);

    //from SD cache
    Bitmap b = decodeFile(f);
    if(b!=null)
        return b;

    //from web
    try {
        Bitmap bitmap=null;
        URL imageUrl = new URL(url);
        HttpURLConnection conn = (HttpURLConnection)imageUrl.openConnection();
        conn.setConnectTimeout(30000);
        conn.setReadTimeout(30000);
        conn.setInstanceFollowRedirects(true);
        InputStream is=conn.getInputStream();
        OutputStream os = new FileOutputStream(f);
        Utils.CopyStream(is, os);
        os.close();
        bitmap = decodeFile(f);
        return bitmap;
    } catch (Exception ex){
       ex.printStackTrace();
       return null;
    }
}

//decodes image and scales it to reduce memory consumption
private Bitmap decodeFile(File f){
    try {
        //decode image size
        BitmapFactory.Options o = new BitmapFactory.Options();
        o.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(new FileInputStream(f),null,o);

        //Find the correct scale value. It should be the power of 2.
        final int REQUIRED_SIZE=150;
        int width_tmp=o.outWidth, height_tmp=o.outHeight;
        int scale=1;
        while(true){
            if(width_tmp/2<REQUIRED_SIZE || height_tmp/2<REQUIRED_SIZE)
                break;
            width_tmp/=2;
            height_tmp/=2;
            scale*=2;
        }

        //decode with inSampleSize
        BitmapFactory.Options o2 = new BitmapFactory.Options();
        o2.inSampleSize=scale;
        return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
    } catch (FileNotFoundException e) {}
    return null;
}



//Task for the queue
private class PhotoToLoad
{
    public String url;
    public ImageView imageView;
    public PhotoToLoad(String u, ImageView i){
        url=u; 
        imageView=i;
    }
}

class PhotosLoader implements Runnable {
    PhotoToLoad photoToLoad;
    PhotosLoader(PhotoToLoad photoToLoad){
        this.photoToLoad=photoToLoad;
    }

    @Override
    public void run() {
        if(imageViewReused(photoToLoad))
            return;
        Bitmap bmp=getBitmap(photoToLoad.url);
        memoryCache.put(photoToLoad.url, bmp);
        if(imageViewReused(photoToLoad))
            return;
        BitmapDisplayer bd=new BitmapDisplayer(bmp, photoToLoad);
        Activity a=(Activity)photoToLoad.imageView.getContext();
        a.runOnUiThread(bd);
    }
}

boolean imageViewReused(PhotoToLoad photoToLoad){
    String tag=imageViews.get(photoToLoad.imageView);
    if(tag==null || !tag.equals(photoToLoad.url))
        return true;
    return false;
}

//Used to display bitmap in the UI thread
class BitmapDisplayer implements Runnable
{
    Bitmap bitmap;
    PhotoToLoad photoToLoad;
    public BitmapDisplayer(Bitmap b, PhotoToLoad p){bitmap=b;photoToLoad=p;}
    public void run()
    {
        if(imageViewReused(photoToLoad))
            return;
        if(bitmap!=null)
            photoToLoad.imageView.setImageBitmap(bitmap);
        else
            photoToLoad.imageView.setImageResource(stub_id);
    }
}

public void clearCache() {
    memoryCache.clear();
    fileCache.clear();
}

}

Upvotes: 0

Views: 343

Answers (1)

Sushil
Sushil

Reputation: 8488

May be you can try to make your code more efficient by clearing the cache when image is not in used or dynamically resizing the images. For a quick solution, you can try to request for more memory for your app by doing this AndroidManisfest file:

You can use

android:largeHeap="true" 

to request a larger heap size, but this will not work on any pre Honeycomb devices.

Upvotes: 1

Related Questions