Сообщение об ошибке "Системные службы недоступны для операций перед 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()
,