Reputation: 33
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
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