Графическая память неограниченно увеличивается в приложении для Android при переходе между фрагментами - PullRequest
0 голосов
/ 14 октября 2018

Я использую Android Studio, и я разработал очень простое приложение.Приложение имеет 3 фрагмента и один BottomNavigationView для навигации между фрагментами.Вот код, который я использую для навигации между фрагментами:

private Fragment chartFragment;
private Fragment tutorialFragment;
private Fragment optionFragment;
private FragmentManager fm;
private boolean isDisplaying;

@Override
protected void onCreate(Bundle savedInstanceState) {
    Log.i("LifeCicle","MainActivity - Created");
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    BottomNavigationView navigation = findViewById(R.id.navigation);
    navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);

    fm = getSupportFragmentManager();

    if(savedInstanceState != null){
        chartFragment = fm.getFragment(savedInstanceState,CHART_FRAGMENT__KEY);
        tutorialFragment = fm.getFragment(savedInstanceState,TUTORIAL_FRAGMENT__KEY);
        optionFragment = fm.getFragment(savedInstanceState,OPTION_FRAGMENT__KEY);
        isDisplaying = savedInstanceState.getBoolean(IS_DISPLAYING_KEY);
    }else{
        tryCreateFragmentsInstances();
        isDisplaying = false;
    }

    if(!isDisplaying){
        showFragment(chartFragment);
    }
}

private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
        = new BottomNavigationView.OnNavigationItemSelectedListener() {

    @Override
    public boolean onNavigationItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId()) {
            case R.id.navigation_home:
                if(tutorialFragment.isHidden()){
                    showFragment(tutorialFragment);
                }
                return true;
            case R.id.navigation_dashboard:
                if(chartFragment.isHidden()){
                    recreateChartFragment();
                }
                return true;
            case R.id.navigation_notifications:
                if(optionFragment.isHidden()){
                    showFragment(optionFragment);
                }
                return true;
        }
        return false;
    }
};

@Override
protected void onSaveInstanceState(Bundle outState) {
    Log.i("LifeCicle","MainActivity - Saving States");
    super.onSaveInstanceState(outState);

    if(chartFragment.isAdded()){
        fm.putFragment(outState,CHART_FRAGMENT__KEY,chartFragment);
        Log.i("LifeCicle","MainActivity - Chart fragment saved");
    }if(tutorialFragment.isAdded()){
        fm.putFragment(outState,TUTORIAL_FRAGMENT__KEY,tutorialFragment);
        Log.i("LifeCicle","MainActivity - Turotial fragment saved");
    }if(optionFragment.isAdded()){
        fm.putFragment(outState,OPTION_FRAGMENT__KEY,optionFragment);
        Log.i("LifeCicle","MainActivity - Option fragment saved");
    }

    outState.putBoolean(IS_DISPLAYING_KEY,isDisplaying);
}

@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    Log.i("LifeCicle","MainActivity - Restoring States");

}

private void tryCreateFragmentsInstances(){
    if(chartFragment == null){
        chartFragment = ChartFragment.newInstance(gameLetterTime,gameLetterNum);
        fm.beginTransaction().add(R.id.displayPanel,chartFragment).commit();
    }if(tutorialFragment==null){
        tutorialFragment = TutorialFragment.newInstance();
        fm.beginTransaction().add(R.id.displayPanel,tutorialFragment).commit();
    }if(optionFragment==null){
        optionFragment = OptionFragment.newInstance();
        fm.beginTransaction().add(R.id.displayPanel,optionFragment).commit();
    }
    hideAllFragments();
}

/**showFragment - Hide all fragments that are being displayed and show that one requested*/
private void showFragment(Fragment fragment){
    hideAllFragments();

    Log.i("LifeCicle","Displaying Fragment: "+fragment);
    fm.beginTransaction()
            .setCustomAnimations(android.R.anim.fade_in,android.R.anim.fade_out).
            show(fragment).commit();

    isDisplaying=true;
    fm.popBackStack();
}

/**hideAllFragments - hide all fragments that exists in the project
 * @see OptionFragment,ChartFragment,TutorialFragment*/
private  void hideAllFragments(){
    Log.i("LifeCicle","Hiding all fragments");
    if(!chartFragment.isHidden()){
        fm.beginTransaction().hide(chartFragment).commit();
    }if(!optionFragment.isHidden()){
        fm.beginTransaction().hide(optionFragment).commit();
    }if(!tutorialFragment.isHidden()){
        fm.beginTransaction().hide(tutorialFragment).commit();
    }
}

private void recreateChartFragment(){
    fm.beginTransaction().remove(chartFragment).commit();
    chartFragment = ChartFragment.newInstance(gameLetterTime,gameLetterNum);
    fm.beginTransaction().add(R.id.displayPanel,chartFragment).commit();
    showFragment(chartFragment);
}

Фрагмент ChartFragment, по особым причинам в моем приложении, мне нужно создавать его заново каждый раз, когда я хочу его отобразить.

После того, как я закончил приложение, я пошел в Profiler из студии Android, запустив приложение с моим реальным устройством.

Приложение запускается с использованием памяти 30 МБ, а 15 МБ описываются как графическая память,

Моя проблема в том, что каждый раз, когда я перемещаюсь между фрагментами, использование памяти увеличивается все больше и больше.Я ожидал, что использование памяти будет расти, но до некоторого момента.

Навигация вперед и назад между 3 фрагментами. Я мог бы увеличить объем используемой памяти до 80 МБ, а 44 МБ описать как графическую память.Ниже есть фотография моего профилировщика (все, что я делал во время этого теста, это переключался между фрагментами, нажимая на кнопки BottomNavigationView):

Profiler

Последнее событие сборщика мусора, которое явынужден проверить, уменьшит ли это использование памяти графической памятью, но это не сработало.

Это нормально для такого небольшого приложения?(внутри фрагментов просто тексты без изображений вообще!) Я пропускаю некоторую утечку памяти или делаю навигацию между фрагментами действительно плохим способом?

Я пытался уменьшить использование памяти в течение нескольких дней, но ничего не получалось.

...