有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java在Android Studio中更改片段时,如何关闭Unity而不关闭整个应用程序?

我有一个应用程序,用户可以使用BottomNavigationView浏览不同的片段,其中一个片段是Unity3D应用程序。所以,当我打开Unity片段时,它是工作的,但是当我打开另一个片段并打开Unity片段时,它崩溃了。我该如何修复这个问题?这是我的代码

主要活动。爪哇

public class MainActivity extends AppCompatActivity {

BottomNavigationView mBottomNavigationView;
NavController mNavController;
NavDestination mDestination;
AppBarConfiguration appBarConfiguration;
String tab;
private boolean doubleBackToExitPressedOnce ;

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    boolean b = this.requestWindowFeature(Window.FEATURE_NO_TITLE);
    this.setContentView(R.layout.activity_main);

    ActionBar mActionBar = getSupportActionBar();
    mActionBar.setDisplayShowHomeEnabled(false);
    mActionBar.setDisplayShowTitleEnabled(false);
    LayoutInflater li = LayoutInflater.from(this);
    View customView = li.inflate(R.layout.top_menu_custom, null);
    mActionBar.setCustomView(customView);
    mActionBar.setDisplayShowCustomEnabled(true);


    mBottomNavigationView = (BottomNavigationView) findViewById(R.id.nav_view);

    ImageButton profileButton = (ImageButton) customView.findViewById(R.id.profile_button);
    ImageButton notificationButton = (ImageButton) customView.findViewById(R.id.noti_button);

    profileButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            ProfileFragment profileFragment = new ProfileFragment();
            getSupportFragmentManager().beginTransaction()
                    .replace(R.id.nav_host_fragment,profileFragment)
                    .addToBackStack(tab)
                    .setReorderingAllowed(true)
                    .commit();
            mBottomNavigationView.setVisibility(View.GONE);
        }
    });

    notificationButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            NotificationFragment notificationFragment = new NotificationFragment();
            getSupportFragmentManager().beginTransaction()
                    .replace(R.id.nav_host_fragment,notificationFragment)
                    .addToBackStack(tab)
                    .setReorderingAllowed(true)
                    .commit();
            mBottomNavigationView.setVisibility(View.GONE);
        }
    });

    mBottomNavigationView.setItemIconTintList(null);
    mBottomNavigationView.setItemTextColor(ColorStateList.valueOf(getColor(R.color.black)));

    mNavController = Navigation.findNavController(this, R.id.nav_host_fragment);

    // Passing each menu ID as a set of Ids because each
    // menu should be considered as top level destinations.
    appBarConfiguration = new AppBarConfiguration.Builder(
            R.id.navigation_home, R.id.navigation_dashboard,R.id.navigation_map, R.id.navigation_card,R.id.navigation_deals)
            .build();

    NavigationUI.setupActionBarWithNavController(this, mNavController, appBarConfiguration);
    NavigationUI.setupWithNavController(mBottomNavigationView, mNavController);
    mNavController.addOnDestinationChangedListener(new NavController.OnDestinationChangedListener() {

        @Override
        public void onDestinationChanged(@NonNull NavController controller, @NonNull NavDestination destination, @Nullable Bundle arguments) {
            Toast.makeText(getApplicationContext(),"hi",Toast.LENGTH_SHORT).show();
            mDestination = mNavController.getCurrentDestination();
            tab = mDestination.toString();
        }
    });


}

@Override
public void onBackPressed() {
    //Toast.makeText(getApplicationContext(), mDestination.toString(),Toast.LENGTH_SHORT).show();


    if (doubleBackToExitPressedOnce) {
        getSupportFragmentManager().popBackStackImmediate();
        mNavController.navigate(mDestination.getId());
        mBottomNavigationView.setVisibility(View.VISIBLE);
        super.onBackPressed();
        return;
    }

    this.doubleBackToExitPressedOnce = true;
    Toast.makeText(this, "Please click BACK again to exit", Toast.LENGTH_SHORT).show();

    new Handler().postDelayed(new Runnable() {

        @Override
        public void run() {
            doubleBackToExitPressedOnce=false;
        }
    }, 2000);
}

