我尝试json
使用HttpURLConnection
我在onCreate()中测试以下代码
try {
URL url = new URL("http://localhost/testrealm/api/v1/status");
HttpURLConnection urlConnection = null;
urlConnection = (HttpURLConnection) url.openConnection();
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
Log.d(TAG, "get json: " + in.toString());
urlConnection.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
请求中的错误
java.lang.RuntimeException:无法启动活动 ComponentInfo ... android.os.NetworkOnMainThreadException
记录错误整数
06-10 14:32:21.113 E/AndroidRuntime: FATAL EXCEPTION: main
Process: realm.test.app.testrealm, PID: 11702
java.lang.RuntimeException: Unable to start activity ComponentInfo{realm.test.app.testrealm/realm.test.app.testrealm.MainActivity}: android.os.NetworkOnMainThreadException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2339)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2413)
at android.app.ActivityThread.access$800(ActivityThread.java:155)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1317)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5343)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:905)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:700)
Caused by: android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1161)
at java.net.InetAddress.lookupHostByName(InetAddress.java:418)
at java.net.InetAddress.getAllByNameImpl(InetAddress.java:252)
at java.net.InetAddress.getAllByName(InetAddress.java:215)
at com.android.okhttp.HostResolver$1.getAllByName(HostResolver.java:29)
at com.android.okhttp.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:232)
at com.android.okhttp.internal.http.RouteSelector.next(RouteSelector.java:124)
at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:272)
at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:211)
at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:382)
at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:332)
at com.android.okhttp.internal.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:199)
at realm.test.app.testrealm.MainActivity.onCreate(MainActivity.java:57)
at android.app.Activity.performCreate(Activity.java:6010)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1129)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2292)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2413)
at android.app.ActivityThread.access$800(ActivityThread.java:155)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1317)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5343)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:905)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:700)
如果您使用StrictMode.ThreadPolicy.Builder来允许它工作的任何操作,但您正在禁用不应允许应用程序中某些行为的策略,在这种情况下,主线程上的操作,这主要用于开发,用于生产你不应该使用它。
使用runOnUiThread()
其他选项是Asynctask和Handler.post()。
我找到了这篇出色的文章以获取更多信息:“Android 后台任务(I):线程和 AsyncTask”(Salvador Gómez 的博客)。
你应该使用 AsynkTask:
如果您需要知道何时收到响应和/或在调用后修改视图,请像这样使用 AsynkTask:
在发出 Web 请求之前添加以下代码
HttpURLConnection
作为这个问题的另一个选择,我也通过我的手,是在 a 中实现你的代码,
runOnUiThread()
这将允许访问主线程的变量,因为这正是问题所在。在这个问题中,我解释了这种方法:
使用 Activity.runOnUiThread() 或 Handler.post(Runnable) 更新主线程?
一旦我再次有机会,我将尝试您的解决方案,从而了解其他可能的解决方案。
这个话题总是可以谈论的。禁用策略绝对不是选项。
但请注意,这与您想如何做事有很大关系,根据我的经验,我见过以下场景:
因此,我不知道您的情况是什么,您考虑一下很重要。对于第一种情况
AsyncTask
,这对您非常有利。您在其中执行繁重的过程doInBackground
,通知用户其进度,publishProgress
最后通过onPostExecute
. 它是通常的,不仅对服务器发出请求,它还适用于复杂的计算、数据库搜索等。只要您的意图是让用户等待这个过程(这可能很烦人),并且一旦完成,他们就可以与应用程序进行交互。对于第二种情况,一个
Thread
或一个Runnable
与一个一起Handler
派上用场,您在一个run
独立于其完成状态的方法中执行一个流程,而用户甚至不知道这一点。对于第三种情况,我们举个例子:您有一个流程,它捕获数据并将其转换为有用的信息,您将这些信息保存在本地数据库中,但由于数据冗余,您还必须将其发送到服务器;但是您还必须等待发送到服务器的结果来更新记录上的指示符,该指示符定义发送是否成功,例如,不要再次发送。对于这种情况,使用线程调度程序很方便,它允许您在线程完成执行的那一刻执行操作。一个非常简单的例子是Google Guava及其类
Futures
和ListenableFuture
.这是对您已回答的内容的一些额外信息,很高兴知道,因此请定义好您的场景,以便您可以选择更好的工作方式。