From 2f049c0edd5cd10ae2e605289ebaf8cd6609e1b2 Mon Sep 17 00:00:00 2001 From: bofeng Date: Fri, 13 Dec 2024 16:43:04 +0800 Subject: [PATCH] Fix the crash issue on the Android platform caused by an invalid context. --- .../platform/android/AndroidPlatform.cpp | 2 +- .../cocos/platform/android/adpf_manager.cpp | 4 ++-- .../java/src/com/cocos/lib/CocosActivity.java | 7 ++++--- .../src/com/cocos/lib/CocosDownloader.java | 9 ++++++++- .../src/com/cocos/lib/CocosWebViewHelper.java | 2 +- .../platform/android/jni/JniCocosEntry.cpp | 5 +++-- native/cocos/platform/java/jni/JniHelper.cpp | 19 ++++++++++++++++--- native/cocos/platform/java/jni/JniHelper.h | 2 ++ 8 files changed, 37 insertions(+), 13 deletions(-) diff --git a/native/cocos/platform/android/AndroidPlatform.cpp b/native/cocos/platform/android/AndroidPlatform.cpp index 335c90d189d..8a8f192e750 100644 --- a/native/cocos/platform/android/AndroidPlatform.cpp +++ b/native/cocos/platform/android/AndroidPlatform.cpp @@ -158,7 +158,7 @@ class GameInputProxy { } ABORT_IF(_jniEnv != nullptr) - Paddleboat_init(_jniEnv, platform->_app->activity->javaGameActivity); + Paddleboat_init(_jniEnv, cc::JniHelper::getContext()); Paddleboat_setControllerStatusCallback(gameControllerStatusCallback, this); // This is needed to allow controller events through to us. // By default, only touch-screen events are passed through, to match the diff --git a/native/cocos/platform/android/adpf_manager.cpp b/native/cocos/platform/android/adpf_manager.cpp index ff9e186944d..9dad2384412 100644 --- a/native/cocos/platform/android/adpf_manager.cpp +++ b/native/cocos/platform/android/adpf_manager.cpp @@ -104,7 +104,7 @@ bool ADPFManager::initializePowerManager() { #endif JNIEnv *env = cc::JniHelper::getEnv(); - auto *javaGameActivity = cc::JniHelper::getActivity(); + auto *javaGameActivity = cc::JniHelper::getContext(); // Retrieve class information jclass context = env->FindClass("android/content/Context"); @@ -189,7 +189,7 @@ bool ADPFManager::initializePerformanceHintManager() { return true; #else JNIEnv *env = cc::JniHelper::getEnv(); - auto *javaGameActivity = cc::JniHelper::getActivity(); + auto *javaGameActivity = cc::JniHelper::getContext(); // Retrieve class information jclass context = env->FindClass("android/content/Context"); diff --git a/native/cocos/platform/android/java/src/com/cocos/lib/CocosActivity.java b/native/cocos/platform/android/java/src/com/cocos/lib/CocosActivity.java index 55e93a24ba9..7942bd1184a 100644 --- a/native/cocos/platform/android/java/src/com/cocos/lib/CocosActivity.java +++ b/native/cocos/platform/android/java/src/com/cocos/lib/CocosActivity.java @@ -24,6 +24,7 @@ package com.cocos.lib; +import android.content.Context; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; @@ -58,19 +59,19 @@ public class CocosActivity extends GameActivity { - private native void onCreateNative(); + private native void onCreateNative(Context applicationContext); @Override protected void onCreate(Bundle savedInstanceState) { onLoadNativeLibraries(); - onCreateNative(); + onCreateNative(this.getApplicationContext()); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); getWindow().requestFeature(Window.FEATURE_NO_TITLE); super.onCreate(savedInstanceState); // GlobalObject.init should be initialized at first. - GlobalObject.init(this, this); + GlobalObject.init(this.getApplicationContext(), this); CocosHelper.registerBatteryLevelReceiver(this); CocosHelper.init(); diff --git a/native/cocos/platform/android/java/src/com/cocos/lib/CocosDownloader.java b/native/cocos/platform/android/java/src/com/cocos/lib/CocosDownloader.java index c5f98b8b64a..da05c5c3f49 100644 --- a/native/cocos/platform/android/java/src/com/cocos/lib/CocosDownloader.java +++ b/native/cocos/platform/android/java/src/com/cocos/lib/CocosDownloader.java @@ -180,7 +180,11 @@ public void run() { host = domain.startsWith("www.") ? domain.substring(4) : domain; if (fileLen > 0) { - SharedPreferences sharedPreferences = GlobalObject.getContext().getSharedPreferences("breakpointDownloadSupport", Context.MODE_PRIVATE); + Context ctx = GlobalObject.getContext(); + if (ctx == null) { + return; + } + SharedPreferences sharedPreferences = ctx.getSharedPreferences("breakpointDownloadSupport", Context.MODE_PRIVATE); if (sharedPreferences.contains(host) && sharedPreferences.getBoolean(host, false)) { downloadStart = fileLen; } else { @@ -246,6 +250,9 @@ public void onResponse(Call call, Response response) throws IOException { // save breakpointDownloadSupport Data to SharedPreferences storage Context context = GlobalObject.getContext(); + if (context == null) { + return; + } SharedPreferences sharedPreferences = context.getSharedPreferences("breakpointDownloadSupport", Context.MODE_PRIVATE); SharedPreferences.Editor editor = sharedPreferences.edit(); long total = response.body().contentLength() + downloadStart; diff --git a/native/cocos/platform/android/java/src/com/cocos/lib/CocosWebViewHelper.java b/native/cocos/platform/android/java/src/com/cocos/lib/CocosWebViewHelper.java index adf17aa99c0..90bcc08b23a 100755 --- a/native/cocos/platform/android/java/src/com/cocos/lib/CocosWebViewHelper.java +++ b/native/cocos/platform/android/java/src/com/cocos/lib/CocosWebViewHelper.java @@ -80,7 +80,7 @@ public static int createWebView() { GlobalObject.runOnUiThread(new Runnable() { @Override public void run() { - CocosWebView webView = new CocosWebView(GlobalObject.getContext(), index); + CocosWebView webView = new CocosWebView(GlobalObject.getActivity(), index); FrameLayout.LayoutParams lParams = new FrameLayout.LayoutParams( FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT); diff --git a/native/cocos/platform/android/jni/JniCocosEntry.cpp b/native/cocos/platform/android/jni/JniCocosEntry.cpp index 9334f01c263..5c2566d7cd4 100644 --- a/native/cocos/platform/android/jni/JniCocosEntry.cpp +++ b/native/cocos/platform/android/jni/JniCocosEntry.cpp @@ -39,7 +39,8 @@ void android_main(struct android_app *app) { } //NOLINTNEXTLINE -JNIEXPORT void JNICALL Java_com_cocos_lib_CocosActivity_onCreateNative(JNIEnv *env, jobject activity) { - cc::JniHelper::init(env, activity); +JNIEXPORT void JNICALL Java_com_cocos_lib_CocosActivity_onCreateNative(JNIEnv *env, jobject activity, jobject context) { + cc::JniHelper::init(env, context); + cc::JniHelper::setActivity(activity); } } diff --git a/native/cocos/platform/java/jni/JniHelper.cpp b/native/cocos/platform/java/jni/JniHelper.cpp index 8e7eff242a2..339c591282e 100644 --- a/native/cocos/platform/java/jni/JniHelper.cpp +++ b/native/cocos/platform/java/jni/JniHelper.cpp @@ -120,6 +120,7 @@ jmethodID JniHelper::loadclassMethodMethodId = nullptr; jobject JniHelper::classloader = nullptr; std::function JniHelper::classloaderCallback = nullptr; jobject JniHelper::sContext = nullptr; +jobject JniHelper::sActivity = nullptr; JavaVM *JniHelper::sJavaVM = nullptr; JavaVM *JniHelper::getJavaVM() { @@ -139,9 +140,13 @@ void JniHelper::init(JNIEnv *env, jobject context) { void JniHelper::onDestroy() { if (JniHelper::sJavaVM) { - if (JniHelper::sContext) { - cc::JniHelper::getEnv()->DeleteGlobalRef(JniHelper::sContext); - JniHelper::sContext = nullptr; + if (sContext) { + cc::JniHelper::getEnv()->DeleteGlobalRef(sContext); + sContext = nullptr; + } + if (sActivity) { + cc::JniHelper::getEnv()->DeleteGlobalRef(sActivity); + sActivity = nullptr; } LOGD("JniHelper::onDestroy"); } @@ -202,6 +207,14 @@ jobject JniHelper::getActivity() { return sContext; } +void JniHelper::setActivity(jobject activity) { + if (sActivity) { + cc::JniHelper::getEnv()->DeleteGlobalRef(sActivity); + sActivity = nullptr; + } + sActivity = cc::JniHelper::getEnv()->NewGlobalRef(activity); +} + #if CC_PLATFORM == CC_PLATFORM_OHOS bool JniHelper::setClassLoaderFrom(jobject contextInstance) { if (!JniHelper::classloader) { diff --git a/native/cocos/platform/java/jni/JniHelper.h b/native/cocos/platform/java/jni/JniHelper.h index e69c5f04bfe..06ed926cbf2 100644 --- a/native/cocos/platform/java/jni/JniHelper.h +++ b/native/cocos/platform/java/jni/JniHelper.h @@ -74,6 +74,7 @@ class CC_DLL JniHelper { static JavaVM *getJavaVM(); static JNIEnv *getEnv(); static jobject getActivity(); + static void setActivity(jobject activity); static jobject getContext(); static void init(JNIEnv *env, jobject context); @@ -394,6 +395,7 @@ class CC_DLL JniHelper { private: static jobject sContext; + static jobject sActivity; static JavaVM *sJavaVM; static JNIEnv *cacheEnv();