Как открыть фрагмент Android в новом процессе?

Приложение, над которым я сейчас работаю, использует Навигационный ящик, и каждая вкладка открывает новый фрагмент в упражнении (заменяя старый).

Одним из этих фрагментов является сцена Unity3D. В основном то, что я сделал, было:

  1. экспортировать проект Unity как приложение для Android
  2. откройте Активность, которую он дал (которая была UnityPlayerNativeActivity)
  3. преобразуйте этот UnityPlayerNativeActivity во фрагмент, как показано в коде ниже. Я также изменил некоторые мелочи в Манифесте.

    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);
    }
    }
    

Проблема здесь заключается в функции mUnityPlayer.quit(). Как указано здесь, mUnityPlayer.quit() полностью убивает процесс, в котором он запущен. Поэтому в основном происходит то, что все приложение завершается, когда я переключаю фрагменты (т. Е. Переключаем вкладки в NavigationDrawer), потому что это вызывает onDestroy объекта UnityPlayerNativeFragment,

Я не хочу это. В идеале пользователь должен переключаться на другую вкладку в Navigation Drawer, и когда он / она возвращается на вкладку сцены Unity, это именно то место, где он / она оставили ее. Как будто они использовали многозадачность Android для смены приложений и возврата - ничего не меняется.

Если бы это было действие, было бы возможно открыть его в другом процессе, чем основное приложение, добавив android:process=":UnityKillsMe" строка в файле манифеста, но это невозможно для фрагмента. Итак, мои вопросы:

  1. Как я могу открыть UnityPlayerNativeFragment в новом процессе, чтобы функция.quit () не убивала все мое приложение, и чтобы я мог перезапустить фрагмент, когда пользователь покидает вкладку и затем возвращается к ней?
  2. Даже если я смогу достичь первого квартала, остается проблема состояния. Выход и перезагрузка сцены 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();
        }
    }

1 ответ

Спасибо за твой код Я нахожу код, как изменить активность единства на фрагмент.

На ваш вопрос, я думаю, почему вам нужно вызвать mUnityPlayer.quit(); на метод Destory(). метод on Destory означает конец фрагмента. не деятельность.

Я думаю удалить метод бросить курить. добавьте слушатель между фрагментом с помощью MainActivity, когда MainActivity onDestroy вызовет метод фрагмента, чтобы вызвать выход из единства.

Другие вопросы по тегам