Igal
Igal

Reputation: 6093

"System services not available to Activities before onCreate()" Error message?

When the user hits an icon in my app, I want the app first to check if the device is connected to the internet and then do something depending on the result it receives (for know it's just popping up a dialog, informing whether the device is connected or not). So I wrote this code:

public class MainActivity extends Activity {

// SOME CONSTANTS WILL BE DEFINED HERE

AlertDialog.Builder builder = new AlertDialog.Builder(this);

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    findViewById(R.id.icoMyIcon).setOnClickListener(listener);
}


private OnClickListener listener = new OnClickListener() {

    public void onClick(View v) {
        if (isNetworkConnected()) {
            builder.setMessage("Internet connected!").setCancelable(false)
            .setPositiveButton("OK", null);
            builder.create().show();
        } else {
            builder.setMessage("Internet isn\'t connected!")
            .setCancelable(false)
            .setPositiveButton("OK", null);
            builder.create().show();
        }

    }
};


// Check if the device is connected to the Internet
private boolean isNetworkConnected() {
    ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo ni = cm.getActiveNetworkInfo();
    if (ni == null) {
        // There are no active networks.
        return false;
    } else
        return true;
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.activity_main, menu);
    return true;
}

}

When I'm trying to run this App on the emulator it keeps crushing and I'm getting this Error messages in LogCat:

07-24 22:59:45.034: E/AndroidRuntime(894): FATAL EXCEPTION: main
07-24 22:59:45.034: E/AndroidRuntime(894): java.lang.RuntimeException: Unable to 
    instantiate activity ComponentInfo{com.my.app/com.my.app.MainActivity}: 
    java.lang.IllegalStateException: System services not available to Activities before onCreate()
07-24 22:59:45.034: E/AndroidRuntime(894):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2585)
07-24 22:59:45.034: E/AndroidRuntime(894):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
07-24 22:59:45.034: E/AndroidRuntime(894):  at android.app.ActivityThread.access$2300(ActivityThread.java:125)
07-24 22:59:45.034: E/AndroidRuntime(894):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
07-24 22:59:45.034: E/AndroidRuntime(894):  at android.os.Handler.dispatchMessage(Handler.java:99)
07-24 22:59:45.034: E/AndroidRuntime(894):  at android.os.Looper.loop(Looper.java:123)
07-24 22:59:45.034: E/AndroidRuntime(894):  at android.app.ActivityThread.main(ActivityThread.java:4627)
07-24 22:59:45.034: E/AndroidRuntime(894):  at java.lang.reflect.Method.invokeNative(Native Method)
07-24 22:59:45.034: E/AndroidRuntime(894):  at java.lang.reflect.Method.invoke(Method.java:521)
07-24 22:59:45.034: E/AndroidRuntime(894):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
07-24 22:59:45.034: E/AndroidRuntime(894):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
07-24 22:59:45.034: E/AndroidRuntime(894):  at dalvik.system.NativeStart.main(Native Method)
07-24 22:59:45.034: E/AndroidRuntime(894): Caused by: java.lang.IllegalStateException: System services not available to Activities before onCreate()
07-24 22:59:45.034: E/AndroidRuntime(894):  at android.app.Activity.getSystemService(Activity.java:3526)
07-24 22:59:45.034: E/AndroidRuntime(894):  at com.android.internal.app.AlertController$AlertParams.<init>(AlertController.java:743)
07-24 22:59:45.034: E/AndroidRuntime(894):  at android.app.AlertDialog$Builder.<init>(AlertDialog.java:273)
07-24 22:59:45.034: E/AndroidRuntime(894):  at com.my.app.MainActivity.<init>(MainActivity.java:24)
07-24 22:59:45.034: E/AndroidRuntime(894):  at java.lang.Class.newInstanceImpl(Native Method)
07-24 22:59:45.034: E/AndroidRuntime(894):  at java.lang.Class.newInstance(Class.java:1429)
07-24 22:59:45.034: E/AndroidRuntime(894):  at android.app.Instrumentation.newActivity(Instrumentation.java:1021)
07-24 22:59:45.034: E/AndroidRuntime(894):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2577)
07-24 22:59:45.034: E/AndroidRuntime(894):  ... 11 more

