Другим случаем, когда NullReferenceExceptions
может случиться, является (неправильное) использование оператора as
:
class Book {
public string Name { get; set; }
}
class Car { }
Car mycar = new Car();
Book mybook = mycar as Book; // Incompatible conversion --> mybook = null
Console.WriteLine(mybook.Name); // NullReferenceException
Здесь Book
и Car
являются несовместимыми типами; a Car
не может быть преобразован / передан в Book
. Когда этот сбой завершается неудачно, as
возвращает null
. Используя mybook
после этого, вы вызываете NullReferenceException
.
В общем случае вы должны использовать cast или as
, как показано ниже:
Если вы ожидаете преобразования типа в всегда преуспевает (т. е. вы знаете, какой объект должен быть впереди времени), тогда вы должны использовать cast:
ComicBook cb = (ComicBook)specificBook;
Если вы не уверены в типе, но хотите попробовать , чтобы использовать его как определенный тип, затем используйте as
:
ComicBook cb = specificBook as ComicBook;
if (cb != null) {
// ...
}
Я столкнулся с той же проблемой. В основном это работает для меня, когда ANALActivity_finish (..) вызывается в основном цикле, поскольку он делает недействительными состояния и завершает само приложение, устанавливая state-> destroyRequested на 1 после вызова ANativeActivity_finish (..) в static void android_app_destroy (struct android_app * android_app) (android_native_app_glue.c C: 173).
void android_main(struct android_app* state)
{
// Attach current state if needed
state->activity->vm->AttachCurrentThread(&state->activity->env, NULL);
...
// our main loop for the app. Will only return once the game is really finished.
while (true) {
...
while ((ident=ALooper_pollAll(engine.animating ? 0 : -1, NULL, &events,(void**)&source)) >= 0) {
...
// Check if we are exiting. Which is the case once we called ANativeActivity_finish(state->activity);
if (state->destroyRequested != 0)
{
// Quit our app stuff herehere
// detatch from current thread (if we have attached in the beginning)
state->activity->vm->DetachCurrentThread();
// return the main, so we get back to our java activity which calle the nativeactivity
return;
}
}
if (engine.animating)
{
// animation stuff here
}
// if our app told us to finish
if(Closed)
{
ANativeActivity_finish(state->activity);
}
}
}
Ну, это слишком поздно для вас, я думаю, но я потратил так много времени на это, потому что я не мог найти султу, поэтому я разместите его здесь для всех, кто сталкивается с теми же проблемами. Подробнее о других сложностях, связанных с вызовами отсоединения и присоединения, можно найти здесь: Доступ к данным APK Asset Android непосредственно в c ++ без Asset Manager и копирование
Решение, которое в конечном итоге помогло мне закончить (подкласс a) NativeActivity
из приложения (родной), вызывало java-метод, который запускает finish()
в потоке пользовательского интерфейса.
C / C ++ сторона:
...
jmethodID FinishHim = jni->GetMethodID(activityClass, "FinishMe", "()V");
jni->CallVoidMethod(state->activity->clazz, FinishHim);
Сторона Java:
public class CustomNativeActivity extends NativeActivity {
...
public void FinishMe() {
this.runOnUiThread(new Runnable() {
public void run() {
finish();
}
});
}
}