0

Following scenario: I've a TabLayout with 2 tabs. On the one tab there are a button. When I press that button, the app connects to a chat server and automatically switches to the second tab. The problem is that when I go back to the first tab (while the connection to the server is still up) the app crashes. If I switch between the tabs (as long as no connection to the server has been established) then everything is normal and the app doesn't crash at all. The app throws the Exception: "java.lang.IllegalStateException: No host".

Here the (shorted) code of MainActivity.java:

public class MainActivity extends AppCompatActivity 
{
    FrameLayout simpleFrameLayout;
    TabLayout tabLayout;
    SecondFragment s = new SecondFragment();
    
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        
        simpleFrameLayout = (FrameLayout) findViewById(R.id.simpleFrameLayout);
        tabLayout = (TabLayout) findViewById(R.id.simpleTabLayout);
// Create a new Tab named "First"
        TabLayout.Tab firstTab = tabLayout.newTab();
        firstTab.setText("First"); // set the Text for the first Tab
    
// first tab
        tabLayout.addTab(firstTab); // add  the tab at in the TabLayout
// Create a new Tab named "Second"
        TabLayout.Tab secondTab = tabLayout.newTab();
        secondTab.setText("Second"); // set the Text for the second Tab
        
        tabLayout.addTab(secondTab); // add  the tab  in the TabLayout

        Fragment fragment = null;
        fragment = new FirstFragment();
        FragmentManager fm = getSupportFragmentManager();
        FragmentTransaction ft = fm.beginTransaction();
        ft.replace(R.id.simpleFrameLayout, fragment);
        ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
        ft.commit();
        
        tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
                @Override
                public void onTabSelected(TabLayout.Tab tab) {
// get the current selected tab's position and replace the fragment accordingly
                    Fragment fragment = null;
                    switch (tab.getPosition()) {
                        case 0:
                            fragment = new FirstFragment();
                            myMenu.findItem(R.id.telefono).setVisible(false);
                            break;
                        case 1:
                            fragment = s;
                            myMenu.findItem(R.id.telefono).setVisible(true);
                            break;
                    }
                    FragmentManager fm = getSupportFragmentManager();
                    FragmentTransaction ft = fm.beginTransaction();
                    ft.replace(R.id.simpleFrameLayout, fragment);
                    ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
                    ft.commit();
                }
                @Override
                public void onTabUnselected(TabLayout.Tab tab) {

                }

                @Override
                public void onTabReselected(TabLayout.Tab tab) {

                }
            });
    }
    
    
    
    public void conectar(String nombre, String ip, int puerto) { //This method is called when the button of tab one is pressed
        //Code...
        Executor executor = Executors.newSingleThreadExecutor();
        executor.execute(new Runnable() {
                @Override
                public void run() {
                    Looper.prepare();
                    
                    try{
                        //Code...
                        try {
                            //Code...
                            try {
                                runOnUiThread(new Runnable() {

                                        @Override
                                        public void run() {
                                            TabLayout.Tab tab = tabLayout.getTabAt(1);
                                            tab.select();
                                        }
                                    });
                                
                            }
                            catch (Exception e){
                                
                            }
                            
                            //Code...
                        }
                        catch(SocketTimeoutException ex)
                        {

                        }
                    }
                    catch(Exception e){
                        StringWriter sw = new StringWriter();
                        e.printStackTrace(new PrintWriter(sw));
                        String stacktrace = sw.toString();
                        // create an email intent to send to yourself
                        final Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
                        emailIntent.setType("plain/text");
                        emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[] { "lets.think.android@gmail.com" });
                        emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "App Error Report");
                        emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, stacktrace);
                        // start the email activity - note you need to start it with a chooser
                        startActivity(Intent.createChooser(emailIntent, "Send error report..."));
                    }
                }
            });

    }
    
    
}

As you can see, in the method 'conectar', which is executed when the button of tab 1 is pressed, the app automatically switches from tab 1 to tab 2. Therefore I suspect that some status has to be reported. For example, maybe I need to report that tab 1 is no longer selected.

Does anyone have any idea what could be the problem?

Aaron
  • 55
  • 5

1 Answers1

0

I think the problem is that when you use replace for changing fragment its destroy all other fragment that you added before to your container. and when you press back button there is no fragment to get back on.I have tow suggestion for you:

1- use a view pager instead of using fragment manager(if the Design allow you)

2- use add instead of replace in your fragment manager

Shadman Adman
  • 383
  • 3
  • 12
  • Many thanks for your response! Only: if a fragment is destroyed, then it has to be recreated when you tap on the tab, right? And: if I use 'add' instead of 'replace', then so many first fragments will accumulate over time until the memory is full; and tabs that are no longer required will not be deleted. Or am I wrong? – Aaron Dec 20 '20 at 17:17
  • @Aaron you are right. but you can achieve that by adding a condition that if this fragment is already added, do not added again. this link is a very good sample for that condition https://stackoverflow.com/a/37703245/4398123 . – Shadman Adman Dec 20 '20 at 19:37
  • I'm not understanding the point: if the fragment was not created, then yes, I could use the 'add' method. But if it was created, I can't use 'add'. But when I don't use 'add', then the fragment can't be showed. The only logical way I see, is to use the 'replace' method. Can you show a code about what are you meaning, so I can understand you better. – Aaron Dec 21 '20 at 13:48
  • @Aaron you can search for difference for add and replace. this lick might help. but i still suggest you ,use view pager. https://stackoverflow.com/a/42554681/4398123 – Shadman Adman Dec 21 '20 at 15:18