如何将Android独立Activity与Unity主Activity分离并实现交互
解决方案:在Unity之上运行独立Android Activity且不暂停游戏
针对你提出的四个问题,结合Unity与Android的交互逻辑,我给你梳理了具体的实现方案:
1. 能否让新Android Activity直接运行在Unity Activity之上,而非让Unity暂停?
当然可以!默认情况下,启动新Activity时Unity主Activity会触发onPause,而UnityPlayer的pause()方法会暂停游戏循环。但我们可以通过主题配置+Activity生命周期控制来避免这个情况:
- 给自定义Activity设置透明/对话框样式主题,让系统认为Unity Activity仍处于可见状态;
- 在Unity主Activity中添加标志位,控制UnityPlayer的暂停行为,仅在真正切后台时才暂停游戏。
2. 正确的实现步骤
步骤1:配置AndroidManifest.xml
首先给自定义Activity设置透明主题,并确保它和Unity主Activity在同一个任务栈:
<!-- 定义透明主题 --> <style name="TransparentActivity" parent="Theme.AppCompat.Light.NoActionBar"> <item name="android:windowBackground">@android:color/transparent</item> <item name="android:windowIsTranslucent">true</item> <item name="android:windowAnimationStyle">@android:style/Animation.Translucent</item> <item name="android:windowNoTitle">true</item> <item name="android:windowContentOverlay">@null</item> </style> <!-- 声明自定义Activity --> <activity android:name=".MyCustomActivity" android:theme="@style/TransparentActivity" android:exported="false" android:launchMode="standard"> </activity>
注意:不要设置
FLAG_ACTIVITY_NEW_TASK,否则会脱离Unity的任务栈,导致startActivityForResult失效。
步骤2:修改扩展的UnityPlayerActivity
重写生命周期方法,添加标志位控制UnityPlayer的暂停:
public class UnityMainActivity extends UnityPlayerActivity { private boolean isCustomActivityActive = false; // 供Unity调用的方法,启动自定义Activity public void launchCustomActivity(int requestCode) { isCustomActivityActive = true; Intent intent = new Intent(this, MyCustomActivity.class); startActivityForResult(intent, requestCode); } @Override protected void onPause() { // 只有当不是自定义Activity启动时,才执行Unity的默认暂停逻辑 if (!isCustomActivityActive) { super.onPause(); } } @Override protected void onResume() { super.onResume(); // 自定义Activity关闭后,重置标志位 isCustomActivityActive = false; } // 处理自定义Activity返回的结果 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_OK && requestCode == 1001) { // 对应你设置的requestCode String resultData = data.getStringExtra("task_result"); // 将结果传递给Unity UnityPlayer.UnitySendMessage("GameManager", "OnCustomActivityResult", resultData); } } }
步骤3:实现自定义Activity
编写你的业务逻辑,完成后返回结果给Unity主Activity:
public class MyCustomActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_custom); // 你的自定义布局 // 示例:完成任务后返回结果 findViewById(R.id.btn_complete_task).setOnClickListener(v -> { Intent resultIntent = new Intent(); resultIntent.putExtra("task_result", "自定义任务已完成"); setResult(RESULT_OK, resultIntent); finish(); // 关闭当前Activity,回到Unity主Activity }); } }
3. 如何让独立Activity完成后回调Unity主Activity,传递结果并恢复Unity?
整个流程是这样的:
- 自定义Activity完成任务后,调用
setResult()封装结果,再调用finish()关闭自身; - Unity主Activity的
onActivityResult会被触发,在这个方法里用UnityPlayer.UnitySendMessage()将结果传递给Unity的指定GameObject和方法; - Unity端接收结果后,继续游戏逻辑。
Unity端C#示例代码
public class GameManager : MonoBehaviour { private AndroidJavaObject _unityActivity; void Start() { // 获取Unity主Activity的引用 using (var unityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) { _unityActivity = unityClass.GetStatic<AndroidJavaObject>("currentActivity"); } } // 供UI按钮调用,启动Android自定义Activity public void LaunchCustomAndroidActivity() { _unityActivity.Call("launchCustomActivity", 1001); // requestCode与Android端对应 } // Android端回调的方法,必须是public、无返回值,参数类型要匹配 public void OnCustomActivityResult(string result) { Debug.Log("收到Android返回的结果:" + result); // 这里处理你的游戏逻辑,比如更新UI、继续游戏等 } }
4. 关于FLAG_ACTIVITY_NEW_TASK的问题
这个flag会将新Activity放入一个全新的任务栈,导致它和Unity主Activity不在同一个任务栈中,startActivityForResult自然无法接收返回结果——这就是你达不到预期效果的原因。
正确的做法是完全不要使用这个flag,保持自定义Activity的launchMode为默认的standard,这样它会和Unity主Activity共享同一个任务栈,startActivityForResult就能正常工作,结果也能正确回调。
内容的提问来源于stack exchange,提问作者hellaeon
相关产品推荐
相关产品推荐

