如何解决 java.lang.IllegalStateException:没有主机?

Posted

技术标签:

【中文标题】如何解决 java.lang.IllegalStateException:没有主机?【英文标题】:How to solve java.lang.IllegalStateException: No host? 【发布时间】:2021-03-30 13:22:27 【问题描述】:

以下场景: 我有一个带有 2 个选项卡的 TabLayout。 在一个选项卡上有一个按钮。当我按下该按钮时,该应用程序会连接到聊天服务器并自动切换到第二个选项卡。 问题是,当我返回第一个选项卡时(与服务器的连接仍然存在),应用程序崩溃了。 如果我在选项卡之间切换(只要未建立与服务器的连接),那么一切正常,应用程序根本不会崩溃。 应用抛出异常:“java.lang.IllegalStateException: No host”。

这里是 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..."));
                    
                
            );

    
    
    

如您所见,在按下选项卡1的按钮时执行的方法'conectar'中,应用程序会自动从选项卡1切换到选项卡2。因此我怀疑必须报告某些状态。例如,也许我需要报告标签 1 不再被选中。

有人知道可能是什么问题吗?

【问题讨论】:

【参考方案1】:

我认为问题在于,当您使用replace 更改片段时,它会破坏您之前添加到容器中的所有其他片段。当你按下返回按钮时,没有片段可以重新打开。我有两个建议给你:

1- 使用视图寻呼机而不是使用片段管理器(如果设计允许)

2- 在片段管理器中使用 add 而不是 replace

【讨论】:

非常感谢您的回复!仅:如果片段被破坏,那么当您点击选项卡时必须重新创建它,对吗?并且:如果我使用 'add' 而不是 'replace',那么随着时间的推移会积累很多第一个片段,直到内存已满;不再需要的选项卡将不会被删除。还是我错了? @Aaron 你是对的。但是您可以通过添加一个条件来实现这一点,如果该片段已经添加,则不要再次添加。此链接是该条件的一个很好的示例***.com/a/37703245/4398123。 我不明白这一点:如果没有创建片段,那么是的,我可以使用“添加”方法。但如果它是创建的,我不能使用“添加”。但是当我不使用'add'时,片段就无法显示。我看到的唯一合乎逻辑的方法是使用“替换”方法。你能给出一个代码来说明你的意思,这样我就可以更好地理解你了。 @Aaron 您可以搜索差异以进行添加和替换。这个舔可能会有所帮助。但我仍然建议你,使用查看寻呼机。 ***.com/a/42554681/4398123

以上是关于如何解决 java.lang.IllegalStateException:没有主机?的主要内容,如果未能解决你的问题,请参考以下文章

使用多租户时的 Spring Boot 范围问题

云原生景观:可观察性和分析解决了什么问题?如何解决的?

如何解决 Ajax 跨域请求不到的问题

如何解决包冲突问题

如何解决包冲突问题

如何解决ajax跨域问题