Add initInternal to ViewController.

ViewController's init method was not ideal to override. On the one hand,
if you put a call super.init() first your onViewAttach method is called
before you're subclass's init.

Further, if you put your own code befer super.init(), you are still left
with the problem that your init is not automatically idempotent, and
multiple calls to #init() could result in multiple executions of your
code unless you handle it yourself.

With this change, #initInternal() is introduced, giving ViewControllers
a place to put their run-once code such that it runs before any
view-attachment callbacks are fired.

Fixes: 171472009
Test: manual
Change-Id: I2e284024c82e3f7c7b6f29f22a1ffa3c8aae9fcb
This commit is contained in:
Dave Mankoff
2020-10-22 10:49:13 -04:00
parent 311a1510b7
commit dd1341ec62
8 changed files with 26 additions and 17 deletions

View File

@@ -81,8 +81,7 @@ public abstract class KeyguardAbsKeyInputViewController<T extends KeyguardAbsKey
abstract void resetState();
@Override
public void init() {
super.init();
public void initInternal() {
mMessageAreaController.init();
}

View File

@@ -92,8 +92,7 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
* Attach the controller to the view it relates to.
*/
@Override
public void init() {
super.init();
public void initInternal() {
mKeyguardSliceViewController.init();
}

View File

@@ -178,8 +178,7 @@ public class KeyguardHostViewController extends ViewController<KeyguardHostView>
}
/** Initialize the Controller. */
public void init() {
super.init();
public void initInternal() {
mKeyguardSecurityContainerController.init();
}

View File

@@ -190,8 +190,8 @@ public class KeyguardPatternViewController
}
@Override
public void init() {
super.init();
public void initInternal() {
super.initInternal();
mMessageAreaController.init();
}

View File

@@ -169,8 +169,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
}
@Override
public void init() {
super.init();
public void initInternal() {
mSecurityViewFlipperController.init();
}

View File

@@ -70,8 +70,7 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
}
@Override
public void init() {
super.init();
public void initInternal() {
mKeyguardClockSwitchController.init();
}

View File

@@ -34,8 +34,7 @@ public class QSContainerImplController extends ViewController<QSContainerImpl> {
}
@Override
public void init() {
super.init();
public void initInternal() {
mQuickStatusBarHeaderController.init();
}

View File

@@ -26,8 +26,8 @@ import android.view.View.OnAttachStateChangeListener;
*
* Implementations should handle setup and teardown related activities inside of
* {@link #onViewAttached()} and {@link #onViewDetached()}. Be sure to call {@link #init()} on
* any child controllers that this uses. This can be done in {@link init()} if the controllers
* are injected, or right after creation time of the child controller.
* any child controllers that this uses. This can be done in {@link #initInternal()} if the
* controllers are injected, or right after creation time of the child controller.
*
* Tip: View "attachment" happens top down - parents are notified that they are attached before
* any children. That means that if you call a method on a child controller in
@@ -62,11 +62,18 @@ public abstract class ViewController<T extends View> {
mView = view;
}
/** Call immediately after constructing Controller in order to handle view lifecycle events. */
/**
* Call immediately after constructing Controller in order to handle view lifecycle events.
*
* Generally speaking, you don't want to override this method. Instead, override
* {@link #initInternal()} as a way to have an run-once idempotent method that you can use for
* setup of your ViewController.
*/
public void init() {
if (mInited) {
return;
}
initInternal();
mInited = true;
if (mView != null) {
@@ -77,6 +84,14 @@ public abstract class ViewController<T extends View> {
}
}
/**
* Run once when {@link #init()} is called.
*
* Override this to perform idempotent, one-time setup that your controller needs. It will
* be called before {@link #onViewAttached()}.
*/
protected void initInternal() {}
protected Context getContext() {
return mView.getContext();
}