[android] Refactor cpp-java ui thread forwarding
Signed-off-by: Andrew Shkrob <andrew.shkrob.social@yandex.by>
This commit is contained in:
parent
aaad6ecb44
commit
3ec607313b
9 changed files with 60 additions and 51 deletions
|
@ -66,6 +66,7 @@ set(SRC
|
|||
app/organicmaps/util/LogsManager.cpp
|
||||
app/organicmaps/util/NetworkPolicy.cpp
|
||||
app/organicmaps/util/StringUtils.cpp
|
||||
app/organicmaps/util/UiThread.cpp
|
||||
app/organicmaps/vulkan/android_vulkan_context_factory.cpp
|
||||
)
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#include "app/organicmaps/Framework.hpp"
|
||||
|
||||
#include "app/organicmaps/platform/GuiThread.hpp"
|
||||
#include "app/organicmaps/platform/AndroidPlatform.hpp"
|
||||
|
||||
#include "app/organicmaps/core/jni_helper.hpp"
|
||||
|
@ -14,16 +13,16 @@ extern "C"
|
|||
android::Platform::Instance().SetSettingsDir(jni::ToNativeString(env, settingsPath));
|
||||
}
|
||||
|
||||
// void nativeInitPlatform(String apkPath, String storagePath, String privatePath, String tmpPath,
|
||||
// static void nativeInitPlatform(Context context, String apkPath, String storagePath, String privatePath, String tmpPath,
|
||||
// String flavorName, String buildType, boolean isTablet);
|
||||
JNIEXPORT void JNICALL
|
||||
Java_app_organicmaps_MwmApplication_nativeInitPlatform(JNIEnv * env, jobject thiz,
|
||||
jstring apkPath, jstring writablePath,
|
||||
jstring privatePath, jstring tmpPath,
|
||||
jstring flavorName, jstring buildType,
|
||||
jboolean isTablet)
|
||||
Java_app_organicmaps_MwmApplication_nativeInitPlatform(JNIEnv * env, jclass clazz, jobject context,
|
||||
jstring apkPath, jstring writablePath,
|
||||
jstring privatePath, jstring tmpPath,
|
||||
jstring flavorName, jstring buildType,
|
||||
jboolean isTablet)
|
||||
{
|
||||
android::Platform::Instance().Initialize(env, thiz, apkPath, writablePath, privatePath, tmpPath,
|
||||
android::Platform::Instance().Initialize(env, context, apkPath, writablePath, privatePath, tmpPath,
|
||||
flavorName, buildType, isTablet);
|
||||
}
|
||||
|
||||
|
@ -42,13 +41,6 @@ extern "C"
|
|||
}
|
||||
}
|
||||
|
||||
// static void nativeProcessTask(long taskPointer);
|
||||
JNIEXPORT void JNICALL
|
||||
Java_app_organicmaps_MwmApplication_nativeProcessTask(JNIEnv * env, jclass clazz, jlong taskPointer)
|
||||
{
|
||||
android::GuiThread::ProcessTask(taskPointer);
|
||||
}
|
||||
|
||||
// static void nativeAddLocalization(String name, String value);
|
||||
JNIEXPORT void JNICALL
|
||||
Java_app_organicmaps_MwmApplication_nativeAddLocalization(JNIEnv * env, jclass clazz, jstring name, jstring value)
|
||||
|
|
|
@ -130,11 +130,18 @@ platform::NetworkPolicy GetCurrentNetworkPolicy()
|
|||
|
||||
namespace android
|
||||
{
|
||||
void Platform::Initialize(JNIEnv * env, jobject functorProcessObject, jstring apkPath,
|
||||
Platform::~Platform()
|
||||
{
|
||||
JNIEnv *env = jni::GetEnv();
|
||||
env->DeleteGlobalRef(m_context);
|
||||
}
|
||||
|
||||
void Platform::Initialize(JNIEnv * env, jobject context, jstring apkPath,
|
||||
jstring writablePath, jstring privatePath, jstring tmpPath,
|
||||
jstring flavorName, jstring buildType, bool isTablet)
|
||||
{
|
||||
m_guiThread = std::make_unique<GuiThread>(functorProcessObject);
|
||||
m_context = env->NewGlobalRef(context);
|
||||
m_guiThread = std::make_unique<GuiThread>();
|
||||
|
||||
std::string const flavor = jni::ToNativeString(env, flavorName);
|
||||
std::string const build = jni::ToNativeString(env, buildType);
|
||||
|
@ -182,7 +189,7 @@ Platform & Platform::Instance()
|
|||
|
||||
jobject Platform::GetContext() const
|
||||
{
|
||||
return static_cast<GuiThread const *>(m_guiThread.get())->GetObject();
|
||||
return m_context;
|
||||
}
|
||||
|
||||
void Platform::AndroidSecureStorage::Init(JNIEnv * env)
|
||||
|
|
|
@ -17,6 +17,8 @@ namespace android
|
|||
class Platform : public ::Platform
|
||||
{
|
||||
public:
|
||||
~Platform() override;
|
||||
|
||||
void Initialize(JNIEnv * env, jobject functorProcessObject, jstring apkPath, jstring writablePath,
|
||||
jstring privatePath, jstring tmpPath, jstring flavorName,
|
||||
jstring buildType, bool isTablet);
|
||||
|
@ -49,5 +51,6 @@ public:
|
|||
|
||||
private:
|
||||
AndroidSecureStorage m_secureStorage;
|
||||
jobject m_context;
|
||||
};
|
||||
} // namespace android
|
||||
|
|
|
@ -6,21 +6,21 @@
|
|||
|
||||
namespace android
|
||||
{
|
||||
GuiThread::GuiThread(jobject processObject)
|
||||
GuiThread::GuiThread()
|
||||
{
|
||||
JNIEnv * env = jni::GetEnv();
|
||||
|
||||
m_object = env->NewGlobalRef(processObject);
|
||||
ASSERT(m_object, ());
|
||||
m_class = GetGlobalClassRef(env, "app/organicmaps/util/concurrency/UiThread");
|
||||
ASSERT(m_class, ());
|
||||
|
||||
m_method = env->GetMethodID(env->GetObjectClass(m_object), "forwardToMainThread", "(J)V");
|
||||
m_method = env->GetStaticMethodID(m_class, "forwardToMainThread", "(J)V");
|
||||
ASSERT(m_method, ());
|
||||
}
|
||||
|
||||
GuiThread::~GuiThread()
|
||||
{
|
||||
JNIEnv * env = jni::GetEnv();
|
||||
env->DeleteGlobalRef(m_object);
|
||||
env->DeleteGlobalRef(m_class);
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -34,7 +34,7 @@ base::TaskLoop::PushResult GuiThread::Push(Task && task)
|
|||
{
|
||||
// Pointer will be deleted in ProcessTask.
|
||||
auto t = new Task(std::move(task));
|
||||
jni::GetEnv()->CallVoidMethod(m_object, m_method, reinterpret_cast<jlong>(t));
|
||||
jni::GetEnv()->CallStaticVoidMethod(m_class, m_method, reinterpret_cast<jlong>(t));
|
||||
return {true, kNoId};
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@ base::TaskLoop::PushResult GuiThread::Push(Task const & task)
|
|||
{
|
||||
// Pointer will be deleted in ProcessTask.
|
||||
auto t = new Task(task);
|
||||
jni::GetEnv()->CallVoidMethod(m_object, m_method, reinterpret_cast<jlong>(t));
|
||||
jni::GetEnv()->CallStaticVoidMethod(m_class, m_method, reinterpret_cast<jlong>(t));
|
||||
return {true, kNoId};
|
||||
}
|
||||
} // namespace android
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace android
|
|||
class GuiThread : public base::TaskLoop
|
||||
{
|
||||
public:
|
||||
explicit GuiThread(jobject processObject);
|
||||
GuiThread();
|
||||
~GuiThread() override;
|
||||
|
||||
static void ProcessTask(jlong task);
|
||||
|
@ -18,10 +18,8 @@ public:
|
|||
PushResult Push(Task && task) override;
|
||||
PushResult Push(Task const & task) override;
|
||||
|
||||
jobject GetObject() const { return m_object; }
|
||||
|
||||
private:
|
||||
jobject m_object = nullptr;
|
||||
jclass m_class = nullptr;
|
||||
jmethodID m_method = nullptr;
|
||||
};
|
||||
} // namespace android
|
||||
|
|
12
android/app/src/main/cpp/app/organicmaps/util/UiThread.cpp
Normal file
12
android/app/src/main/cpp/app/organicmaps/util/UiThread.cpp
Normal file
|
@ -0,0 +1,12 @@
|
|||
#include "app/organicmaps/core/jni_helper.hpp"
|
||||
#include "app/organicmaps/platform/GuiThread.hpp"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
// static void nativeProcessTask(long taskPointer);
|
||||
JNIEXPORT void JNICALL
|
||||
Java_app_organicmaps_util_concurrency_UiThread_nativeProcessTask(JNIEnv * env, jclass clazz, jlong taskPointer)
|
||||
{
|
||||
android::GuiThread::ProcessTask(taskPointer);
|
||||
}
|
||||
}
|
|
@ -7,10 +7,7 @@ import android.app.Application;
|
|||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.UiThread;
|
||||
|
@ -81,8 +78,6 @@ public class MwmApplication extends Application implements Application.ActivityL
|
|||
private volatile boolean mFrameworkInitialized;
|
||||
private volatile boolean mPlatformInitialized;
|
||||
|
||||
private Handler mMainLoopHandler;
|
||||
private final Object mMainQueueToken = new Object();
|
||||
@NonNull
|
||||
private final MapManager.StorageCallback mStorageCallbacks = new StorageCallbackImpl();
|
||||
|
||||
|
@ -157,7 +152,6 @@ public class MwmApplication extends Application implements Application.ActivityL
|
|||
|
||||
Config.init(this);
|
||||
|
||||
mMainLoopHandler = new Handler(getMainLooper());
|
||||
ConnectionState.INSTANCE.initialize(this);
|
||||
|
||||
DownloaderNotifier.createNotificationChannel(this);
|
||||
|
@ -204,7 +198,8 @@ public class MwmApplication extends Application implements Application.ActivityL
|
|||
// external storage is damaged or not available (read-only).
|
||||
createPlatformDirectories(writablePath, privatePath, tempPath);
|
||||
|
||||
nativeInitPlatform(apkPath,
|
||||
nativeInitPlatform(getApplicationContext(),
|
||||
apkPath,
|
||||
writablePath,
|
||||
privatePath,
|
||||
tempPath,
|
||||
|
@ -275,22 +270,11 @@ public class MwmApplication extends Application implements Application.ActivityL
|
|||
System.loadLibrary("organicmaps");
|
||||
}
|
||||
|
||||
// Called from JNI.
|
||||
@Keep
|
||||
@SuppressWarnings("unused")
|
||||
private void forwardToMainThread(final long taskPointer)
|
||||
{
|
||||
Message m = Message.obtain(mMainLoopHandler, () -> nativeProcessTask(taskPointer));
|
||||
m.obj = mMainQueueToken;
|
||||
mMainLoopHandler.sendMessage(m);
|
||||
}
|
||||
|
||||
private static native void nativeSetSettingsDir(String settingsPath);
|
||||
private native void nativeInitPlatform(String apkPath, String writablePath, String privatePath,
|
||||
String tmpPath, String flavorName, String buildType,
|
||||
boolean isTablet);
|
||||
private static native void nativeInitPlatform(Context context, String apkPath, String writablePath,
|
||||
String privatePath, String tmpPath, String flavorName,
|
||||
String buildType, boolean isTablet);
|
||||
private static native void nativeInitFramework(@NonNull Runnable onComplete);
|
||||
private static native void nativeProcessTask(long taskPointer);
|
||||
private static native void nativeAddLocalization(String name, String value);
|
||||
private static native void nativeOnTransit(boolean foreground);
|
||||
|
||||
|
|
|
@ -3,6 +3,8 @@ package app.organicmaps.util.concurrency;
|
|||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
|
||||
public class UiThread
|
||||
{
|
||||
private static final Handler sUiHandler = new Handler(Looper.getMainLooper());
|
||||
|
@ -38,7 +40,7 @@ public class UiThread
|
|||
/**
|
||||
* Executes something on UI thread after a given delayMillis.
|
||||
*
|
||||
* @param task the code that must be executed on UI thread after given delayMillis.
|
||||
* @param task the code that must be executed on UI thread after given delayMillis.
|
||||
* @param delayMillis The delayMillis until the code will be executed.
|
||||
*/
|
||||
public static void runLater(Runnable task, long delayMillis)
|
||||
|
@ -56,4 +58,14 @@ public class UiThread
|
|||
{
|
||||
sUiHandler.removeCallbacks(task);
|
||||
}
|
||||
|
||||
// Called from JNI.
|
||||
@Keep
|
||||
@SuppressWarnings("unused")
|
||||
private static void forwardToMainThread(final long taskPointer)
|
||||
{
|
||||
runLater(() -> nativeProcessTask(taskPointer), 0);
|
||||
}
|
||||
|
||||
private static native void nativeProcessTask(long taskPointer);
|
||||
}
|
||||
|
|
Reference in a new issue