2013-11-29 5 views
0

У меня есть один фрагмент, который как разная ориентация меняется. Но поскольку я не хочу, чтобы моя деятельность воссоздавалась, я использовал android:configChanges="orientation|screenSize|keyboardHidden" в операции Фрагмент, в которой хранится мой фрагмент.Ошибка памяти при изменении ориентации при использовании фрагмента

Таким образом, в фрагменте я переопределение onConfiguratinoChanged, как показано ниже:

@Override 
public void onConfigurationChanged(Configuration newConfig) { 
    // TODO Auto-generated method stub 
    super.onConfigurationChanged(newConfig); 
    // need to change the according port/landscape layout file as recreation of activity is restricted. 
    main.removeAllViews();   
    main.addView(View.inflate(getActivity(), R.layout.fragment_home, null)); 
} 

В fragment_home корневого вида я поставил фоновое изображение, которое отличается для портретных и альбомных макетов.

Я устанавливаю свои фоновые изображения только в макете xml.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/tablet_home_main" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:background="@drawable/bg_landscape" //bg_portrait changed in portrait layout 
    android:orientation="vertical" 
    android:paddingTop="10dp" > 

Я сохранил свои фоновые изображения в папке drawable-hdpi.

Это мой фрагмент:

public class HomeFragment extends SherlockFragment { 
    LinearLayout main; 
    @Override 
    public View onCreateView(LayoutInflater inflater, 
      ViewGroup container,Bundle savedInstanceState) { 

    View rootView = inflater.inflate(R.layout.fragment_home, container,false); 
    main = (LinearLayout) rootView.findViewById(R.id.tablet_home_main);  
    return rootView; 
    } 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    } 
    @Override 
     public void onConfigurationChanged(Configuration newConfig) { 
    // TODO Auto-generated method stub 
    super.onConfigurationChanged(newConfig);   
    main.removeAllViews(); 
    main.addView(View.inflate(getActivity(), R.layout.fragment_home, null)); 
    } 
} 

Мой вопрос, когда я постоянно менять ориентацию дома фрагмента 4-5 раз мое приложение падает и показать следующее сообщение об ошибке:

Caused by: java.lang.OutOfMemoryError 
at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method) 
    at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:502) 
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:355) 
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:785) 
at android.content.res.Resources.loadDrawable(Resources.java:1965) 
at android.content.res.TypedArray.getDrawable(TypedArray.java:601) 
at android.widget.ImageView.<init>(ImageView.java:120) 
at android.widget.ImageView.<init>(ImageView.java:110) 
+0

ты пользуешься Растровые изображения (изображения) большого размера? –

+0

@GopalRao Мой фоновый растровый чертеж для размещения portait составляет 51 kb, а для макета ландшафта 48 kb – Dory

+0

Пожалуйста, покажите код, где создайте растровое изображение из потока. У вас там утечка памяти. –

ответ

2

Во-первых, в

onCreateView(...) 

вы ar е накачивании представления с идентификатором компоновки R.layout.fragment_home и вы назначаете это значение основных как

View rootView = inflater.inflate(R.layout.fragment_home, container,false); 
main = (LinearLayout) rootView.findViewById(R.id.tablet_home_main); 

так вот главное, LinearLayout

и

onConfigurartiion(...) 

вы снова надувая с тем же id R.layout.fragment_home и добавлением к main просмотров.

так что вы держите на добавление LinearLayout к LinearLayout ...

попробовать это ..

private FrameLayout frameLayout; 
    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
      Bundle savedInstanceState) { 
     frameLayout = new FrameLayout(getActivity()); 
     View view = inflater.inflate(R.layout.activity_main, null); 
     frameLayout.addView(view); 
     return frameLayout; 
    } 

    @Override 
    public void onConfigurationChanged(Configuration newConfig) { 
     super.onConfigurationChanged(newConfig); 
     View view = frameLayout.getChildAt(0); 
     Drawable drawable = view.getBackground(); 
     frameLayout.removeAllViews(); 
     if(drawable != null && drawable instanceof BitmapDrawable) { 
      BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable; 
      bitmapDrawable.getBitmap().recycle(); 
     } 
     LayoutInflater inflater = getActivity().getLayoutInflater(); 
     if(newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) { 
      view = inflater.inflate(R.layout.landscape_layout, null); 
     } else { 
      view = inflater.inflate(R.layout.portraitlayout, null); 
     } 
     frameLayout.addView(view); 
    } 
+0

Это может потенциально «исправить» проблему, но не касается реальной проблемы. 'removeAllViews()' должен очищать память, но не будет, если есть ссылки на макет или дочерние представления. Downvoted, поскольку это не касается основной проблемы. –

+0

@JeffreyKlardie Будьте осторожны, когда вы делаете downvoting, он удаляет Views из Linearlayout, потому что все виды в макете удаляются.но он устанавливает фон Lingleayout, который представляет собой большое изображение. удаление всех представлений из линейного макета не очистит его фон ... –

+0

Я удалил нижний предел, поскольку я не вижу четких проблем во фрагменте, который может привести к утечке памяти (удалит, когда я смогу сделать это снова, временные ограничения) , Тем не менее, 'removeAllViews()' должен очистить всю память удаленных просмотров, и поэтому делать это самостоятельно не нужно. Кажется, что-то еще утечка памяти. –

Смежные вопросы