Сообщение об ошибке "Системные службы недоступны для операций перед onCreate()"?

Когда пользователь нажимает на значок в моем приложении, я хочу, чтобы приложение сначала проверило, подключено ли устройство к Интернету, а затем что-то предприняло в зависимости от полученного результата (для примера, это просто всплывающее диалоговое окно, информирующее, является ли устройство подключен или нет). Итак, я написал этот код:

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;
}

}

Когда я пытаюсь запустить это приложение на эмуляторе, оно продолжает падать, и я получаю следующие сообщения об ошибках в 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

Почему это происходит и как мне это исправить? Я новичок в этом, так что... пожалуйста, будьте нежны!:)

6 ответов

Решение

Я думаю, это потому, что вы вызываете создание экземпляра слушателя onClick перед созданием. Попробуйте создать экземпляр прослушивателя onClick внутри onCreate() метод.

Это может или не может быть в случае с AlertDialog тоже, но я не совсем уверен.

Технически я считаю, что это следующая строка, которая вызывает проблему:

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

Тем не менее, потому что это называется в isNetworkConnected() Метод, который, в свою очередь, вызывается в вашем методе onClick, перемещение экземпляра onClick решает проблему.

Подсказка находится в исключении Системные сервисы, недоступные Операциям до onCreate()

Ошибка связана с созданием этого объекта.

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

Вы должны сделать это после вызова onCreate.

Для вызова системных служб мы должны использовать текущую активность. Это означает, что нам нужно выполнить onCreate метод, унаследованный к super, Таким образом, чтобы определить, что мы должны использовать текущий контекст приложения для вызова системной службы.

использование

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

или если у нас есть context объект, который ссылается на Contextмы можем использовать его как ниже

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

Правильный ответ

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

что уже упоминалось в jeet, и причина в том, что вы инициализировали AlertDialog до того, как какой-либо метод жизненного цикла был выполнен с контекстом Activity, который логически неверен.

И решение вашей проблемы

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();
    }

}

};

Инициализируйте диалоговое окно оповещения, когда его нужно увидеть. Причиной публикации ответа на эту старую ветку является принятый ответ, и ответ Джит не решил проблему, даже если вы переместите свой слушатель onclick из onCreate(), но проблема останется прежней.

Сегодня я столкнулся с той же проблемой с kotlin, где, если Интернет не доступен, то показать диалог ошибки, и моя глупая ошибка была

вместо передачи контекста как "это" я передал его как MainActivity()

Исправить R.string.error.errorDialog(this) //

Неверный R.string.error.errorDialog(MainActivity())

Добавьте следующее разрешение в файл AndroidManifest.xml.

Я думаю, что вы забыли добавить это разрешение.

android.permission.ACCESS_NETWORK_STATE

это поможет вам.

В моем случае я получил сообщение об ошибке: "Системные службы недоступны для Activity до onCreate()"

когда я инициализирую свойство класса, используя контекст, как показано ниже

 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)
        }

    }

Проблема в том, что вы определяете "слушатель" как глобальную переменную. Так как это указано в сообщении об ошибке: Системные сервисы недоступны Операциям до onCreate().

Ваш метод onCreate должен быть таким:

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);

}

Кроме того, если есть внутренний класс, скажем class MyAdapter extends ArrayAdapter<myModel> или подобное, это помогает НЕ создавать его экземпляр - (MyAdapter = new mAdapter<mModel>()) до деятельности onCreate(),

Другие вопросы по тегам