Всем добрый вечер.
В процессе разработки приложения есть большая необходимость передачи каких либо переменных из одной Активити в другую. Я использовал всегда стандартный метод:
Intent intent = new Intent(First.this, Second.class);
intent.putExtra("key",from_to);
startActivity(intent);
И далее получение:
String from_to = getIntent().getExtras().getString("key", "null");
Но данный метод мне откровенно осточертел, и я решил делать это через static преременные так:
static String from_to;
Где то:
from_to = "Hello dear Android";
И в другой активити:
String from_to = First.from_to;
Но теперь меня мучает вопрос: чем же это может обернуться для меня?!
Заранее всем спасибо!
Ответы
Ответ 1
Половина из написанного откровенная чушь не совсем верна. Если все делат
по человечачьи то ужасов навроде #сборщикмусораубил или #нарвалсянаnullpointer можно избежать.
В Android есть такой класс Application, который является естественным синглтоном. Как пишется в умной книжке:
When your Application implementation is registered in the manifest, it will be
instantiated when your application process is created. As a result your
Application implementation is by nature a singleton and should be implemented as
such to provide access to its methods and member variables.
Надо всего лишь создать свой собственный Application типа:
public class MyApplication extends Application {
private static MyApplication singleton;
private static MyVar myPreciousStaticVariable;
// Returns the application instance
public static MyApplication getInstance() {
return singleton;
}
public final void onCreate() {
super.onCreate();
singleton = this;
}
}
Правильно задекларировать в манифесте и вперед.
Нужные статические переменные (без фанатизма - то есть за минусом контекстов, юа
элементов и проч. сумасшедшины) пихаем в MyApplication с правильной инициализацией в Application.onCreate() или в конструкторе (не забываем про lazy-init!), обкладываем статику геттерами (при необходимости и сеттерами) и все.
Далее в более менее любом месте проги делаем так:
myVar=MyApplication.getInstance().getMyPreciousStaticVariable();
Update
С освобождением ресурсов в Application это действительно проблема. Поскольку в Applicatio
нет явного колбэка вызываемого при закрытии. Немного утешает, что Application создаетс
еще до момента создания любой из компонент приложения - Activity, Service, Receive
и проч. так что вы не сможете в Application явным образом создать эти объекты. А обще
правило при создании объекта гласит - уничтожай там же где и создал. Так что создаем скажем в Activity.onCreate() - стало быть уничтожаем в Activity.onDestroy() и т.д. В общем хранение синглтон объектов в Application имеет свои ограничения - я согласен. В любом случае Application будет выгружен последним и все что останется после него будет убрано сборщиком мусора - не совсем кошерно, конечно.
Ответ 2
обернется NullPointerException в тот прекрасный момент, когда приложение полность
выгрузится из памяти и будет открыто вновь (например, свернуто кнопкой "Домой" и открыто из списка последних запущенных).
допустим такая ситуация:
в Activity_A есть статичное поле, в Activity_B оно используется. текущий стек тако
Activity_A -> Activity_B. приложение выгрузилось из памяти, все ссылки на объекты
включая статичные поля, были обнулены. Приложение восстанавливается из памяти, первой будет загружена Activity_B (поскольку она на вершине стека), которая обращается к статичному полю в Activity_A, и тут же получает NullPointerException. Надеюсь понятно описал.
как раз-таки способ передачи через Intent более предпочтителен, поскольку все переданны
параметры будут сохранены вместе с состоянием текущей активности и будут так же восстановлены.
Ответ 3
Как минимум утечкой памяти. Поясняю.
Интернированные строки хранятся не в heapspace, а в permgen space. Сборка мусор
в нем происходит по отдельным правилам, не так как в heap-e / young /tenured memory pools.
Сборщик мусора в Java не является универсальным механизмом, позволяющим программист
полностью забыть о правилах использования памяти и о том, в каких случаях осуществляется его работа.
Статичная переменная хранится своим классом, а как следствие, его загрузчиком (classloader)
По причине внешнего использования увеличивается шанс, что сборщик мусора не соберё
данный экземпляр. Также зачастую в static-переменных кэшируется информация или же хранятся состояния, используемые несколькими потоками. Отдельным примером являются статичные коллекции. Хорошим же тоном при архитектурном проектировании служит полное избегание изменяемых статичных объектов — зачастую существует лучшая альтернатива.
Ответ 4
Тема старая, но всегда актуальная. Все ответы хороши, но забыт один довольно редкий случай, когда части приложения запущены в разных процессах.
Теория здесь: https://developer.android.com/guide/components/processes-and-threads.html
Так вот в случае межпроцессной коммуникации никакие статические переменные не помогут
В новом процессе загрузится класс по новому и все статические поля будут пустыми. И только Intent + Bundle + Parcelable вам смогут доставить данные в новый/иной процесс.
Комментариев нет:
Отправить комментарий