Страница 1 из 1

освобождение private static объектов

Добавлено: 09 апр 2015, 11:43
slbel
Доброго всем времени суток!

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

Есть объект класса Foo который создается в единственном экземпляре через newInstance() в OnCreate основной Activity.

Код: Выделить всё

protected void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     setContentView(R.layout.activity_main);
// ...
     Foo foo = Foo.newInstance(this);
     if (foo != null) {
// можно работать
     }
сам объект Foo выглядит примерно так:

Код: Выделить всё

class Foo {
    public static ArrayList<SubFoo1> subFoo1;
    public static ArrayList<SubFoo2> subFoo2;
    public static ArrayList<SubFoo3> subFoo3;

    public static Foo newInstance(Context context) {
// создание объектов subFoo1, subFoo2, subFoo3 (загрузка данных через XML)
// данный метод может выбросить исключение если данные в XML файле некорректны
   }
    
// сам конструктор - пустой
    private Foo(Context context) { }
}
Опытным путем установлено (через сообщения Logcat), что хотя объект foo уничтожается (null -ится), внутренние структуры объекта subFoo1, subFoo2, subFoo3 по-прежнему висят в памяти, и при повторном запуске приложения (через эмулятор) в методе newInstance(Context context) выбрасывается исключение, т.к. программа косвенно ожидает что subFoo1, subFoo2, subFoo3 будут не инициализированы.

Что интересно, почему-то метод Foo.Finalize() - не вызывается :(
Что я могу сделать:
Явно удалить все внутренние структуры в OnDestroy основной Activity. Остается только один неясный момент, OnCreate может быть вызван несколько раз минуя OnDestroy().
см. lifecycle Activity:
http://developer.android.com/reference/ ... ivity.html

Как здесь лучше поступить?

Re: освобождение private static объектов

Добавлено: 09 апр 2015, 17:29
doter.ua
Зачем такие велосипеды? гонять данные по приложению можно и без статиков.

Re: освобождение private static объектов

Добавлено: 10 апр 2015, 08:06
slbel
doter.ua писал(а):Зачем такие велосипеды? гонять данные по приложению можно и без статиков.
Вообще-то я хотел бы создать класс, к которому можно обращаться так: <имя класса>.<поле класса> (паблик статик).
Экземпляр объекта мне не нужен. А инициализацию класса произвести в методе OnCreate главной активити (класс инициализируется из данных XML ресурса).

Идеально чтобы этот класс был наследником ArrayList<мой тип объекта>.

Но пока не знаю как это сделать :(

Re: освобождение private static объектов

Добавлено: 10 апр 2015, 12:15
KamiSempai
Инициализация статик ссылок при создании объекта - хуже и не придумаешь.

Re: освобождение private static объектов

Добавлено: 10 апр 2015, 12:17
Mikhail_dev
В каком смысле хуже не придумаешь? А каким образом происходит ленивая инициализация синглтона?

Re: освобождение private static объектов

Добавлено: 11 апр 2015, 14:55
KamiSempai
Mikhail_dev писал(а):В каком смысле хуже не придумаешь? А каким образом происходит ленивая инициализация синглтона?
То есть автор поста все делает правильно? Ну только в некоторых местах подправить, что бы ошибок не возникало, так?

Re: освобождение private static объектов

Добавлено: 11 апр 2015, 20:52
Mikhail_dev
Да, в некоторых местах подправить, к примеру у subFoo1, subFoo2, subFoo2 просто удалить static префикс и инициализировать их не в newInstance, а в конструкторе объекта. Тем самым, они буду уничтожаться вместе с объектом.
P.S. автор, почитайте про статические и динамические объекты, и как они вообще живут.
Что интересно, почему-то метод Foo.Finalize() - не вызывается :(
А его вызов на сколько помню и не гарантирован. К тому же указав static префикс, вы автоматически привязали данные ссылки к объекту класса, а не к создаваемому объекту. Чтобы понять о чем я, читать "P.S. " выше.

Re: освобождение private static объектов

Добавлено: 13 апр 2015, 08:10
slbel
Mikhail_dev писал(а):Да, в некоторых местах подправить, к примеру у subFoo1, subFoo2, subFoo2 просто удалить static префикс и инициализировать их не в newInstance, а в конструкторе объекта. Тем самым, они буду уничтожаться вместе с объектом.
P.S. автор, почитайте про статические и динамические объекты, и как они вообще живут.
Что интересно, почему-то метод Foo.Finalize() - не вызывается :(
А его вызов на сколько помню и не гарантирован. К тому же указав static префикс, вы автоматически привязали данные ссылки к объекту класса, а не к создаваемому объекту. Чтобы понять о чем я, читать "P.S. " выше.
Спасибо за идею, я имею ввиду синглетоны. Почитал немного про них, но так до конца не разобрался как это все работает.

Что касается инициализации объекта через newInstance - это сделано только потому, что при инициализации может выбросить исключение (некорректные данные в XML файле, например дублирование записей, или отсутствие необходимого атрибута).

Сейчас пока сделал без статиков, все вроде удаляется корректно. Но исключение может быть выброшено прямо из конструктора, что мне не очень нравится. Хотелось бы просто вернуть ссылку null.

И еще попутно вопрос: есть ли в андроид приложении место, которое выполняется только один раз за весь жизненный цикл приложения? Заметил, что даже поворот экрана вызывает onDestroy() -> onCreate() (на старых версиях андроида точно). А хотелось бы загружать конфигурацию из XML файла только один раз - XML структура достаточно громоздкая и требует значительных ресурсов.
Можно ли такую отловить ситуацию а onCreate с помощью следующей конструкции:?

Код: Выделить всё

		act_string = getIntent().getAction();
		if( -1 != act_string.indexOf("android.intent.action.MAIN")){...}