尝试以json格式返回url请求的输出,而不是在模拟器中工作

时间:2018-01-20 20:26:13

标签: android json android-emulator networkonmainthread

问题是返回给定设备的公共IP地址。最简单的方法是向返回IP的网站发送请求。在下面的方法中,提供的url将向您发送公共IP地址的json对象,该对象将返回一个字符串,问题可能是与android studio中的网站连接,因为它在常规记事本++和我的cmd中工作正常。

方法是

    public String getIP(){
    String out = "";
    try{
        out = new Scanner(new URL("https://api.ipify.org/?format=json").openStream(), "UTF-8").useDelimiter("\\A").next();
    }catch(MalformedURLException e){
        System.out.println(e);
    }catch(IOException e){
        System.out.println(e);
    }
    return out;
}

我的整个堆栈跟踪是

E/AndroidRuntime: FATAL EXCEPTION: main
              Process: com.example.matthewr.aiwlayout, PID: 2303
              java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.matthewr.aiwlayout/com.example.matthewr.aiwlayout.MainFeed}: android.os.NetworkOnMainThreadException
                  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2646)
                  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707)
                  at android.app.ActivityThread.-wrap12(ActivityThread.java)
                  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460)
                  at android.os.Handler.dispatchMessage(Handler.java:102)
                  at android.os.Looper.loop(Looper.java:154)
                  at android.app.ActivityThread.main(ActivityThread.java:6077)
                  at java.lang.reflect.Method.invoke(Native Method)
                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
               Caused by: android.os.NetworkOnMainThreadException
                  at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1303)
                  at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:86)
                  at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:74)
                  at java.net.InetAddress.getAllByName(InetAddress.java:752)
                  at com.android.okhttp.internal.Network$1.resolveInetAddresses(Network.java:29)
                  at com.android.okhttp.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:187)
                  at com.android.okhttp.internal.http.RouteSelector.nextProxy(RouteSelector.java:156)
                  at com.android.okhttp.internal.http.RouteSelector.next(RouteSelector.java:98)
                  at com.android.okhttp.internal.http.HttpEngine.createNextConnection(HttpEngine.java:345)
                  at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:328)
                  at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:246)
                  at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:457)
                  at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:405)
                  at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:243)
                  at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getInputStream(DelegatingHttpsURLConnection.java:210)
                  at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java)
                  at java.net.URL.openStream(URL.java:1057)
                  at com.example.matthewr.aiwlayout.TownieDBHandler.getIP(TownieDBHandler.java:121)
                  at com.example.matthewr.aiwlayout.TownieDBHandler.databaseToString(TownieDBHandler.java:89)
                  at com.example.matthewr.aiwlayout.MainFeed.printDatabase(MainFeed.java:56)
                  at com.example.matthewr.aiwlayout.MainFeed.onCreate(MainFeed.java:39)
                  at android.app.Activity.performCreate(Activity.java:6662)
                  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
                  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2599)
                  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707) 
                  at android.app.ActivityThread.-wrap12(ActivityThread.java) 
                  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460) 
                  at android.os.Handler.dispatchMessage(Handler.java:102) 
                  at android.os.Looper.loop(Looper.java:154) 
                  at android.app.ActivityThread.main(ActivityThread.java:6077) 
                  at java.lang.reflect.Method.invoke(Native Method) 
                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865) 
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755) 

1 个答案:

答案 0 :(得分:0)

由于Exception声明 NetworkOnMainThreadException ,您试图在主线程上调用网络任务,这将导致UI出现延迟,这应该使用另一个线程或使用{{3} }

<强>更新

以下是使用Asynctask

解决此错误的方法
class RetrieveIP extends AsyncTask<String, Void, String> {

    private Exception exception;

    protected String doInBackground(String... urls) {
        try {
             return new Scanner(new URL("https://api.ipify.org/?format=json").openStream(), "UTF-8").useDelimiter("\\A").next();
        } catch (Exception e) {
            this.exception = e;
            return null;
        } 
    }

    protected void onPostExecute(String out) {
        // TODO: check this.exception
        // TODO: do something with the string url out you got from the api
    }
}

如何执行任务:

MainActivity.java文件中,您可以在oncreate()方法

中添加此行
new RetrieveIP().execute("");

不要忘记将其添加到AndroidManifest.xml文件:

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