为什么在使用中断我的程序崩溃?

时间:2015-08-04 00:41:49

标签: java android android-studio

我在MainActivity中添加了一个按钮点击事件:

public void addListenerOnButton()
    {

        btnClick = (Button) findViewById(R.id.checkipbutton);

        btnClick.setOnClickListener(new OnClickListener()
        {
            byte[] response = null;
            @Override
            public void onClick(View arg0)
            {

                text = (TextView) findViewById(R.id.textView2);


                Thread t = new Thread(new Runnable()
                {
                    @Override
                    public void run()
                    {
                        for (int i = 0; i < ipaddresses.length; i++)

                        {

                            try
                            {
                                response = Get(ipaddresses[i]);
                                break;     

                            } catch (Exception e)
                            {
                                text.setText("Connection Failed");
                            }
                        }
                        if (response!=null)
                        {
                            String a = null;
                            try
                            {
                                a = new String(response,"UTF-8");
                                text.setText(a);
                            } catch (UnsupportedEncodingException e)
                            {
                                e.printStackTrace();
                            }
                            Logger.getLogger("MainActivity(inside thread)").info(a);
                        }
                    }
                });
                t.start();
            }
        });

    }

我想在执行response = Get(ipaddresses[i]);之后进入try块时创建一个中断,以便停止for循环。

问题在于,response = Get(ipaddresses[i]);完成了它应该休息之后,我的程序崩溃了。

在Android设备上,我收到消息:

  

不幸的是myapp已经停止了

当我点击消息时,程序就会关闭。

我无法弄清楚为什么休息会让程序崩溃。

这是Get方法:

private byte[] Get(String urlIn)
    {
        URL url = null;

        String urlStr = urlIn;
        if (urlIn!=null)
            urlStr=urlIn;

        try
        {
            url = new URL(urlStr);
        } catch (MalformedURLException e)
        {
            e.printStackTrace();
            return null;
        }
        HttpURLConnection urlConnection = null;
        try
        {

            urlConnection = (HttpURLConnection) url.openConnection();


            InputStream in = new BufferedInputStream(urlConnection.getInputStream());

            byte[] buf=new byte[10*1024];
            int szRead = in.read(buf); 

            byte[] bufOut;



            if (szRead==10*1024)
            {
                throw new AndroidRuntimeException("the returned data is bigger than 10*1024.. we don't handle it..");
            }
            else
            {
                bufOut = Arrays.copyOf(buf, szRead);
            }

            return bufOut;
        }
        catch (IOException e)
        {
            e.printStackTrace();
            return null;
        }
        finally
        {
            if (urlConnection!=null)
                urlConnection.disconnect();
        }
    }

1 个答案:

答案 0 :(得分:0)

崩溃的原因很可能来自您没有向我们展示过的堆栈跟踪。

但是那个循环的逻辑对我来说是非常可疑的。

  • 如果没有break,循环将遍历所有IP地址,并在每个IP地址上尝试Get。最后,response将是Get来电返回的最后一个值,可能是也可能不是null

  • 使用break,循环终止于Get未引发异常的第一个IP地址之后......无论Get调用返回什么。 (可能是null。)

这可能是导致崩溃的原因,但也可能是其他原因。无论哪种方式,逻辑都是可疑的。 (调用方法Get是不好的风格!)

<强>更新

鉴于Get方法捕获异常并在失败时返回null,调用它的代码的推荐结构是:

    for (int i = 0; i < ipaddresses.length; i++) {
        response = Get(ipaddresses[i]);
        if (response != null) {
            break;     
        }
    }
    if (response == null) {
        // notify connection failed
    } else {
        // process response
    }

调用代码中不需要“腰带和大括号”try {...} catch ...如果您已经处理过Get中的预期异常。而且(IMO)你应该(几乎)永远不会抓住Exception,因为这很容易隐藏错误。