У меня был набор кода в действии, которое отображает рабочий график некоторых внешних данных. Поскольку код деятельности становился отчасти нарушенным, я решил извлечь этот код и создать a 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
- производный класс был прост. Но был некоторый код управления жизненным циклом, связанный с созданием и уничтожением таймеров и слушателей события, используемых этим графиком (я не хотел эту вещь, опрашивающую в фоновом режиме, если действие было приостановлено, например).
Происходя из среды MS Windows, я отчасти ожидал находить переопределяемым onCreate()
и onDestroy()
методы или что-то подобное, но я не нашел ничего вида в LinearLayout (или ни один из его наследованных участников). Необходимость оставить весь этот код инициализации в Действии и затем необходимость передать его в представление казались, что это победило исходную цель инкапсулировать весь этот код в допускающее повторное использование представление.
Я закончил тем, что добавил два дополнительных открытых метода для своего представления: start()
и stop()
. Я выполняю эти вызовы от действия onResume()
и onPause()
методы соответственно.
Это, кажется, работает, но такое чувство, что я использую клейкую ленту здесь. Кто-либо знает, как это обычно делается? Я чувствую, что пропускаю что-то...
Вы можете получить некоторую пользу от переопределения protected void onAttachedToWindow ()
и protected void onDetachedFromWindow ()
Никогда не пробовал, но могут позвонить примерно когда захотите.
К сожалению, объект View не имеет каких-либо методов обратного вызова в качестве Activity при переходе из фонового и активного режима.
В любом случае, если вы настаиваете на таком подходе, я думаю, что самое лучшее, что вы получите, - это поместить код инициализации в конструктор, а код деструкции - в переопределение finalize (). Однако метод finalize () запускается системой, когда объект больше не упоминается, что делает его готовым к сборке мусора. Он может не вызываться вообще, если vm завершает работу. И я бы не рекомендовал такой способ.
Кроме того, вы не хотите создавать и уничтожать объект (ы) GraphView снова и снова, когда ваше приложение переходит из паузы в возобновление, поскольку короткоживущие объекты вызывают утечку памяти. Никогда не угадаешь, когда gc освободит память для этих объектов, даже если на них нет ссылок.
Я думаю, что ваш подход с методами start () и stop () в порядке, просто делайте их простыми и понятными. Все, что им нужно сделать, это поддерживать AsyncTasks (или объекты Timer).
(Не по теме относительно того, как вы увеличиваете свои взгляды: я использую View.inflate () в основном, потому что это экономит мне несколько строк кода)
Я провел с этим лишь краткий эксперимент, но похоже, что если вы переопределите onAttachedToWindow
и onDetachedFromWindow
], как упомянуто CaseyB выше, вместе с переопределением
protected void onWindowVisibilityChanged (int visibility)
Он должен предоставить вам необходимую информацию.
У меня такая же ситуация, как и у вас. Я удивлен, что для этого нет механизма уведомлений.