Why is it happening and how do I fix it? I'm a novice at this, so... please be gentle! :)

Upvotes: 21

Views: 55113

Answers (8)

sandy
sandy

Reputation: 3351

Correct answer is

    AlertDialog.Builder builder = new AlertDialog.Builder(this);

which is already mentioned by jeet and reason is you have initialized AlertDialog before any lifecycle method of activity executed with Activity context that is logically not correct.

And solution to your problem is:

private OnClickListener listener = new OnClickListener() {

    public void onClick(View v) {
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
        if (isNetworkConnected()) {
            builder.setMessage("Internet connected!").setCancelable(false)
            .setPositiveButton("OK", null);
            builder.create().show();
        } else {
            builder.setMessage("Internet isn\'t connected!")
            .setCancelable(false)
            .setPositiveButton("OK", null);
            builder.create().show();
        }

    }
};

Initialize alert dialog when it need to visible. Reason behind posting answer to this old thread is the accepted answer and Jeet's answer did not solve the issue even if you move your onclick listener out of onCreate() still issue will be same.

Today I came across same issue with kotlin where if internet not available then show error dialog and my silly mistake was

instead of passing context as "this" I passed it as MainActivity()

Correct R.string.error.errorDialog(this) //

Wrong R.string.error.errorDialog(MainActivity())

Upvotes: 1

Agung
Agung

Reputation: 13813

in my case, I got error message : “System services not available to Activities before onCreate()”

when I initialize class property using context like below

 class MainActivity : AppCompatActivity() {

        // this line below
        private val notificationManager: NotificationManagerCompat = NotificationManagerCompat.from(this) 

        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
        }

    }

Upvotes: 0

E J Chathuranga
E J Chathuranga

Reputation: 925

To call system services we have to use running activity. That means we need executed onCreate method that inherited to the super. So to identify that we have to use the current application context to call system service.

use

ConnectivityManager cm = (ConnectivityManager) getBaseContext().getSystemService(Context.CONNECTIVITY_SERVICE);

or if we have context object that reference to Context, we can use it as below

ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

Upvotes: 2

Narayana J
Narayana J

Reputation: 307

Also, if there's an inner class, say class MyAdapter extends ArrayAdapter<myModel> or similar, it helps NOT to instantiate it - (MyAdapter = new mAdapter<mModel>()) before the activity's onCreate().

Upvotes: 0

Jitesh Dalsaniya
Jitesh Dalsaniya

Reputation: 1917

add the following permission to AndroidManifest.xml file.

i think you forget to add this permission.

android.permission.ACCESS_NETWORK_STATE

it will help you.

Upvotes: 0

Burhan ARAS
Burhan ARAS

Reputation: 2517

The problem is that you define "listener" as a global variable. Since it's given in the error message: System services not available to Activities before onCreate().

Your onCreate method should be like this:

private OnClickListener listener = null;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    listener = new OnClickListener() {

    public void onClick(View v) {
        if (isNetworkConnected()) {
            builder.setMessage("Internet connected!").setCancelable(false)
            .setPositiveButton("OK", null);
            builder.create().show();
        } else {
            builder.setMessage("Internet isn\'t connected!")
            .setCancelable(false)
            .setPositiveButton("OK", null);
            builder.create().show();
        }

    }
};


    findViewById(R.id.icoMyIcon).setOnClickListener(listener);

}

Upvotes: 0

Jon Taylor
Jon Taylor

Reputation: 7905

I think it's because your instantiating an onClick listener before on create is called. Try instantiating the onClick listener inside the onCreate() method.

This may or may not be the case with the AlertDialog too, but I'm not entirely sure.

Technically I believe it is the following line that causes the problem:

ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);

However, because this is being called within the isNetworkConnected() method which in turn is called within your onClick method, moving the instantiation of the onClick fixes the problem.

The clue is in the exception System services not available to Activities before onCreate()

Upvotes: 19

jeet
jeet

Reputation: 29199

Error is due to create this object creation.

AlertDialog.Builder builder = new AlertDialog.Builder(this);

you should do this after onCreate has been invoked.

Upvotes: 10

Related Questions