Android - Activity constructor

2020-02-13 05:55发布

问题:

I noticed that using the shortcut Alt + Insert and selecting the builders, it tries to create a constructor with each private property (e.g. cManager and mTextView). I remember I already created projects without it and worked correctly.

The error happens when I run the application, following the full logcat and the Activity constructor:

Constructor with private property:

private ConnectivityManager cManager;
private TextView mTextView;

public SplashScreenActivity() {
    this.cManager = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
    this.mTextView = (TextView)this.findViewById(R.id.mProgressText);
}

Logcat:

02-20 18:20:56.155    1591-1591/com.universo91.towersrock I/art﹕ Not late-enabling -Xcheck:jni (already on)
02-20 18:20:58.355    1591-1591/com.universo91.towersrock D/AndroidRuntime﹕ Shutting down VM
    --------- beginning of crash
02-20 18:20:58.361    1591-1591/com.universo91.towersrock E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.universo91.towersrock, PID: 1591
    java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.universo91.towersrock/com.universo91.towersrock.Pages.SplashScreenActivity}: java.lang.InstantiationException: class com.universo91.towersrock.Pages.SplashScreenActivity has no zero argument constructor
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2209)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
            at android.app.ActivityThread.access$800(ActivityThread.java:144)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5221)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
     Caused by: java.lang.InstantiationException: class com.universo91.towersrock.Pages.SplashScreenActivity has no zero argument constructor
            at java.lang.Class.newInstance(Class.java:1563)
            at android.app.Instrumentation.newActivity(Instrumentation.java:1065)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2199)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
            at android.app.ActivityThread.access$800(ActivityThread.java:144)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5221)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
     Caused by: java.lang.NoSuchMethodException: <init> []
            at java.lang.Class.getConstructor(Class.java:531)
            at java.lang.Class.getDeclaredConstructor(Class.java:510)
            at java.lang.Class.newInstance(Class.java:1561)
            at android.app.Instrumentation.newActivity(Instrumentation.java:1065)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2199)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
            at android.app.ActivityThread.access$800(ActivityThread.java:144)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5221)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
02-20 18:20:58.772    1591-1603/com.universo91.towersrock I/art﹕ Background sticky concurrent mark sweep GC freed 1747(114KB) AllocSpace objects, 0(0B) LOS objects, 37% free, 391KB/623KB, paused 825us total 382.655ms
02-20 18:21:29.824    1690-1690/com.universo91.towersrock D/AndroidRuntime﹕ Shutting down VM
02-20 18:21:29.829    1690-1690/com.universo91.towersrock E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.universo91.towersrock, PID: 1690
    java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.universo91.towersrock/com.universo91.towersrock.Pages.SplashScreenActivity}: java.lang.InstantiationException: class com.universo91.towersrock.Pages.SplashScreenActivity has no zero argument constructor
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2209)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
            at android.app.ActivityThread.access$800(ActivityThread.java:144)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5221)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
     Caused by: java.lang.InstantiationException: class com.universo91.towersrock.Pages.SplashScreenActivity has no zero argument constructor
            at java.lang.Class.newInstance(Class.java:1563)
            at android.app.Instrumentation.newActivity(Instrumentation.java:1065)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2199)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
            at android.app.ActivityThread.access$800(ActivityThread.java:144)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5221)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
     Caused by: java.lang.NoSuchMethodException: <init> []
            at java.lang.Class.getConstructor(Class.java:531)
            at java.lang.Class.getDeclaredConstructor(Class.java:510)
            at java.lang.Class.newInstance(Class.java:1561)
            at android.app.Instrumentation.newActivity(Instrumentation.java:1065)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2199)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
            at android.app.ActivityThread.access$800(ActivityThread.java:144)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5221)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
02-20 18:21:30.168    1690-1702/com.universo91.towersrock I/art﹕ Background sticky concurrent mark sweep GC freed 1749(114KB) AllocSpace objects, 0(0B) LOS objects, 37% free, 391KB/623KB, paused 856us total 166.355ms
02-20 18:21:53.341    1690-1690/com.universo91.towersrock I/Process﹕ Sending signal. PID: 1690 SIG: 9
02-20 18:26:00.878    1754-1754/com.universo91.towersrock D/AndroidRuntime﹕ Shutting down VM
02-20 18:26:00.903    1754-1754/com.universo91.towersrock E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.universo91.towersrock, PID: 1754
    java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.universo91.towersrock/com.universo91.towersrock.Pages.SplashScreenActivity}: java.lang.IllegalStateException: System services not available to Activities before onCreate()
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2209)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
            at android.app.ActivityThread.access$800(ActivityThread.java:144)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5221)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
     Caused by: java.lang.IllegalStateException: System services not available to Activities before onCreate()
            at android.app.Activity.getSystemService(Activity.java:4989)
            at com.universo91.towersrock.Pages.SplashScreenActivity.<init>(SplashScreenActivity.java:24)
            at java.lang.reflect.Constructor.newInstance(Native Method)
            at java.lang.Class.newInstance(Class.java:1572)
            at android.app.Instrumentation.newActivity(Instrumentation.java:1065)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2199)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
            at android.app.ActivityThread.access$800(ActivityThread.java:144)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5221)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
02-20 18:26:01.144    1754-1766/com.universo91.towersrock I/art﹕ Background sticky concurrent mark sweep GC freed 1745(118KB) AllocSpace objects, 0(0B) LOS objects, 38% free, 382KB/623KB, paused 950us total 131.218ms
02-20 18:26:04.429    1754-1754/com.universo91.towersrock I/Process﹕ Sending signal. PID: 1754 SIG: 9

回答1:

All of your initializations should be performed in the onCreate() method of your Activity:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.cManager = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
    this.mTextView = (TextView)this.findViewById(R.id.mProgressText);
}

Overriding the constructor of Activity involves quite a bit of heavy lifting, and is really not a walk in the park. Although you can [of course] have an empty constructor for an Activity, it really is quite superfluous in the context of the Android framework.

Related answers:

1. Why I cannot pass parameters to Android Activity Constructor.

2. Start an Activity with a parameter.



回答2:

Android activities can have constructors as long as they take zero arguments. And in fact there is such a constructor as soon as you initialize any field when declaring it.

But as your log says, System services not available to Activities before onCreate(), so you can't call getSystemService from the constructor.

So the code in https://stackoverflow.com/a/28636652/53974 is correct, but the reason isn't.



回答3:

Your code should be in onCreate()

Don't bother with a constructor for activities.



回答4:

Android activity allows only class default constructor is allowed. i.e. constructor with zero parameters. In default constructor you can do initializations to those final variables except which are linked system services as only available after lifecycle onCreate method.