Android:应用程序意外停止了!致命异常:主要是NetworkOnMainThreadException

时间:2014-08-01 01:19:34

标签: android json android-activity

当我使用我的Android手机将json发送到服务器并且应用程序被刷新时。但是当我使用模拟器时它会起作用。

Application has stopped unexpectedly!

代码:

String url = <<the url>>;
DefaultHttpClient httpClient = new DefaultHttpClient();

HttpPost httpPost = new HttpPost(url);


List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("email", email));
params.add(new BasicNameValuePair("password", password));

try {
  httpPost.setEntity(new UrlEncodedFormEntity(params));
                          httpPost.getParams().setParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, Boolean.FALSE);
                    } catch (UnsupportedEncodingException e1) {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                    }

                    HttpResponse httpResponse = null;
                    StringBuilder builder = new StringBuilder();
                    JSONTokener tokener = null;
                    try {
                        httpResponse = httpClient.execute(httpPost);
                        HttpEntity entity = httpResponse.getEntity();

                        InputStream content = entity.getContent();

                        BufferedReader reader = new BufferedReader(new InputStreamReader(content));
    String line;

    while((line = reader.readLine()) != null){
    builder.append(line);
    }
    tokener = new JSONTokener(builder.toString());
    String execution = null;

    try{
    //convert the api response into json object
    JSONObject jsonObject = new JSONObject(tokener);
    execution = jsonObject.get("execution").toString();

    //display the json object
    } catch(Exception e){
    e.printStackTrace();
    }

    if (execution.equals("true")){
    //run method to open message dialog
    openSuccessDialog(v, "You have logged in your account.");
    }
    else{
    //run method to open message dialog
    openErrorDialog(v, "Execution false. Your email and password doesn't match.");
                        }

logcat的:

08-01 10:26:52.985: W/dalvikvm(4335): threadid=1: thread exiting with uncaught exception (group=0x416a7e18)
08-01 10:26:52.995: E/AndroidRuntime(4335): FATAL EXCEPTION: main
08-01 10:26:52.995: E/AndroidRuntime(4335): Process: com.entityaccess.assetmappingsprintone, PID: 4335
08-01 10:26:52.995: E/AndroidRuntime(4335): android.os.NetworkOnMainThreadException
08-01 10:26:52.995: E/AndroidRuntime(4335):     at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1239)
08-01 10:26:52.995: E/AndroidRuntime(4335):     at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:84)
08-01 10:26:52.995: E/AndroidRuntime(4335):     at libcore.io.IoBridge.connectErrno(IoBridge.java:127)
08-01 10:26:52.995: E/AndroidRuntime(4335):     at libcore.io.IoBridge.connect(IoBridge.java:112)
08-01 10:26:52.995: E/AndroidRuntime(4335):     at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
08-01 10:26:52.995: E/AndroidRuntime(4335):     at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:459)
08-01 10:26:52.995: E/AndroidRuntime(4335):     at java.net.Socket.connect(Socket.java:873)
08-01 10:26:52.995: E/AndroidRuntime(4335):     at org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:125)
08-01 10:26:52.995: E/AndroidRuntime(4335):     at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:144)
08-01 10:26:52.995: E/AndroidRuntime(4335):     at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
08-01 10:26:52.995: E/AndroidRuntime(4335):     at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
08-01 10:26:52.995: E/AndroidRuntime(4335):     at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:367)
08-01 10:26:52.995: E/AndroidRuntime(4335):     at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:754)
08-01 10:26:52.995: E/AndroidRuntime(4335):     at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:519)
08-01 10:26:52.995: E/AndroidRuntime(4335):     at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:497)
08-01 10:26:52.995: E/AndroidRuntime(4335):     at com.entityaccess.assetmappingsprintone.LoginActivity$1.onClick(LoginActivity.java:119)
08-01 10:26:52.995: E/AndroidRuntime(4335):     at android.view.View.performClick(View.java:4480)
08-01 10:26:52.995: E/AndroidRuntime(4335):     at android.view.View$PerformClick.run(View.java:18686)
08-01 10:26:52.995: E/AndroidRuntime(4335):     at android.os.Handler.handleCallback(Handler.java:733)
08-01 10:26:52.995: E/AndroidRuntime(4335):     at android.os.Handler.dispatchMessage(Handler.java:95)
08-01 10:26:52.995: E/AndroidRuntime(4335):     at android.os.Looper.loop(Looper.java:157)
08-01 10:26:52.995: E/AndroidRuntime(4335):     at android.app.ActivityThread.main(ActivityThread.java:5872)
08-01 10:26:52.995: E/AndroidRuntime(4335):     at java.lang.reflect.Method.invokeNative(Native Method)
08-01 10:26:52.995: E/AndroidRuntime(4335):     at java.lang.reflect.Method.invoke(Method.java:515)
08-01 10:26:52.995: E/AndroidRuntime(4335):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
08-01 10:26:52.995: E/AndroidRuntime(4335):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:674)
08-01 10:26:52.995: E/AndroidRuntime(4335):     at dalvik.system.NativeStart.main(Native Method)
08-01 10:26:55.858: D/Process(4335): killProcess, pid=4335
08-01 10:26:55.858: D/Process(4335): com.android.internal.os.RuntimeInit$UncaughtHandler.uncaughtException:131 java.lang.ThreadGroup.uncaughtException:693 java.lang.ThreadGroup.uncaughtException:690 

