如何在Android中解决NetworkonMainThreadException问题?

20

我正在为作业创建一个项目,我是Android的新手,并想要访问非常常见的urlhttp://api.androidhive.info/contacts/中的json数据。

问题:我正尝试读取该url并获取解析返回的json数据。

我已经将以下行添加到了我的AndroidManifest.xml中。

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

偏好设置:我的 Android 偏好设置是

<uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="18" />
  1. Api level 18
  2. Android 4.3

and this is how I'm trying to read the url

static InputStream is = null;

DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);

HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();

错误信息

11-02 05:23:47.843: E/AndroidRuntime(2207): FATAL EXCEPTION: main
11-02 05:23:47.843: E/AndroidRuntime(2207): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.me.countrypedia/com.me.countrypedia.MainActivity}: android.os.NetworkOnMainThreadException
11-02 05:23:47.843: E/AndroidRuntime(2207):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2211)
11-02 05:23:47.843: E/AndroidRuntime(2207):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
11-02 05:23:47.843: E/AndroidRuntime(2207):     at android.app.ActivityThread.access$600(ActivityThread.java:141)
11-02 05:23:47.843: E/AndroidRuntime(2207):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)

我正在按照这篇ListView示例的教程进行: http://www.androidhive.info/2011/11/android-xml-parsing-tutorial/


3
使用线程或异步任务。应该在一个线程上执行此操作HttpResponse httpResponse = httpClient.execute(httpPost);。参考链接:https://dev59.com/-mw15IYBdhLWcg3w3vpe - Raghunandan
3个回答

19

你的Exception实际上告诉了你你做错了什么。你没有使用另一个线程来执行网络操作。相反,你在UI线程上执行网络操作,在安卓系统中这是无法工作的。

连接到url的代码应该例如在AsyncTaskdoInBackground()方法中在非UI线程上执行。

参考这个关于如何使用AsyncTask的问题:How to use AsyncTask


14

更新的答案:

网络等潜在耗时操作应在工作线程中完成。

创建用于长时间操作的最有效方法是使用AsyncTask类。只需扩展AsyncTask并实现doInBackground()方法来执行工作。

许多库可用于进行网络操作,例如Volleyretrofit等。


旧的答案:

在您的活动onCreate方法中添加以下行:

StrictMode.ThreadPolicy policy = new
StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);

这个很好用。谢谢分享。 - Uday

13

使用以下代码。

private class UpdateTask extends AsyncTask<String, String,String> {
     protected String doInBackground(String... urls) {

        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpPost httpPost = new HttpPost(url);

        HttpResponse httpResponse = httpClient.execute(httpPost);
        HttpEntity httpEntity = httpResponse.getEntity();
        is = httpEntity.getContent();
        return null;
     }

 }

在你的MainActivity中使用以下代码。

new UpdateTask().execute();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接