如何在新进程中打开Android Fragment?

Jim*_*mmy 5 android process unity-game-engine android-fragments

我目前正在处理的应用程序使用导航抽屉,每个选项卡在活动中打开一个新片段(替换旧片段).

其中一个片段是Unity3D场景.基本上,我做的是:

  1. 将Unity项目导出为Android应用程序
  2. 打开它给出的Activity(这是UnityPlayerNativeActivity)
  3. 将此UnityPlayerNativeActivity转换为Fragment,如下面的代码所示.我还改变了Manifest中的一些小问题.

    import com.unity3d.player.*;
    import android.app.Fragment;
    import android.app.NativeActivity;
    import android.content.res.Configuration;
    import android.graphics.PixelFormat;
    import android.os.Bundle;
    import android.view.KeyEvent;
    import android.view.LayoutInflater;
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.ViewGroup;
    import android.view.WindowManager;
    
    public class UnityPlayerNativeFragment extends Fragment
    {
        protected UnityPlayer mUnityPlayer;     // don't change the name of this variable; referenced from native code
        private static final String ARG_SECTION_NUMBER = "section_number";
    
    public static UnityPlayerNativeFragment newInstance(int sectionNumber) {
        UnityPlayerNativeFragment fragment = new UnityPlayerNativeFragment();
        Bundle args = new Bundle();
        args.putInt(ARG_SECTION_NUMBER, sectionNumber);
        fragment.setArguments(args);
        return fragment;
    }
    // Setup activity layout
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState)
    {
    
        getActivity().getWindow().takeSurface(null);
        getActivity().setTheme(android.R.style.Theme_NoTitleBar_Fullscreen);
        getActivity().getWindow().setFormat(PixelFormat.RGB_565);
    
        mUnityPlayer = new UnityPlayer(getActivity());
        if (mUnityPlayer.getSettings ().getBoolean ("hide_status_bar", true))
            getActivity().getWindow().setFlags (WindowManager.LayoutParams.FLAG_FULLSCREEN,
                                   WindowManager.LayoutParams.FLAG_FULLSCREEN);
    
        int glesMode = mUnityPlayer.getSettings().getInt("gles_mode", 1);
        boolean trueColor8888 = false;
        mUnityPlayer.init(glesMode, trueColor8888);
        mUnityPlayer.windowFocusChanged(true);
        mUnityPlayer.setX((float)-5);
        View playerView = mUnityPlayer.getView();
        return playerView;
    }
    
    // Quit Unity
    @Override
    public void onDestroy ()
    {
        mUnityPlayer.quit();
        super.onDestroy();
    }
    
    // Pause Unity
    @Override
    public void onPause()
    {
        super.onPause();
        mUnityPlayer.pause();
    }
    
    // Resume Unity
    @Override
    public void onResume()
    {
        super.onResume();
        mUnityPlayer.resume();
    }
    
    // This ensures the layout will be correct.
    @Override
    public void onConfigurationChanged(Configuration newConfig)
    {
        super.onConfigurationChanged(newConfig);
        mUnityPlayer.configurationChanged(newConfig);
    }
    
    public void onWindowFocusChanged(boolean hasFocus)
    {
        mUnityPlayer.windowFocusChanged(hasFocus);
    }
    }
    
    Run Code Online (Sandbox Code Playgroud)

这里的问题是使用mUnityPlayer.quit()函数.如前所述这里,mUnityPlayer.quit()完全杀死进程正在运行的,所以基本上什么情况是,整个应用程序退出时,我切换片段(在NavigationDrawer即开关选项卡),因为调用UnityPlayerNativeFragment的的onDestroy .

我不想要这个.理想情况下,用户可以切换到NavigationDrawer中的另一个选项卡,当他/她回到Unity场景的选项卡时,它正是他/她离开的位置.好像他们使用Android多任务来更改应用程序和返回 - 没有任何变化.

如果这是一个Activity,则可以通过android:process=":UnityKillsMe"在Manifest文件中添加行来在与主应用程序不同的进程中打开它,但这对于片段是不可能的.所以,我的问题:

  1. 如何在新进程中打开UnityPlayerNativeFragment,以便.quit()函数不会终止我的整个应用程序,以便当用户离开选项卡然后返回时,我可以重新启动片段?
  2. 即使我能够实现Q1,仍然存在国家问题.退出然后重新加载Unity场景将重新创建它,从默认视图开始,并丢失它拥有的任何属性(例如,想象它是一个游戏,然后所有数据都将丢失).问题2是:我如何切换到同一个应用程序中的另一个选项卡,然后返回Unity选项卡,而根本不更改场景?(基本上,保持它在后台运行而根本不退出).

这是我如何切换片段(来自MainActivity):

@Override
    public void onNavigationDrawerItemSelected(int position) {
        // update the main content by replacing fragments
        FragmentManager fragmentManager = getFragmentManager();
        if (position==3) {
            fragmentManager.beginTransaction()
                    .replace(R.id.container, DirectoryFragment.newInstance(position + 1))
                    .commit();
        }
        else if (position == 0) {
            upnf = UnityPlayerNativeFragment.newInstance(position + 1);
            fragmentManager.beginTransaction()
                    .replace(R.id.container, upnf, "UnityPlayerNativeFragment")
                    .commit();
        }
        else if (position == 2){
            fragmentManager.beginTransaction()
                    .replace(R.id.container, WeatherFragment.newInstance(position + 1))
                    .commit();
        }
        else if (position == 4) {
            fragmentManager.beginTransaction()
                    .replace(R.id.container, SettingsFragment.newInstance(position + 1))
                    .commit();
            //Log.d("worked pos=4","worked pos=4");
        }
        else{
            fragmentManager.beginTransaction()
                    .replace(R.id.container, PlaceholderFragment.newInstance(position + 1))
                    .commit();
        }
    }
Run Code Online (Sandbox Code Playgroud)

小智 0

感谢您的代码。我正在寻找如何将统一活动更改为片段的代码。

对于你的问题,我在想为什么你需要调用 mUnityPlayer.quit(); 在 Destory() 方法上。onDestory 方法意味着片段完成。不是活动。

我认为删除 quit 方法。在fragment和MainActivity之间添加一个监听器,当MainActivity onDestroy时,调用fragment方法来调用unity退出。