由于NetworkOnMainThreadException,Android应用程序崩溃

时间:2016-02-23 07:05:37

标签: android exception networkonmainthread

我想开发一个应用程序,允许我从Android应用程序的形式上传数据作为服务器中的文本文件 这是主要活动类

    package com.example.incrediblemachine.sendtest;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends Activity {

    EditText msgTextField;
    Button sendButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //make message text field object
        msgTextField = (EditText) findViewById(R.id.msgTextField);
        //make button object
        sendButton = (Button) findViewById(R.id.sendButton);
    }

    public void send(View v)
    {
        //get message from message box
        String  msg = msgTextField.getText().toString();

        //check whether the msg empty or not
        if(msg.length()>0) {
            HttpClient httpclient = new DefaultHttpClient();
            HttpPost httppost = new HttpPost("http://ramsproject.16mb.com/sendorder.php");

            try {
                List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
                nameValuePairs.add(new BasicNameValuePair("id", "01"));
                nameValuePairs.add(new BasicNameValuePair("message", msg));
                httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
                httpclient.execute(httppost);
                msgTextField.setText(""); //reset the message text field
                Toast.makeText(getBaseContext(),"Sent",Toast.LENGTH_SHORT).show();
            }catch (IllegalStateException e)
            {
                e.printStackTrace();
            }
            catch (ClientProtocolException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            //display message if text field is empty
            Toast.makeText(getBaseContext(),"All fields are required",Toast.LENGTH_SHORT).show();
        }
    }

}

第53行出现了例外情况 httpclient.execute(httppost);

异常说android.app.NetworkOnMainThreadException 我该如何解决这个问题

4 个答案:

答案 0 :(得分:2)

只需使用一个帖子。

Thread thread = new Thread(new Runnable(){
    @Override
    public void run() {
        try {
            //Your code goes here
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
});

thread.start(); 

在这个帖子中调用httpClient。

答案 1 :(得分:2)

您无法在MainThread中进行网络通话。您应该使用asynctask进行网络操作。您可以从以下链接中找到有关它的更多信息:

https://developer.android.com/reference/android/os/AsyncTask.html

另外,我建议您使用网络库来处理网络操作。您可以通过以下链接找到适合您的网络运营的好库:

http://square.github.io/retrofit/

答案 2 :(得分:0)

当应用程序尝试在其主线程上执行网络操作时引发此异常。 针对Honeycomb SDK或更高版本的应用程序可以在其主要事件循环线程上进行联网,以避免与网络相关的无响应情境的迟缓。你可以接受Documentation

要解决此问题,您可以选择以下选项:  1.使用AsyncTasks  2.线程  3.处理程序

答案 3 :(得分:0)

我想在这里为您提供解决方案。为此,我想在您了解解决方案之前指出几点。

  1. 所有Android组件(Activity,Service,BroadcastReceiver,Fragment以及可视化显示数据的任何内容)都在UI线程或主线程中运行,以进一步理解此读取。

  2. 每个Android应用程序都在自己的进程上运行,并拥有唯一的用户ID。安装Android应用程序时,会给它一个唯一的用户ID。每当应用程序运行时,都会为程序执行提供单独的内存空间和路径。这个过程由它自己的内存Heap组成。该过程就像一个单独的环境,为您的应用程序提供运行代码或流程代码。

  3. 另一方面,线程是子流程或轻量级流程。它是在这个过程中产生的。当创建一个线程时,它会被赋予内存的一部分(堆栈)。一个进程可以产生许多线程。

  4. 一个线程无法访问另一个线程内存(堆栈),它对特定线程是私有的。但是他们可以访问进程内存(堆内存)。将堆内存视为全局内存。

  5. 每当为您的应用程序创建一个进程时,就会创建一个必需的线程。该线程称为主线程。在android中它也可能被称为UI线程。因为此线程处理您看到的所有UI组件(如活动,片段和服务(即使服务在后台运行,它在UI线程上运行)等。)

  6. Android框架的创建方式使得他们希望处理主线程上的所有UI操作,从而为处理UI组件提供高优先级。因为UI是向用户显示的UI,并且如果在不处理UI的情况下冻结应用程序,则用户将不喜欢该应用程序。

  7. 这就是您获得“NetworkOnMainThread”异常的原因。因为Android限制运行长时间运行的操作,如网络访问,文件访问,数据库访问以及在UI线程上运行的那些处理。因为处理限制UI的响应需要花费很多时间,因为它没有为UI组件提供处理的机会。

  8. 我希望你明白为什么你现在得到这样的例外。长时间运行的操作不应限制UI线程操作。所以它应该从UI线程移动到另一个新线程(移动代码,你创建一个HttpClient,直到你收到它的响应)。 Android还为此提供了另一种选择。您可以创建一个AsyncTask,它为您处理线程创建过程。您可以只编写代码并将结果传递给UI线程。了解更多信息。

    注意:所有线程都访问进程内存。但是,除非具有相同的USER ID,否则进程无法访问其他进程的内存。除非是来自您的一个申请,否则意味着。这可以使用AIDL接口完成。

    我希望这个解决方案可以帮助您理解您获得的异常并解决它们。