2014-02-26 109 views
0

我得到這個內存不足2457616字節的分配錯誤,在我的應用程序中,我在線性佈局背景中使用21個圖像在幾個xml文件。和一些圖像訪問形式服務器只爲顯示不設置在後臺,我也使用片段在我的應用程序,應用程序運行良好,直到第一次12至13,但之後,它顯示內存不足的錯誤。android應用程序崩潰內存不足2457616字節分配

請我的XML,Java文件提到波紋管和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(); 
    } 


} 

訪問服務器的圖像也檢查下面的代碼: 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(); 
} 

}

+0

哇,你是認真的嗎?圖像大小超過500 KB。其中一些差不多是1MB!你正在加載21張巨大的圖片?嘗試調整它們的大小 – JoelFernandes

回答

1

可能是你可以嘗試讓你的代碼更有效的通過清除緩存圖像時不使用或動態調整影像。對於一個快速的解決方案,你可以嘗試更多的內存來請求您的應用程序做這個AndroidManisfest文件:

您可以使用

android:largeHeap="true" 

要求更大的堆大小,但這不會對任何工作預蜂窩設備。