为什么使用 BufferedReader 打开 URL 流时捕获 UnknownHostException 会使我的应用程序崩溃?

发布于 2024-10-06 08:14:32 字数 2096 浏览 6 评论 0原文

我正在编写一个 Android 应用程序,该应用程序连接到网站并以 JSON 形式检索搜索结果。此函数发生在 AsyncTask 中,该任务被设置为与 UI 分开的流。我需要处理连接中断/不存在/太延迟的情况。我需要处理这种情况,以便向用户显示 AlertDialog,让他们知道连接不良。我看到帖子建议为 URLConnection 设置超时参数,但我现在没有使用 URLConnection。

现在,当我有数据连接时,该函数可以完美执行,但在没有连接时则不然。当我运行模拟器并禁用 PC 的互联网连接时,运行该函数会显示“强制关闭”消息并产生 UnknownHostException。我捕获了此异常,但我的应用程序仍然崩溃。

我还需要处理找不到缩略图的情况,这会产生 FileNotFoundException。

请告诉我应该做什么。谢谢。

@Override
protected HashMap<String, String> doInBackground(Object... params) {
    InputStream imageInput = null;
    FileOutputStream imageOutput = null;
    try {   
        URL url = new URL("http://www.samplewebsite.com/" + mProductID);
        BufferedReader reader = 
                new BufferedReader(new InputStreamReader(url.openStream()));
        String jsonOutput = "";
        String temp = "";
        while ((temp = reader.readLine()) != null) {
            jsonOutput += temp;
        }
        JSONObject json = new JSONObject(jsonOutput);

        // ... Do some JSON parsing and save values to HashMap

        String filename = mProductID + "-thumbnail.jpg";
        URL thumbnailURL = new URL("http://www.samplewebsite.com/img/" + mProductID + ".jpg");

        imageInput = thumbnailURL.openConnection().getInputStream();
        imageOutput = mContext.openFileOutput(outputName, Context.MODE_PRIVATE);

        int read;
        byte[] data = new byte[1024];
        while ((read = imageInput.read(data)) != -1) {
            imageOutput.write(data, 0, read);
        }

        reader.close();

    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (UnknownHostException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (JSONException e) {
        e.printStackTrace();
    }
    finally {
        try {
            imageOutput.close();
            imageInput.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

return mProductInfoHashMap;

}

I'm writing an Android application that is connecting to a website and retrieving search results in the form of JSON. This function is happening in an AsyncTask, which is set up as a separate stream from the UI. I need to handle the case where the connection is interrupted/non-existent/too latent. I need to handle this case in order to display an AlertDialog to the user letting them know the connection is bad. I've seen posts suggest setting a timeout parameter for URLConnection, but I'm not using URLConnection right now.

Right now, The function performs flawlessly when I have a data connection, but not so when there is no connection. When I run the emulator and disable my PC's internet connection, running the function brings up a "Force Close" message and produces an UnknownHostException. I'm catching this exception, but my application still crashes.

I also need to handle a case where no thumbnail can be found, which produces a FileNotFoundException.

Please advise me on what I should do. Thanks.

@Override
protected HashMap<String, String> doInBackground(Object... params) {
    InputStream imageInput = null;
    FileOutputStream imageOutput = null;
    try {   
        URL url = new URL("http://www.samplewebsite.com/" + mProductID);
        BufferedReader reader = 
                new BufferedReader(new InputStreamReader(url.openStream()));
        String jsonOutput = "";
        String temp = "";
        while ((temp = reader.readLine()) != null) {
            jsonOutput += temp;
        }
        JSONObject json = new JSONObject(jsonOutput);

        // ... Do some JSON parsing and save values to HashMap

        String filename = mProductID + "-thumbnail.jpg";
        URL thumbnailURL = new URL("http://www.samplewebsite.com/img/" + mProductID + ".jpg");

        imageInput = thumbnailURL.openConnection().getInputStream();
        imageOutput = mContext.openFileOutput(outputName, Context.MODE_PRIVATE);

        int read;
        byte[] data = new byte[1024];
        while ((read = imageInput.read(data)) != -1) {
            imageOutput.write(data, 0, read);
        }

        reader.close();

    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (UnknownHostException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (JSONException e) {
        e.printStackTrace();
    }
    finally {
        try {
            imageOutput.close();
            imageInput.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

return mProductInfoHashMap;

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

彻夜缠绵 2024-10-13 08:14:32

你的问题不是 UnknownHost 而是在你的finally块中你没有正确关闭开放资源(不是导致问题的原因,但你本质上做错了)并且你没有捕获所有可能的异常(这就是为什么你的代码没有按你的预期工作)。你最好使用 try{ __.close(); } catch(__Exception e){...} 对于您要关闭的每个资源。这样,如果您的其中一个 close() 调用出现异常,其他资源仍然会关闭,否则您只需将它们保持打开状态并直接跳入 catch 块在最后中。

然而,问题的真正原因是,在获得初始异常然后进入 finally 块之前,您的资源没有被实例化。所以,它们仍然是null。您应该捕获的异常以及 IOExceptionNullPointerException

希望这对您有所帮助。

Your problem isn't the UnknownHost but rather in your finally block you're not closing open resources correctly (not what's causing the issue, but you're essentially doing it wrong) and you're not catching all possible exceptions (this is why you're code isn't working as you expect). You are much better off having a try{ __.close(); } catch(__Exception e){...} for EACH resource you're closing. This way if one of your close() calls has an exception, the other resources still get closed, otherwise you're just leaving them open and jumping straight into the catch block in finally.

The real reason for your issue, however, is that your resources aren't getting instantiated before getting an initial exception and then going into the finally block. So, they're still null. The exception you should be catching, along with an IOException is a NullPointerException.

Hopefully this helps you out.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文