Android: использование JNI от NativeActivity

Мы разрабатываем игру OpenGL на Android с использованиемNativeActivity учебный класс. Пока все прошло хорошо, но теперь нам нужно получить доступ к некоторым функциям, которые, похоже, доступны только с Java.

Есть и другие, но первое, что мы посчитали полезным, это доступ к DPI дисплея. Как описаноВот код Java выглядит следующим образом:

DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);

И вот неудачный соответствующий код C ++:

// My checking routine.
#define JNI_ASSERT(jni, cond) { \
  if (!(cond)) {\
    std::stringstream ss; \
    ss < __FILE__ < ":" < __LINE__; \
    throw std::runtime_error(ss.str()); \
  } \
  if (jni->ExceptionCheck()) { \
    std::stringstream ss; \
    ss < __FILE__ < ":" < __LINE__; \
    throw std::runtime_error("Exception: " + ss.str()); \
  } \
}

void print_dpi(android_app* app) {
  JNIEnv* jni;
  app->activity->vm->AttachCurrentThread(&jni, NULL);

  jclass activityClass = jni->FindClass("android/app/NativeActivity");
  JNI_ASSERT(jni, activityClass);

  jmethodID getWindowManager = jni->GetMethodID
                                    ( activityClass
                                    , "getWindowManager"
                                    , "()Landroid/view/WindowManager;"); 
  JNI_ASSERT(jni, getWindowManager);

  jobject wm = jni->CallObjectMethod(app->activity->clazz, getWindowManager);
  JNI_ASSERT(jni, wm);

  jclass windowManagerClass = jni->FindClass("android/view/WindowManager");
  JNI_ASSERT(jni, windowManagerClass);

  jmethodID getDefaultDisplay = jni->GetMethodID( windowManagerClass
                                                , "getDefaultDisplay"
                                                , "()Landroid/view/Display;");
  JNI_ASSERT(jni, getDefaultDisplay);

  jobject display = jni->CallObjectMethod(wm, getDefaultDisplay);
  JNI_ASSERT(jni, display);

  jclass displayClass = jni->FindClass("android/view/Display");
  JNI_ASSERT(jni, displayClass);

  // Check if everything is OK so far, it is, the values it prints
  // are sensible.
  { 
    jmethodID getWidth = jni->GetMethodID(displayClass, "getWidth", "()I");
    JNI_ASSERT(jni, getWidth);

    jmethodID getHeight = jni->GetMethodID(displayClass, "getHeight", "()I");
    JNI_ASSERT(jni, getHeight);

    int width = jni->CallIntMethod(display, getWidth);
    JNI_ASSERT(jni, true);
    log("Width: ", width); // Width: 320

    int height = jni->CallIntMethod(display, getHeight);
    JNI_ASSERT(jni, true);
    log("Height: ", height); // Height: 480
  }

  jclass displayMetricsClass = jni->FindClass("android/util/DisplayMetrics");
  JNI_ASSERT(jni, displayMetricsClass);

  jmethodID displayMetricsConstructor = jni->GetMethodID( displayMetricsClass
                                                        , "

Ответы на вопрос(2)

Ваш ответ на вопрос