Ответ 1
Возможно, вам удастся извлечь выгоду из переопределения protected void onAttachedToWindow()
и protected void onDetachedFromWindow()
, которые я никогда не пробовал, но их можно вызвать примерно, когда захотите.
У меня была куча кода в активности, которая отображает текущий график некоторых внешних данных. Поскольку код активности становился чем-то загроможденным, я решил извлечь этот код и создать класс GraphView
:
public class GraphView extends LinearLayout {
public GraphView(Context context, AttributeSet attrs) {
super(context, attrs);
LayoutInflater inflater = (LayoutInflater)
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.graph_view, this, true);
}
public void start() {
// Perform initialization (bindings, timers, etc) here
}
public void stop() {
// Unbind, destroy timers, yadda yadda
}
.
.
.
}
Перемещение материала в этот новый класс LinearLayout
-derived было простым. Но был некоторый код управления жизненным циклом, связанный с созданием и уничтожением таймеров и прослушивателей событий, используемых этим графиком (я не хотел, чтобы эта вещь была опроса в фоновом режиме, если активность была приостановлена, например).
Исходя из фона MS Windows, я как бы ожидал найти переопределяемые методы onCreate()
и onDestroy()
или что-то подобное, но я не нашел ничего подобного в LinearLayout (или любом из его унаследованных элементов). Чтобы оставить весь этот код инициализации в Activity, а затем передать его в представление, казалось, он победил исходную цель инкапсуляции всего этого кода в многоразовое представление.
В результате я добавил два дополнительных общедоступных метода: start()
и stop()
. Я делаю эти вызовы из действий onResume()
и onPause()
соответственно.
Это похоже на работу, но мне кажется, что я использую клейкую ленту здесь. Кто-нибудь знает, как это обычно делается? Я чувствую, что мне что-то не хватает...
Возможно, вам удастся извлечь выгоду из переопределения protected void onAttachedToWindow()
и protected void onDetachedFromWindow()
, которые я никогда не пробовал, но их можно вызвать примерно, когда захотите.
Я только сделал небольшой эксперимент с этим, но кажется, что если вы переопределите onAttachedToWindow
и onDetachedFromWindow
, как упоминалось выше в CaseyB, а также переопределите
protected void onWindowVisibilityChanged(int visibility)
Он должен предоставить вам необходимую информацию.
Я сталкиваюсь с той же ситуацией, что и вы. Я удивлен, что для этого нет механизма уведомления.
К сожалению, объект View не имеет методов обратных вызовов в качестве Activity при переходе из фона и активного режима.
В любом случае, если вы настаиваете на таком подходе, я думаю, что ближе всего вы ставите код инициализации в конструктор и код destruct в переопределение finalize(). Хотя, метод finalize() запускается системой, когда объект больше не упоминается, что делает его готовым к сбору мусора. Это может не быть вызвано вообще, если vm выйдет. И я бы не рекомендовал этот путь.
Кроме того, вы не хотите создавать и уничтожать объекты GraphView снова и снова, когда ваше приложение переходит из паузы, чтобы возобновить работу, поскольку объекты с коротким замыканием вызывают проблемы с памятью. Вы никогда не знаете, когда gc освободит память для этих объектов, даже нет ссылок на них.
Я думаю, что ваш approrach с методами start() и stop() в порядке, просто сохраните их просто и чисто. Все, что им нужно сделать, это сохранить объекты AsyncTasks (или объекты Timer).
(Не в тему о том, как вы раздуваете свои взгляды: я использую View.inflate() в основном, так как это меня спасает несколькими строками кода)