Как управлять жизненным циклом в классе, производном от ViewGroup? - PullRequest
29 голосов
/ 01 марта 2010

У меня была группа кода в действии, которая отображает текущий график некоторых внешних данных. Поскольку код активности становился все более загроможденным, я решил извлечь этот код и создать класс 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 (или любом из его унаследованных членов). Необходимость оставить весь этот код инициализации в Activity, а затем передать его в представление, казалось, побеждала первоначальную цель инкапсуляции всего этого кода в представление многократного использования.

В итоге я добавил два дополнительных публичных метода в мое представление: start() и stop(). Я делаю эти вызовы из методов деятельности onResume() и onPause() соответственно.

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

Ответы [ 3 ]

23 голосов
/ 11 марта 2010

Возможно, вам удастся получить некоторую пользу от переопределения protected void onAttachedToWindow() и protected void onDetachedFromWindow() Я никогда не пробовал, но они могут быть вызваны приблизительно тогда, когда вы захотите.

6 голосов
/ 23 марта 2010

Я только что провел небольшой эксперимент с этим, но кажется, что если вы переопределите onAttachedToWindow и onDetachedFromWindow, как упомянуто выше CaseyB, наряду с переопределением

protected void onWindowVisibilityChanged(int visibility)

Он должен дать вам необходимую информацию.

Я сталкиваюсь с той же ситуацией, что и вы. Я удивлен, что для этого нет механизма уведомления.

2 голосов
/ 08 марта 2010

К сожалению, объект View не имеет методов обратного вызова в качестве Activity при переходе из фонового и активного режима.

В любом случае, если вы настаиваете на таком подходе, я думаю, самое близкое, что вы получите, - это вставить код инициализации в конструктор, а код destruct - в переопределение finalize (). Тем не менее, метод finalize () запускается системой, когда на объект больше не ссылаются, что делает его готовым для сбора мусора. Может не вызываться вообще, если vm выходит. И я бы не советовал так.

Кроме того, вы не хотите создавать и уничтожать объекты (и) GraphView снова и снова, когда ваше приложение переходит из паузы в режим возобновления, поскольку недолговечные объекты вызывают утечки памяти. Вы никогда не знаете, когда gc освободит память для этих объектов, даже если на них нет ссылок.

Я думаю, что вы с методами start () и stop () в порядке, просто держите их простыми и чистыми. Все, что им нужно сделать, - это поддерживать AsyncTasks (или объекты Timer).

(Не по теме, касающейся того, как вы раздуваете свои представления: я использую View.inflate () главным образом, поскольку это экономит меня на несколько строк кода)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...