如何解决这个问题,让我的手机能够将json发送到服务器?

3 个答案:

答案 0 :(得分:0)

您无法在主线程上进行网络调用。您需要在单独的线程中运行此代码,您的问题将得到解决。

例外很明确!

08-01 10:26:52.995: E/AndroidRuntime(4335): android.os.NetworkOnMainThreadException

您可以在Android上选择多种选择。您可以使用java中熟知的Thread类。或者您可以使用AsyncTask。如果你愿意,你也可以把它扔进IntentService。选项在那里,您可以根据自己的需要选择最佳选择。

答案 1 :(得分:0)

首先,这个问题已被多次询问过...在提问之前你应该做一些搜索:)

错误基本上意味着您正在UI线程上运行http请求,这是您不应该做的事情。你要做的是将请求放在Asynctask中,如下所示:

class postRequest extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... params) {
String url = <<the url>>;
DefaultHttpClient httpClient = new DefaultHttpClient();

HttpPost httpPost = new HttpPost(url);


List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("email", email));
params.add(new BasicNameValuePair("password", password));

try {
  httpPost.setEntity(new UrlEncodedFormEntity(params));
                          httpPost.getParams().setParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, Boolean.FALSE);
                    } catch (UnsupportedEncodingException e1) {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                    }

                    HttpResponse httpResponse = null;
                    StringBuilder builder = new StringBuilder();
                    JSONTokener tokener = null;
                    try {
                        httpResponse = httpClient.execute(httpPost);
                        HttpEntity entity = httpResponse.getEntity();

                        InputStream content = entity.getContent();

                        BufferedReader reader = new BufferedReader(new InputStreamReader(content));
    String line;

    while((line = reader.readLine()) != null){
    builder.append(line);
    }
    tokener = new JSONTokener(builder.toString());
    String execution = null;

    try{
    //convert the api response into json object
    JSONObject jsonObject = new JSONObject(tokener);
    execution = jsonObject.get("execution").toString();

    //display the json object
    } catch(Exception e){
    e.printStackTrace();
    }

    if (execution.equals("true")){
    //run method to open message dialog
    openSuccessDialog(v, "You have logged in your account.");
    }
    else{
    //run method to open message dialog
    openErrorDialog(v, "Execution false. Your email and password doesn't match.");
                        }


 }

答案 2 :(得分:0)

创建一个AsyncTask并将您的代码放在doInBackground中。

private class YourTask extends AsyncTask<String, String, String> {
     protected Long doInBackground(String... params) {
         // your network call here
     }

     protected void onPostExecute(String result) {
         // open your dialogs here
     }
 }

然后调用execute来运行你的任务:

new YourTask().execute();

说明:在Android中,所有网络访问(以及任何其他阻止代码)都需要在main thread之外完成,以便UI不会阻止。 AsyncTask是一种方便的方法。它在一个新线程中运行doInBackground,当它完成后,它在主线程中运行onPostExecute,因此你可以在UI中显示结果。