单位碎片

public class MapFragment extends Fragment{

protected UnityPlayer mUnityPlayer;
FrameLayout frameLayoutForUnity;

public MapFragment() {
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    mUnityPlayer = new UnityPlayer(getActivity());
    View view = inflater.inflate(R.layout.fragment_map, container, false);
    this.frameLayoutForUnity = (FrameLayout) view.findViewById(R.id.frameLayoutForUnity);
    this.frameLayoutForUnity.addView(mUnityPlayer.getView(),
            FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT);

    mUnityPlayer.requestFocus();
    mUnityPlayer.windowFocusChanged(true);
    return view;
}

@Override
public void onPause() {
    super.onPause();
    mUnityPlayer.pause();
}

@Override
public void onResume() {
    super.onResume();
    mUnityPlayer.resume();
}

// Quit Unity
@Override
public void onDestroy ()
{
    mUnityPlayer.quit();
    super.onDestroy();
}

共 (2) 个答案

  1. # 1 楼答案

    所以我设法解决了这个问题,我不知道这样做是否好,但我所做的是在我的主要活动中实例化UnityPlayer,在我的片段中,我调用了在我的主要活动中安装的UnityPlayer

    主要活动。爪哇

    public class MainActivity extends AppCompatActivity {
    
    public BottomNavigationView mBottomNavigationView;
    public NavController mNavController;
    public NavDestination mDestination;
    AppBarConfiguration appBarConfiguration;
    String tab;
    int onBackTimes = 0;
    
    public UnityPlayer mUnityPlayer; <  Call unity player
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
        super.onCreate(savedInstanceState);
    
        mUnityPlayer = new UnityPlayer(this); <  UNITY PLAYER HERE
    
        boolean b = this.requestWindowFeature(Window.FEATURE_NO_TITLE);
    
        this.setContentView(R.layout.activity_main);
    
        ActionBar mActionBar = getSupportActionBar();
        mActionBar.setDisplayShowHomeEnabled(false);
        mActionBar.setDisplayShowTitleEnabled(false);
        LayoutInflater li = LayoutInflater.from(this);
        View customView = li.inflate(R.layout.top_menu_custom, null);
        mActionBar.setCustomView(customView);
        mActionBar.setDisplayShowCustomEnabled(true);
    
    
        mBottomNavigationView = (BottomNavigationView) findViewById(R.id.nav_view);
    
        ImageButton profileButton = (ImageButton) customView.findViewById(R.id.profile_button);
        ImageButton notificationButton = (ImageButton) customView.findViewById(R.id.noti_button);
    
        profileButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
    
