1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-09 23:34:20 +00:00

JNI: Tidying

This commit is contained in:
reuk 2023-11-28 13:35:32 +00:00
parent 99d8b9b5e1
commit 8ce1f19bf0
No known key found for this signature in database
9 changed files with 60 additions and 63 deletions

View file

@ -1146,7 +1146,7 @@ public:
auto* env = getEnv(); auto* env = getEnv();
jclass audioManagerClass = env->FindClass ("android/media/AudioManager"); LocalRef<jclass> audioManagerClass { env->FindClass ("android/media/AudioManager") };
// We should be really entering here only if API supports it. // We should be really entering here only if API supports it.
jassert (audioManagerClass != nullptr); jassert (audioManagerClass != nullptr);
@ -1202,7 +1202,7 @@ public:
void addDevice (const LocalRef<jobject>& device, JNIEnv* env) void addDevice (const LocalRef<jobject>& device, JNIEnv* env)
{ {
auto deviceClass = LocalRef<jclass> ((jclass) env->FindClass ("android/media/AudioDeviceInfo")); LocalRef<jclass> deviceClass { env->FindClass ("android/media/AudioDeviceInfo") };
jmethodID getProductNameMethod = env->GetMethodID (deviceClass, "getProductName", jmethodID getProductNameMethod = env->GetMethodID (deviceClass, "getProductName",
"()Ljava/lang/CharSequence;"); "()Ljava/lang/CharSequence;");

View file

@ -286,7 +286,7 @@ void JNIClassBase::initialise (JNIEnv* env, jobject context)
if (sdkVersion >= minSDK) if (sdkVersion >= minSDK)
{ {
LocalRef<jstring> classNameAndPackage (javaString (String (classPath).replaceCharacter (L'/', L'.'))); const auto classNameAndPackage = javaString (String (classPath).replaceCharacter (L'/', L'.'));
static Array<GlobalRef> byteCodeLoaders; static Array<GlobalRef> byteCodeLoaders;
if (! SystemJavaClassComparator::isSystemClass (this)) if (! SystemJavaClassComparator::isSystemClass (this))
@ -294,8 +294,9 @@ void JNIClassBase::initialise (JNIEnv* env, jobject context)
// We use the context's class loader, rather than the 'system' class loader, because we // We use the context's class loader, rather than the 'system' class loader, because we
// may need to load classes from our library dependencies (such as the BillingClient // may need to load classes from our library dependencies (such as the BillingClient
// library), and the system class loader is not aware of those libraries. // library), and the system class loader is not aware of those libraries.
const LocalRef<jclass> contextClass { env->FindClass ("android/content/Context") };
const LocalRef<jobject> defaultClassLoader { env->CallObjectMethod (context, const LocalRef<jobject> defaultClassLoader { env->CallObjectMethod (context,
env->GetMethodID (env->FindClass ("android/content/Context"), env->GetMethodID (contextClass,
"getClassLoader", "getClassLoader",
"()Ljava/lang/ClassLoader;")) }; "()Ljava/lang/ClassLoader;")) };
@ -466,12 +467,12 @@ LocalRef<jobject> CreateJavaInterface (AndroidInterfaceImplementer* implementer,
// you need to override at least one interface // you need to override at least one interface
jassert (interfaceNames.size() > 0); jassert (interfaceNames.size() > 0);
auto classArray = LocalRef<jobject> (env->NewObjectArray (interfaceNames.size(), JavaClass, nullptr)); LocalRef<jobject> classArray { env->NewObjectArray (interfaceNames.size(), JavaClass, nullptr) };
LocalRef<jobject> classLoader; LocalRef<jobject> classLoader;
for (auto i = 0; i < interfaceNames.size(); ++i) for (auto i = 0; i < interfaceNames.size(); ++i)
{ {
auto aClass = LocalRef<jobject> (env->FindClass (interfaceNames[i].toRawUTF8())); LocalRef<jobject> aClass { env->FindClass (interfaceNames[i].toRawUTF8()) };
if (aClass != nullptr) if (aClass != nullptr)
{ {
@ -487,8 +488,8 @@ LocalRef<jobject> CreateJavaInterface (AndroidInterfaceImplementer* implementer,
} }
} }
auto invocationHandler = LocalRef<jobject> (env->NewObject (JuceInvocationHandler, JuceInvocationHandler.constructor, LocalRef<jobject> invocationHandler { env->NewObject (JuceInvocationHandler, JuceInvocationHandler.constructor,
reinterpret_cast<jlong> (implementer))); reinterpret_cast<jlong> (implementer)) };
// CreateJavaInterface() is expected to be called just once for a given implementer // CreateJavaInterface() is expected to be called just once for a given implementer
jassert (implementer->invocationHandler == nullptr); jassert (implementer->invocationHandler == nullptr);
@ -631,7 +632,7 @@ int getAndroidSDKVersion()
// when this method is used // when this method is used
auto* env = getEnv(); auto* env = getEnv();
auto buildVersion = env->FindClass ("android/os/Build$VERSION"); LocalRef<jclass> buildVersion { env->FindClass ("android/os/Build$VERSION") };
jassert (buildVersion != nullptr); jassert (buildVersion != nullptr);
auto sdkVersionField = env->GetStaticFieldID (buildVersion, "SDK_INT", "I"); auto sdkVersionField = env->GetStaticFieldID (buildVersion, "SDK_INT", "I");
@ -825,19 +826,17 @@ String audioManagerGetProperty (const String& property)
LocalRef<jobject> audioManager (env->CallObjectMethod (getAppContext().get(), AndroidContext.getSystemService, LocalRef<jobject> audioManager (env->CallObjectMethod (getAppContext().get(), AndroidContext.getSystemService,
javaString ("audio").get())); javaString ("audio").get()));
if (audioManager != nullptr) if (audioManager == nullptr)
{ return {};
LocalRef<jstring> jProperty (javaString (property));
auto methodID = env->GetMethodID (AndroidAudioManager, "getProperty", "(Ljava/lang/String;)Ljava/lang/String;"); auto methodID = env->GetMethodID (AndroidAudioManager, "getProperty", "(Ljava/lang/String;)Ljava/lang/String;");
if (methodID != nullptr) if (methodID == nullptr)
return juceString (LocalRef<jstring> ((jstring) env->CallObjectMethod (audioManager.get(), return {};
methodID,
javaString (property).get())));
}
return {}; return juceString (LocalRef<jstring> ((jstring) env->CallObjectMethod (audioManager.get(),
methodID,
javaString (property).get())));
} }
} }

View file

@ -63,7 +63,7 @@ namespace AndroidStatsHelpers
{ {
auto* env = getEnv(); auto* env = getEnv();
if (auto settings = (jclass) env->FindClass ("android/provider/Settings$Secure")) if (LocalRef<jclass> settings { env->FindClass ("android/provider/Settings$Secure") })
{ {
if (auto fId = env->GetStaticFieldID (settings, "ANDROID_ID", "Ljava/lang/String;")) if (auto fId = env->GetStaticFieldID (settings, "ANDROID_ID", "Ljava/lang/String;"))
{ {

View file

@ -84,7 +84,7 @@ extern "C" jint JNIEXPORT JNI_OnLoad (JavaVM* vm, void*)
auto* env = getEnv(); auto* env = getEnv();
// register the initialisation function // register the initialisation function
auto juceJavaClass = env->FindClass ("com/rmsl/juce/Java"); LocalRef<jclass> juceJavaClass { env->FindClass ("com/rmsl/juce/Java") };
if (juceJavaClass != nullptr) if (juceJavaClass != nullptr)
{ {
@ -195,7 +195,7 @@ private:
if (mainActivity == nullptr) if (mainActivity == nullptr)
{ {
LocalRef<jobject> appContext (getAppContext()); auto appContext = getAppContext();
auto mainActivityPath = getMainActivityClassPath(); auto mainActivityPath = getMainActivityClassPath();
if (mainActivityPath.isNotEmpty()) if (mainActivityPath.isNotEmpty())
@ -217,7 +217,7 @@ private:
if (mainActivityClassPath.isEmpty()) if (mainActivityClassPath.isEmpty())
{ {
LocalRef<jobject> appContext (getAppContext()); auto appContext = getAppContext();
if (appContext != nullptr) if (appContext != nullptr)
{ {

View file

@ -62,7 +62,7 @@ namespace Android
struct Handler struct Handler
{ {
Handler() : nativeHandler (LocalRef<jobject> (getEnv()->NewObject (AndroidHandler, AndroidHandler.constructor))) {} Handler() = default;
~Handler() { clearSingletonInstance(); } ~Handler() { clearSingletonInstance(); }
JUCE_DECLARE_SINGLETON_INLINE (Handler, false) JUCE_DECLARE_SINGLETON_INLINE (Handler, false)
@ -72,7 +72,7 @@ namespace Android
return (getEnv()->CallBooleanMethod (nativeHandler.get(), AndroidHandler.post, runnable) != 0); return (getEnv()->CallBooleanMethod (nativeHandler.get(), AndroidHandler.post, runnable) != 0);
} }
GlobalRef nativeHandler; GlobalRef nativeHandler { LocalRef<jobject> { getEnv()->NewObject (AndroidHandler, AndroidHandler.constructor) } };
}; };
} }
@ -81,10 +81,7 @@ struct AndroidMessageQueue final : private Android::Runnable
{ {
JUCE_DECLARE_SINGLETON_SINGLETHREADED_INLINE (AndroidMessageQueue, true) JUCE_DECLARE_SINGLETON_SINGLETHREADED_INLINE (AndroidMessageQueue, true)
AndroidMessageQueue() AndroidMessageQueue() = default;
: self (CreateJavaInterface (this, "java/lang/Runnable"))
{
}
~AndroidMessageQueue() override ~AndroidMessageQueue() override
{ {
@ -115,11 +112,11 @@ private:
} }
} }
// the this pointer to this class in Java land
GlobalRef self;
ReferenceCountedArray<MessageManager::MessageBase, CriticalSection> queue; ReferenceCountedArray<MessageManager::MessageBase, CriticalSection> queue;
Android::Handler handler; Android::Handler handler;
// the this pointer to this class in Java land
GlobalRef self { CreateJavaInterface (this, "java/lang/Runnable") };
}; };
//============================================================================== //==============================================================================
@ -149,7 +146,7 @@ void MessageManager::stopDispatchLoop()
void messageCallback() override void messageCallback() override
{ {
auto* env = getEnv(); auto* env = getEnv();
LocalRef<jobject> activity (getCurrentActivity()); auto activity = getCurrentActivity();
if (activity != nullptr) if (activity != nullptr)
{ {
@ -180,7 +177,9 @@ void MessageManager::stopDispatchLoop()
class JuceAppLifecycle final : public ActivityLifecycleCallbacks class JuceAppLifecycle final : public ActivityLifecycleCallbacks
{ {
public: public:
JuceAppLifecycle (juce::JUCEApplicationBase* (*initSymbolAddr)()) using CreateApp = juce::JUCEApplicationBase* (*)();
explicit JuceAppLifecycle (CreateApp initSymbolAddr)
: createApplicationSymbol (initSymbolAddr) : createApplicationSymbol (initSymbolAddr)
{ {
} }
@ -200,8 +199,8 @@ public:
JUCEApplicationBase::appWillTerminateByForce(); JUCEApplicationBase::appWillTerminateByForce();
JNIClassBase::releaseAllClasses (env); JNIClassBase::releaseAllClasses (env);
jclass systemClass = (jclass) env->FindClass ("java/lang/System"); LocalRef<jclass> systemClass { env->FindClass ("java/lang/System") };
jmethodID exitMethod = env->GetStaticMethodID (systemClass, "exit", "(I)V"); jmethodID exitMethod = env->GetStaticMethodID (systemClass.get(), "exit", "(I)V");
env->CallStaticVoidMethod (systemClass, exitMethod, 0); env->CallStaticVoidMethod (systemClass, exitMethod, 0);
} }
} }
@ -225,7 +224,7 @@ public:
app->resumed(); app->resumed();
} }
static JuceAppLifecycle& getInstance (juce::JUCEApplicationBase* (*initSymbolAddr)()) static JuceAppLifecycle& getInstance (CreateApp initSymbolAddr)
{ {
static JuceAppLifecycle juceAppLifecycle (initSymbolAddr); static JuceAppLifecycle juceAppLifecycle (initSymbolAddr);
return juceAppLifecycle; return juceAppLifecycle;
@ -267,7 +266,7 @@ private:
std::optional<ScopedJuceInitialiser_GUI> initialiser; std::optional<ScopedJuceInitialiser_GUI> initialiser;
GlobalRef myself; GlobalRef myself;
juce::JUCEApplicationBase* (*createApplicationSymbol)(); CreateApp createApplicationSymbol{};
bool hasBeenInitialised = false; bool hasBeenInitialised = false;
ActivityLifecycleCallbackForwarder forwarder { GlobalRef { getAppContext() }, this }; ActivityLifecycleCallbackForwarder forwarder { GlobalRef { getAppContext() }, this };
}; };
@ -279,8 +278,8 @@ void juce_juceEventsAndroidStartApp();
void juce_juceEventsAndroidStartApp() void juce_juceEventsAndroidStartApp()
{ {
auto dllPath = juce_getExecutableFile().getFullPathName(); auto dllPath = juce_getExecutableFile().getFullPathName();
auto addr = reinterpret_cast<juce::JUCEApplicationBase*(*)()> (DynamicLibrary (dllPath) auto addr = reinterpret_cast<juce::JUCEApplicationBase* (*)()> (DynamicLibrary (dllPath)
.getFunction ("juce_CreateApplication")); .getFunction ("juce_CreateApplication"));
if (addr != nullptr) if (addr != nullptr)
JuceAppLifecycle::getInstance (addr); JuceAppLifecycle::getInstance (addr);

View file

@ -375,8 +375,8 @@ private:
const auto context = getAppContext(); const auto context = getAppContext();
auto* klass = env->FindClass ("com/rmsl/juce/Receiver"); LocalRef<jclass> klass { env->FindClass ("com/rmsl/juce/Receiver") };
const LocalRef<jobject> replyIntent (env->NewObject (AndroidIntent, AndroidIntent.constructorWithContextAndClass, context.get(), klass)); const LocalRef<jobject> replyIntent (env->NewObject (AndroidIntent, AndroidIntent.constructorWithContextAndClass, context.get(), klass.get()));
getEnv()->CallObjectMethod (replyIntent, AndroidIntent.putExtraInt, javaString ("com.rmsl.juce.JUCE_REQUEST_CODE").get(), request); getEnv()->CallObjectMethod (replyIntent, AndroidIntent.putExtraInt, javaString ("com.rmsl.juce.JUCE_REQUEST_CODE").get(), request);
const auto flags = FLAG_UPDATE_CURRENT | FLAG_IMMUTABLE; const auto flags = FLAG_UPDATE_CURRENT | FLAG_IMMUTABLE;

View file

@ -1329,7 +1329,7 @@ public:
{ {
// we don't know if the user is holding on to a local ref to this, so // we don't know if the user is holding on to a local ref to this, so
// explicitly create a new one // explicitly create a new one
auto nativeView = LocalRef<jobject> (env->NewLocalRef (static_cast<jobject> (nativeViewHandle))); LocalRef<jobject> nativeView { env->NewLocalRef (static_cast<jobject> (nativeViewHandle)) };
if (env->IsInstanceOf (nativeView.get(), AndroidActivity)) if (env->IsInstanceOf (nativeView.get(), AndroidActivity))
{ {
@ -1838,7 +1838,7 @@ public:
if (! handled) if (! handled)
{ {
LocalRef<jobject> activity (getCurrentActivity()); auto activity = getCurrentActivity();
if (activity != nullptr) if (activity != nullptr)
{ {
@ -2003,7 +2003,7 @@ public:
} }
//============================================================================== //==============================================================================
static void handleDoFrameCallback (JNIEnv*, AndroidComponentPeer& t, [[maybe_unused]] int64 frameTimeNanos) static void handleDoFrameCallback (JNIEnv*, AndroidComponentPeer& t, [[maybe_unused]] jlong frameTimeNanos)
{ {
const auto timestampSec = (double) frameTimeNanos / (double) 1'000'000'000; const auto timestampSec = (double) frameTimeNanos / (double) 1'000'000'000;
t.callVBlankListeners (timestampSec); t.callVBlankListeners (timestampSec);
@ -2631,13 +2631,13 @@ Desktop::DisplayOrientation Desktop::getCurrentOrientation() const
}; };
JNIEnv* env = getEnv(); JNIEnv* env = getEnv();
LocalRef<jstring> windowServiceString (javaString ("window")); const auto windowServiceString = javaString ("window");
LocalRef<jobject> windowManager = LocalRef<jobject> (env->CallObjectMethod (getAppContext().get(), AndroidContext.getSystemService, windowServiceString.get())); LocalRef<jobject> windowManager { env->CallObjectMethod (getAppContext().get(), AndroidContext.getSystemService, windowServiceString.get()) };
if (windowManager.get() != nullptr) if (windowManager.get() != nullptr)
{ {
LocalRef<jobject> display = LocalRef<jobject> (env->CallObjectMethod (windowManager, AndroidWindowManager.getDefaultDisplay)); LocalRef<jobject> display { env->CallObjectMethod (windowManager, AndroidWindowManager.getDefaultDisplay) };
if (display.get() != nullptr) if (display.get() != nullptr)
{ {
@ -2688,7 +2688,7 @@ bool KeyPress::isKeyCurrentlyDown (int /*keyCode*/)
JUCE_API void JUCE_CALLTYPE Process::hide() JUCE_API void JUCE_CALLTYPE Process::hide()
{ {
auto* env = getEnv(); auto* env = getEnv();
LocalRef<jobject> currentActivity (getCurrentActivity().get()); auto currentActivity = getCurrentActivity();
if (env->CallBooleanMethod (currentActivity.get(), AndroidActivity.moveTaskToBack, true) == 0) if (env->CallBooleanMethod (currentActivity.get(), AndroidActivity.moveTaskToBack, true) == 0)
{ {
@ -2751,7 +2751,7 @@ public:
if (methodName == "onCancel" || methodName == "onClick") if (methodName == "onCancel" || methodName == "onClick")
{ {
auto* dialog = env->GetObjectArrayElement (args, 0); LocalRef<jobject> dialog { env->GetObjectArrayElement (args, 0) };
env->CallVoidMethod (dialog, AndroidDialogInterface.dismiss); env->CallVoidMethod (dialog, AndroidDialogInterface.dismiss);
NullCheckedInvocation::invoke (callback); NullCheckedInvocation::invoke (callback);
@ -2853,8 +2853,7 @@ void Displays::findDisplays (float masterScale)
{ {
auto* env = getEnv(); auto* env = getEnv();
LocalRef<jstring> windowServiceString (javaString ("window")); const auto windowServiceString = javaString ("window");
LocalRef<jobject> windowManager (env->CallObjectMethod (getAppContext(), AndroidContext.getSystemService, windowServiceString.get())); LocalRef<jobject> windowManager (env->CallObjectMethod (getAppContext(), AndroidContext.getSystemService, windowServiceString.get()));
LocalRef<jobject> display (env->CallObjectMethod (windowManager, AndroidWindowManager.getDefaultDisplay)); LocalRef<jobject> display (env->CallObjectMethod (windowManager, AndroidWindowManager.getDefaultDisplay));

View file

@ -337,7 +337,7 @@ struct PushNotifications::Impl
void notifyListenersAboutLocalNotification (const LocalRef<jobject>& intent) void notifyListenersAboutLocalNotification (const LocalRef<jobject>& intent)
{ {
auto* env = getEnv(); auto* env = getEnv();
LocalRef<jobject> context (getMainActivity()); auto context = getMainActivity();
auto bundle = LocalRef<jobject> (env->CallObjectMethod (intent, AndroidIntent.getExtras)); auto bundle = LocalRef<jobject> (env->CallObjectMethod (intent, AndroidIntent.getExtras));
@ -575,7 +575,7 @@ struct PushNotifications::Impl
static LocalRef<jobject> getNotificationManager() static LocalRef<jobject> getNotificationManager()
{ {
auto* env = getEnv(); auto* env = getEnv();
LocalRef<jobject> context (getMainActivity()); auto context = getMainActivity();
return LocalRef<jobject> (env->CallObjectMethod (context.get(), return LocalRef<jobject> (env->CallObjectMethod (context.get(),
AndroidContext.getSystemService, AndroidContext.getSystemService,
@ -601,9 +601,9 @@ struct PushNotifications::Impl
static LocalRef<jobject> createNotificationBuilder (const Notification& n) static LocalRef<jobject> createNotificationBuilder (const Notification& n)
{ {
auto* env = getEnv(); auto* env = getEnv();
LocalRef<jobject> context (getMainActivity()); auto context = getMainActivity();
jclass builderClass = env->FindClass ("android/app/Notification$Builder"); LocalRef<jclass> builderClass { env->FindClass ("android/app/Notification$Builder") };
jassert (builderClass != nullptr); jassert (builderClass != nullptr);
if (builderClass == nullptr) if (builderClass == nullptr)
@ -621,7 +621,7 @@ struct PushNotifications::Impl
jassert (builderConstructor != nullptr); jassert (builderConstructor != nullptr);
if (builderConstructor == nullptr) if (builderConstructor == nullptr)
return LocalRef<jobject> (nullptr); return LocalRef<jobject>();
if (apiAtLeast26) if (apiAtLeast26)
return LocalRef<jobject> (env->NewObject (builderClass, builderConstructor, return LocalRef<jobject> (env->NewObject (builderClass, builderConstructor,
@ -638,7 +638,7 @@ struct PushNotifications::Impl
return notificationBuilder; return notificationBuilder;
auto* env = getEnv(); auto* env = getEnv();
LocalRef<jobject> context (getMainActivity()); auto context = getMainActivity();
auto activityClass = LocalRef<jobject> (env->CallObjectMethod (context.get(), JavaObject.getClass)); auto activityClass = LocalRef<jobject> (env->CallObjectMethod (context.get(), JavaObject.getClass));
auto notifyIntent = LocalRef<jobject> (env->NewObject (AndroidIntent, AndroidIntent.constructorWithContextAndClass, context.get(), activityClass.get())); auto notifyIntent = LocalRef<jobject> (env->NewObject (AndroidIntent, AndroidIntent.constructorWithContextAndClass, context.get(), activityClass.get()));
@ -875,7 +875,7 @@ struct PushNotifications::Impl
return notificationBuilder; return notificationBuilder;
auto* env = getEnv(); auto* env = getEnv();
LocalRef<jobject> context (getMainActivity()); auto context = getMainActivity();
auto activityClass = LocalRef<jobject> (env->CallObjectMethod (context.get(), JavaObject.getClass)); auto activityClass = LocalRef<jobject> (env->CallObjectMethod (context.get(), JavaObject.getClass));
auto deleteIntent = LocalRef<jobject> (env->NewObject (AndroidIntent, AndroidIntent.constructorWithContextAndClass, context.get(), activityClass.get())); auto deleteIntent = LocalRef<jobject> (env->NewObject (AndroidIntent, AndroidIntent.constructorWithContextAndClass, context.get(), activityClass.get()));
@ -905,7 +905,7 @@ struct PushNotifications::Impl
return notificationBuilder; return notificationBuilder;
auto* env = getEnv(); auto* env = getEnv();
LocalRef<jobject> context (getMainActivity()); auto context = getMainActivity();
for (const auto [actionIndex, action] : enumerate (n.actions)) for (const auto [actionIndex, action] : enumerate (n.actions))
{ {
@ -998,7 +998,7 @@ struct PushNotifications::Impl
static LocalRef<jobject> juceUrlToAndroidUri (const URL& url) static LocalRef<jobject> juceUrlToAndroidUri (const URL& url)
{ {
auto* env = getEnv(); auto* env = getEnv();
LocalRef<jobject> context (getMainActivity()); auto context = getMainActivity();
auto packageNameString = LocalRef<jstring> ((jstring) (env->CallObjectMethod (context.get(), AndroidContext.getPackageName))); auto packageNameString = LocalRef<jstring> ((jstring) (env->CallObjectMethod (context.get(), AndroidContext.getPackageName)));
@ -1462,7 +1462,7 @@ struct PushNotifications::Impl
static bool intentActionContainsAnyOf (jobject intent, const StringArray& strings, bool includePackageName) static bool intentActionContainsAnyOf (jobject intent, const StringArray& strings, bool includePackageName)
{ {
auto* env = getEnv(); auto* env = getEnv();
LocalRef<jobject> context (getMainActivity()); auto context = getMainActivity();
String packageName = includePackageName ? juceString ((jstring) env->CallObjectMethod (context.get(), String packageName = includePackageName ? juceString ((jstring) env->CallObjectMethod (context.get(),
AndroidContext.getPackageName)) AndroidContext.getPackageName))

View file

@ -1484,7 +1484,7 @@ private:
auto* env = getEnv(); auto* env = getEnv();
auto requestBuilderClass = LocalRef<jclass> (env->FindClass ("android/media/AudioFocusRequest$Builder")); LocalRef<jclass> requestBuilderClass { env->FindClass ("android/media/AudioFocusRequest$Builder") };
static jmethodID constructor = env->GetMethodID (requestBuilderClass, "<init>", "(I)V"); static jmethodID constructor = env->GetMethodID (requestBuilderClass, "<init>", "(I)V");
static jmethodID buildMethod = env->GetMethodID (requestBuilderClass, "build", "()Landroid/media/AudioFocusRequest;"); static jmethodID buildMethod = env->GetMethodID (requestBuilderClass, "build", "()Landroid/media/AudioFocusRequest;");