【问题标题】:NullPointerException when trying to read info from an url using HttpURLConnection尝试使用 HttpURLConnection 从 url 读取信息时出现 NullPointerException
【发布时间】:2019-01-20 08:31:21
【问题描述】:

我正在尝试使用 HttpURLConnection 从 url 读取一些信息,但是,当我尝试运行它时,我得到:

java.lang.RuntimeException:无法启动活动 ComponentInfo{...}: java.lang.NullPointerException: println 需要一个 消息。

我已经看到很多例子可以做到这一点,那么问题是什么?我已经仔细检查了 url,当我将它复制/粘贴到网络浏览器时,我得到了我应该得到的消息,没有问题。我使用相同的 url 将信息获取到不同的程序(用 C++ 编写),它在那里工作得很好。是否有我错过的连接设置或其他什么?

代码如下,问题出现在“InputStream stream = connection.getInputStream();”:

public String download_organisations(String url){
    String jsonString = "";
    try {
        if(!url.startsWith("http://")){
            url = "http://" + url;
        }
        if(url.endsWith("/")){
            url = url.substring(0, url.lastIndexOf("/"));
        }
        url = url + SystemStatic.URL_SERVICE_WEB_ORGANISATION_MANAGER;

        Log.d("OrganisationManager-Android","url: " + url);
        URL httpUrl = new URL(url);

        HttpURLConnection connection = (HttpURLConnection) httpUrl.openConnection();
        connection.setConnectTimeout(10000);


        InputStream stream = connection.getInputStream();

        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        int nRead;
        byte[] data = new byte[1024];
        while ((nRead = stream.read(data, 0, data.length)) != -1) {
            buffer.write(data, 0, nRead);
        }

        buffer.flush();
        byte[] inputStreamByteArray = buffer.toByteArray();

        byte[] base64 = Base64.decode(inputStreamByteArray, 0);
        byte[] decrypted = CipherUtils.decrypt(base64);

        jsonString = decrypted.toString();

        if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
            Log.d("OrganisationManager-Android", "Download succeded with response: " + connection.getResponseCode());
        } else {
            Log.d("OrganisationManager-Android", "Download failed with response: " + connection.getResponseCode());
        }
    } catch (MalformedURLException e) {
        Log.e("OrganisationManager-Android", e.getMessage());

    } catch (IOException e) {
        Log.e("OrganisationManager-Android", e.getMessage());

    } catch (Exception e) {
        Log.e("OrganisationManager-Android", e.getMessage());

    }

    return jsonString;
}

错误堆栈:

E/AndroidRuntime: FATAL EXCEPTION: main
              Process: com.organisationmanager.cin, PID: 2066
              java.lang.RuntimeException: Unable to start activity ComponentInfo{com.organisationmanager.cin/com.organisationmanager.ble.ScanningActivity}: java.lang.NullPointerException: println needs a message
                  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3194)
                  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3302)
                  at android.app.ActivityThread.-wrap12(Unknown Source:0)
                  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1891)
                  at android.os.Handler.dispatchMessage(Handler.java:108)
                  at android.os.Looper.loop(Looper.java:166)
                  at android.app.ActivityThread.main(ActivityThread.java:7425)
                  at java.lang.reflect.Method.invoke(Native Method)
                  at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245)
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921)
               Caused by: java.lang.NullPointerException: println needs a message
                  at android.util.Log.println_native(Native Method)
                  at android.util.Log.e(Log.java:261)
                  at com.organisationmanager.ble.common.OrganisationManagerWebPortalCommunicationHelper.download_organisations(OrganisationManagerWebPortalCommunicationHelper.java:210)
                  at com.organisationmanager.ble.ScanningActivity.onCreate(ScanningActivity.java:184)
                  at android.app.Activity.performCreate(Activity.java:7372)
                  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1218)
                  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3147)
                  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3302) 
                  at android.app.ActivityThread.-wrap12(Unknown Source:0) 
                  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1891) 
                  at android.os.Handler.dispatchMessage(Handler.java:108) 
                  at android.os.Looper.loop(Looper.java:166) 
                  at android.app.ActivityThread.main(ActivityThread.java:7425) 
                  at java.lang.reflect.Method.invoke(Native Method) 
                  at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245) 
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921) 

【问题讨论】:

  • 请向我们展示整个代码。您要访问哪个 URL,并且您是否验证过它是可访问的,例如从您的移动网络浏览器或本地计算机?
  • 能否请您也显示完整的错误堆栈?
  • 请分享更多信息。print 声明在哪里抛出NPE
  • @TimBiegeleisen 我扩展了代码以包含整个类,尽管我认为它对我当前的问题没有帮助。关于 URL,正如我在帖子中所说,我确实使用我的网络浏览器对其进行了验证,它既可以访问,又能给出正确的响应。
  • 您是在 Java 代码运行时直接从您的 Java 代码中获取该 URL,还是您认为该代码正在使用该 URL?现在对你来说最好的事情就是调试你的代码。在 Android Studio 中添加一个断点,然后逐行执行该方法,直到看到一些东西。

标签: java android nullpointerexception inputstream httpurlconnection


【解决方案1】:

错误堆栈说:

原因:java.lang.NullPointerException: println 需要一条消息 在 android.util.Log.println_native(本机方法) 在 android.util.Log.e(Log.java:261)

从这些行可以看出,异常是由Log.e()download_organisations() 内的catch 块之一中引发的(捕获MalformedURLException 的块或捕获@987654328 的块) @,或捕获Exception的那个)。

您通过记录消息来处理catch 块中的异常。但也许他们的消息是null,所以println 没有要打印的有效消息并抛出NullPointerException

尝试记录e,并检查是否再次抛出“java.lang.NullPointerException: println needs a message”。这样做:

} catch (IOException e) {
        Log.e("OrganisationManager-Android", e.toString());
}

否则您可以打印捕获到的异常的堆栈跟踪:

} catch (IOException e) {
        Log.e("OrganisationManager-Android");
        e.printStackTrace()
}

【讨论】:

  • 谢谢!这给了我一个新的错误代码: E/OrganisationManager-Android: android.os.NetworkOnMainThreadException 仍然不知道真正的问题是什么,但它有助于获得正确的错误消息。它不会让我只使用“e”,但我使用了“e.toString()”并且有效。为什么“e.getMessage()”不起作用?我认为这是获取错误消息的最常见方式...
  • 抛出此错误是因为您在主线程上发出 HTTP 请求。此行为会阻止应用程序,直到请求未完成:然后,用户将无法使用该应用程序,并将给他们带来糟糕的用户体验。您应该使用 AsyncTask 或者,如果您需要在 UI 上加载请求结果,请使用 Loader(尽管自 API 28 起已弃用),正如 this 页面所述。
  • @Kurodani 这个解决方案有用吗?
  • 抱歉回复慢,是的,这很有帮助!
【解决方案2】:

检查您的应用是否在清单中获得许可?

如果你不使用它 试试看:

在 AndroidManifest 中将这段代码添加到 Tag Application 之外

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

【讨论】:

  • 从我的清单中复制:
猜你喜欢
  • 1970-01-01
  • 2013-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-21
  • 1970-01-01
相关资源
最近更新 更多