                ProfileFragment profileFragment = new ProfileFragment();
                getSupportFragmentManager().beginTransaction()
                        .replace(R.id.nav_host_fragment,profileFragment)
                        .addToBackStack(tab)
                        .setReorderingAllowed(true)
                        .commit();
                mBottomNavigationView.setVisibility(View.GONE);
            }
        });
    
        notificationButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
    
                NotificationFragment notificationFragment = new NotificationFragment();
                getSupportFragmentManager().beginTransaction()
                        .replace(R.id.nav_host_fragment,notificationFragment)
                        .addToBackStack(tab)
                        .setReorderingAllowed(true)
                        .commit();
                mBottomNavigationView.setVisibility(View.GONE);
            }
        });
    
        mBottomNavigationView.setItemIconTintList(null);
        mBottomNavigationView.setItemTextColor(ColorStateList.valueOf(getColor(R.color.black)));
    
        mNavController = Navigation.findNavController(this, R.id.nav_host_fragment);
    
        // Passing each menu ID as a set of Ids because each
        // menu should be considered as top level destinations.
        appBarConfiguration = new AppBarConfiguration.Builder(
                R.id.navigation_home, R.id.navigation_dashboard,R.id.navigation_map, R.id.navigation_card,R.id.navigation_deals)
                .build();
    
        NavigationUI.setupActionBarWithNavController(this, mNavController, appBarConfiguration);
        NavigationUI.setupWithNavController(mBottomNavigationView, mNavController);
        mNavController.addOnDestinationChangedListener(new NavController.OnDestinationChangedListener() {
    
            @Override
            public void onDestinationChanged(@NonNull NavController controller, @NonNull NavDestination destination, @Nullable Bundle arguments) {
                mDestination = mNavController.getCurrentDestination();
                tab = mDestination.toString();
            }
        });
    
    
    }
    
    @Override
    public void onBackPressed() {
    
        Toast.makeText(this, "Please click BACK again to exit", Toast.LENGTH_SHORT).show();
    
        onBackTimes +=1;
    
        if(onBackTimes>1){
            LoginActivity.close.finish();
            finish();
    
        }
        else{
            getSupportFragmentManager().popBackStackImmediate();
            mBottomNavigationView.setVisibility(View.VISIBLE);
            super.onBackPressed();
            mNavController.navigate(mDestination.getId());
        }
    
        new Handler().postDelayed(new Runnable() {
    
            @Override
            public void run() {
                onBackTimes=0;
            }
        }, 2000);
    
    }
    
    @Override
    protected void onStop() {
        super.onStop();
    }
    
    
    //UNITY STUFF OVER HERE
    
    @Override
    protected void onPause() {
        super.onPause();
        mUnityPlayer.pause();
    }
    
    @Override protected void onResume()
    {
        super.onResume();
        mUnityPlayer.resume();
    }
    
    @Override
    protected void onDestroy(){
        super.onDestroy();
    }
    
    }
    

    单位碎片

    public class MapFragment extends Fragment{
    
    private MainActivity mUnityMainActivity;
    private UnityPlayer mUnityPlayer;
    
    public MapFragment() {
    }
    
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
    
        //this code calls the UNITYPLAYER from MainActivity and return it here
        mUnityMainActivity = (MainActivity) getActivity();
        View unityPlayViewer = mUnityMainActivity.mUnityPlayer.getView();
        mUnityMainActivity.mUnityPlayer.requestFocus();
        mUnityMainActivity.mUnityPlayer.windowFocusChanged(true);
    
        return unityPlayViewer;
    }
    
    /** FOR UNITY **/
    @Override
    public void onPause() {
        super.onPause();
        mUnityMainActivity.mUnityPlayer.pause();
    }
    
    // Resume Unity
    @Override public void onResume()
    {
        super.onResume();
        mUnityMainActivity.mUnityPlayer.resume();
    }
    

    我不知道为什么我必须在这两个文件中都包含OnPause、OnResume等,但如果其中一个没有,它就会崩溃

  2. # 2 楼答案

    问题是,每次我们切换到unity片段时,都会创建一个新的UnityPlayer,这会使应用程序崩溃。因此,我们只需要第一次创建UnityPlayer,或者只在播放器停止时创建UnityPlayer。这对我来说很有效

    在UnityFragment类中,我的全局变量:

    protected UnityPlayer mUnityPlayer;
    private View view;
    private FrameLayout frameLayoutForUnity;
    

    onCreate中,将创建一个新的UnityPlayer,它仅第一次被调用:

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mUnityPlayer = new UnityPlayer(getActivity()); // create Unity Player
    }
    

    onCreateView中,我们刷新UnityPlayer的视图:

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        if(mUnityPlayer.getParent() != null){
            ((ViewGroup)mUnityPlayer.getParent()).removeAllViews();
        }
        view = inflater.inflate(R.layout.fragment_unity, container, false);
        this.frameLayoutForUnity = (FrameLayout) view.findViewById(R.id.unityFragmentLayout);
        this.frameLayoutForUnity.addView(mUnityPlayer.getView(),
                FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT);
    
        mUnityPlayer.requestFocus();
        mUnityPlayer.windowFocusChanged(true);
        return view;
    }
    

    其余部分不变。可能有比这更好的解决方案。干杯:)