2010-11-17 2 views
102

Я работаю над довольно сложным Android-приложением, для которого требуется несколько большое количество данных о приложении (я бы сказал, что в общей сложности около 500 КБ - это большое для мобильных устройств устройство?). Из того, что я могу сказать, любое изменение ориентации приложения (в деятельности, если быть более точным) вызывает полное разрушение и восстановление активности. Основываясь на моих выводах, класс Application не имеет одинакового жизненного цикла (т. Е. Он, по сути, всегда инстанцируется). Имеет ли смысл хранить информацию о состоянии внутри класса приложения, а затем ссылаться на нее из Activity или это вообще не «приемлемый» метод из-за ограничений памяти на мобильных устройствах? Я очень ценю любые советы по этой теме. Благодаря!Использование класса приложения Android для сохранения данных

+8

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

+2

Mayra; Я не думаю, что приложение «обычно» удаляется (хотя, как кто-то указывает позже в этом потоке, он может «быть»). Я, вероятно, собираюсь перейти к некоторому «гибридному» подходу использования приложения для хранения и загрузки данных, но затем использовать атрибут «android: orientation» для активности в файле манифеста, чтобы переопределить нормальное поведение срывая и восстанавливая деятельность. Все это, конечно же, предполагает, что приложение может определить «когда» оно уничтожается, чтобы данные могли сохраняться. – Dave

ответ

129

Я не думаю, что 500kb будет такой большой сделкой.

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

Вы можете передавать данные в Global Singleton, если они будут использоваться много.

public class YourApplication extends Application 
{  
    public SomeDataClass data = new SomeDataClass(); 
} 

Затем вызовите его в какой-либо деятельности по:

YourApplication appState = ((YourApplication)this.getApplication()); 
appState.data.UseAGetterOrSetterHere(); // Do whatever you need to with the data here. 

Я обсуждаю это here in my blog post, в разделе "Global Singleton."

+1

К сожалению, сообщение в блоге больше не доступно по этому адресу. – mikebabcock

+1

Я перемещал вещи на своем сайте. Пока он не будет исправлен, вы можете найти его на archive.org здесь: https://web.archive.org/web/20130818035631/http://www.bryandenny.com/index.php/2010/05/25/what- i-learn-from-writing-my-first-android-application –

+1

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

1

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

+15

Вы можете многое сделать. Это не значит, что они хорошие идеи. Это не очень хорошая идея. – Andrew

+0

Тестирование путем изменения ориентации экрана - это самый простой способ убедиться, что ваше приложение делает то, что Android предполагает. – 18446744073709551615

55

Те, кто обращаются к Application примерам, являются неправильными. Во-первых, может показаться, что Application существует до тех пор, пока существует весь процесс приложения, но это неверное предположение.

ОС может убивать процессы по мере необходимости. Все процессы делятся на 5 уровней «killability» specified in the doc.

Так, например, если ваше приложение переходит в фоновом режиме из-за того, что пользователь отвечает на входящий вызов, тогда в зависимости от состояния ОЗУ ОС может (или не может) убить ваш процесс (уничтожая Application экземпляр в процессе).

Я думаю, что лучший подход был бы к persist your data to internal storage file, а затем читать его, когда ваша деятельность возобновится.

UPDATE:

Я получил много отрицательных обратных связей, так что настало время, чтобы добавить пояснение. :) Ну, изначально я действительно использовал неправильное предположение, что состояние действительно важно для приложения. Однако, если ваше приложение в порядке, что иногда состояние теряется (это могут быть некоторые изображения, которые будут просто перечитаны/перезаписаны), тогда вполне нормально держать его в качестве члена Application.

+13

Если Приложение убито, то кого это волнует, не так ли? Приложение исчезло. Насколько я понимаю, Android восстановит процессы, которые содержат память, например Activities. Если процесс, содержащий приложение, будет убит (если Android даже это сделает?), Это по сути похоже на убийство приложения. Пользователю нужно будет снова запустить приложение и, в этот момент, кого это волнует? Это новый пример приложения. – Andrew

+13

Это было неожиданным сюрпризом для нас в производстве. Поверьте мне, что Android убивает процессы, это просто зависит от состояния ОЗУ и других факторов, описанных в документации. Это был кошмар для нас, поэтому я просто передаю свой реальный опыт.Ну, у нас этого не было на эмуляторах, но в реальном мире некоторые устройства «перегружены» приложениями, поэтому убийство фонового процесса - нормальная ситуация. Да, если пользователь решает получить приложение на передний план - ОС восстанавливает свой стек, включая экземпляр «Приложение», однако ваши статические данные не будут учитываться, если вы не сохранили его. –

+2

Я думаю, что я, вероятно, буду использовать гибридный подход. Я уже знал о явном трюке, чтобы переопределить изменение ориентации (которое имеет другие преимущества). Поскольку приложение является игрой, я не уверен, что сохранение данных между запусками «важно» достаточно; хотя, вероятно, это было бы не так сложно, поскольку большинство данных можно было бы сериализовать (хотя я бы не хотел сериализовать и неэтериализовать между каждым изменением ориентации). Я определенно ценю вклад. Я бы не сказал, что те, которые зависят от экземпляра приложения, являются «неправильными». Многое зависит от приложения :). – Dave

6

Если вы хотите получить доступ к «Глобальному синглтону» за пределами действия, и вы не хотите передавать Context через все задействованные объекты для получения синглтона, вы можете просто определить статический атрибут в вашем классе приложения, который содержит ссылку на себя. Просто инициализируйте атрибут в методе onCreate().

Например:

public class ApplicationController extends Application { 
    private static ApplicationController _appCtrl; 

    public static ApplicationController getAppCtrl() 
    { 
     return _appCtrl; 
    } 
} 

Поскольку подклассы Application также могут получить ресурсы, вы можете получить доступ к их просто, когда вы определяете статический метод, который возвращает их, как:

public static Resources getAppResources() 
{ 
    return _appCtrl.getResources(); 
} 

Но будьте очень осторожны при прохождении контекстных ссылок на avoid memory leaks.

+6

Вы забыли отметить, что вы должны добавить android: name = ". ApplicationController" xml атрибут тега приложения в манифест для создаваемого класса. – eggie5

+0

Вам действительно не нужно расширять 'приложение' для этого. Вы можете объявить статическую переменную-член в ** любом классе ** для этого. –

2

Dave, какие данные? Если это общие данные, относящиеся к приложению в целом (пример: данные пользователя), затем расширьте класс приложения и сохраните его там. Если данные относятся к Activity, вы должны использовать обработчики onSaveInstanceState и onRestoreInstanceState для сохранения данных при вращении экрана.

0

Вы можете создать класс приложения и сохранить все данные в этом цикле для использования в любом месте приложения.

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