2016-10-13 2 views
2

Я разрабатываю подробный вид продукта, который дает предложения аналогичных продуктов (пробуждение одной и той же активности с другим продуктом, у которого также есть предложения), более или менее похожим на активность приложения Google Play. Проблема возникает, когда обращается к нескольким связанным продуктам, что вызывает OutOfMemoryException (поскольку мы сохраняем все предыдущие экземпляры этой ProductDetailActivity на BackStack).Как эффективно управлять навигацией Android?

Есть ли способ обеспечить надлежащую историю продукции, не сохраняя при этом все предыдущие действия, потребляющие память?

Я проверил приложение Google Play, и я не могу понять, как это происходит, но похоже, что он сохраняет все предыдущие действия и не вызывает никакой OutOfMemory при навигации по связанным приложениям по связанным приложениям.

+0

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

ответ

0

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

Вы можете думать о нескольких действиях, таких как стек. Когда пользователь выбирает предложение продукта, текущая активность помещается в стек и запускается новое действие. И наоборот, когда нажата кнопка «Назад», действие завершается, и предыдущая активность вылетает из стека и становится текущим.

Это может потреблять много памяти в зависимости от вашего приложения.

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

Итак, давайте начнем с создания стека:

 private ArrayList<Bundle> mProductStack; 

Вам нужно будет сохраняться этот стек в onSaveInstanceState() и восстановить его в onCreate(). Давайте избавимся от них:

@Override 
    public void onSaveInstanceState(Bundle outState) { 
     // ... all your other state saving code 
     outState.putParcelableArrayList("productStack", mProductStack); 
     super.onSaveInstanceState(outState); 
    } 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     // ... all your other activity create logic 
     if (savedInstanceState != null) { 
      mProductStack = savedInstanceState.getParcelableArrayList("productStack"); 
     } else { 
      mProductStack = new ArrayList<>(); 
     } 
    } 

Существует причина использования списка, а не стека. У меня было много проблем с сохранением/отменой Stack<Bundle> вокруг кастинга и т. Д., Поэтому я решил пойти с простым ArrayList<Bundle>, который поддерживается непосредственно Bundle (putParcelableArrayList() и т. Д.).

Теперь, когда пользователь переходит к новому продукту, вам необходимо сохранить текущее состояние в стеке и загрузить новый продукт в текущую операцию. Ваше состояние может быть даже просто как продукт ID:

 Bundle entry = new Bundle(); 
    entry.putInt("productId", mProductId); 
    mProductStack.add(entry); // push 
    // ... load the data for the next product 

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

 int scrollPos = mNestedScrollView.getScrollY(); // remember where we were in the list 
    entry.putInt("scrollPos", scrollPos); 

Теперь вы просто должны обрабатывать спину нажмите кнопку:

@Override 
public void onBackPressed() { 

    if (mProductStack.isEmpty()) { 
     super.onBackPressed(); 
     return; 
    } 

    Bundle entry = mProductStack.remove(mProductStack.size() - 1); // pop 
    mProductId= entry.getInt("productId"); 
    // ... load the data for the previous product 
} 

Я не знаю, насколько сложна ваша состояние, но имейте в виду, что все типы данных, которые вы хотите сохранить нужно будет реализовать Parcelable. В этой теме есть много контента в Интернете (в том числе SO).

Вещь, которая, кажется, оказывает наибольшее влияние на память, - это изображения. Управление памятью для растровых изображений - это целая неприятная тема для себя.Возможно, вы захотите реализовать некоторый тип кеша LRU для изображений, поэтому вам не нужно повторно извлекать изображения для предыдущего продукта —, если ограничения памяти не заставят вас это сделать.

+0

спасибо, что сработало как шарм! – Andoni

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