以下のような場合に問題ないのかが気になっていました。 これ、クラッシュしそうですよね??
@Inject lateinit var dep: Dep
val value = dep.value
class Dep @Inject constructor() {
val value = "aaaa"
}
@AndroidEntryPoint
class CustomView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : FrameLayout(context, attrs, defStyleAttr) {
@Inject lateinit var dep: Dep
val value = dep.value
}
これは以下のようなコードを生成し、CustomViewが継承するようになります。つまりコンストラクタ内でinjectされます。
public abstract class Hilt_CustomView extends FrameLayout implements GeneratedComponentManagerHolder {
private ViewComponentManager componentManager;
private boolean injected;
Hilt_CustomView(Context context) {
super(context);
inject();
}
Hilt_CustomView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
inject();
}
Hilt_CustomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
inject();
}
@TargetApi(21)
Hilt_CustomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr,
int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
inject();
}
...
CustomViewの変換後のdecompile後は以下のようになります。
以下のようにsuperのコンストラクタが呼ばれたあと、つまりinjectされた後にgetValue()などが行われるため、問題なさそうです
抜粋
super(context, attrs, defStyleAttr);
Dep var10001 = this.dep;
if (var10001 == null) {
Intrinsics.throwUninitializedPropertyAccessException("dep");
}
this.value = var10001.getValue();
public final class CustomView extends Hilt_CustomView {
@Inject
public Dep dep;
@NotNull
private final String value;
@NotNull
public final Dep getDep() {
Dep var10000 = this.dep;
if (var10000 == null) {
Intrinsics.throwUninitializedPropertyAccessException("dep");
}
return var10000;
}
public final void setDep(@NotNull Dep var1) {
Intrinsics.checkNotNullParameter(var1, "<set-?>");
this.dep = var1;
}
@NotNull
public final String getValue() {
return this.value;
}
@JvmOverloads
public CustomView(@NotNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
Intrinsics.checkNotNullParameter(context, "context");
super(context, attrs, defStyleAttr);
Dep var10001 = this.dep;
if (var10001 == null) {
Intrinsics.throwUninitializedPropertyAccessException("dep");
}
this.value = var10001.getValue();
}
// $FF: synthetic method
public CustomView(Context var1, AttributeSet var2, int var3, int var4, DefaultConstructorMarker var5) {
if ((var4 & 2) != 0) {
var2 = (AttributeSet)null;
}
if ((var4 & 4) != 0) {
var3 = 0;
}
this(var1, var2, var3);
}
@JvmOverloads
public CustomView(@NotNull Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0, 4, (DefaultConstructorMarker)null);
}
@JvmOverloads
public CustomView(@NotNull Context context) {
this(context, (AttributeSet)null, 0, 6, (DefaultConstructorMarker)null);
}
色々いじってみる
複数パターン
以下のような場合も一応見てみましょう
@AndroidEntryPoint
class CustomView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : FrameLayout(context, attrs, defStyleAttr) {
@Inject lateinit var dep: Dep
val value = dep.value
@Inject lateinit var dep2: Dep
val value2 = dep2.value
}
問題なさそうでした。
public final class CustomView extends Hilt_CustomView {
@Inject
public Dep dep;
@NotNull
private final String value;
@Inject
public Dep dep2;
@NotNull
private final String value2;
@NotNull
public final Dep getDep() {
Dep var10000 = this.dep;
if (var10000 == null) {
Intrinsics.throwUninitializedPropertyAccessException("dep");
}
return var10000;
}
public final void setDep(@NotNull Dep var1) {
Intrinsics.checkNotNullParameter(var1, "<set-?>");
this.dep = var1;
}
@NotNull
public final String getValue() {
return this.value;
}
@NotNull
public final Dep getDep2() {
Dep var10000 = this.dep2;
if (var10000 == null) {
Intrinsics.throwUninitializedPropertyAccessException("dep2");
}
return var10000;
}
public final void setDep2(@NotNull Dep var1) {
Intrinsics.checkNotNullParameter(var1, "<set-?>");
this.dep2 = var1;
}
@NotNull
public final String getValue2() {
return this.value2;
}
@JvmOverloads
public CustomView(@NotNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
Intrinsics.checkNotNullParameter(context, "context");
super(context, attrs, defStyleAttr);
Dep var10001 = this.dep;
if (var10001 == null) {
Intrinsics.throwUninitializedPropertyAccessException("dep");
}
this.value = var10001.getValue();
var10001 = this.dep2;
if (var10001 == null) {
Intrinsics.throwUninitializedPropertyAccessException("dep2");
}
this.value2 = var10001.getValue();
}
コンストラクタを後ろに書くパターン
@AndroidEntryPoint
class CustomView : FrameLayout {
@Inject lateinit var dep: Dep
val value = dep.value
@JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : super(context, attrs, defStyleAttr)
}
問題なさそう
public final class CustomView extends Hilt_CustomView {
@Inject
public Dep dep;
@NotNull
private final String value;
@NotNull
public final Dep getDep() {
Dep var10000 = this.dep;
if (var10000 == null) {
Intrinsics.throwUninitializedPropertyAccessException("dep");
}
return var10000;
}
public final void setDep(@NotNull Dep var1) {
Intrinsics.checkNotNullParameter(var1, "<set-?>");
this.dep = var1;
}
@NotNull
public final String getValue() {
return this.value;
}
@JvmOverloads
public CustomView(@NotNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
Intrinsics.checkNotNullParameter(context, "context");
super(context, attrs, defStyleAttr);
Dep var10001 = this.dep;
if (var10001 == null) {
Intrinsics.throwUninitializedPropertyAccessException("dep");
}
this.value = var10001.getValue();
}
superに渡すパターン
IDE上、コンパイラでエラーになるので問題なさそうでした。
@AndroidEntryPoint
class CustomView : FrameLayout {
@Inject lateinit var dep: Dep
val value = dep.value
@JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : super(context, attrs, defStyleAttr + value.hashCode())
}