2016-02-23 2 views
-2

Я хочу разработать приложение, которое позволяет мне загружать данные из формы андроид приложения в виде текстового файла в сервере здесь класс mainactivityAndroid приложение падает из-за NetworkOnMainThreadException

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 Как я решить эту проблему

+1

использовать AsyncTask для выполнения сетевых вызовов в фоновом режиме. –

+1

используйте этот код в AsyncTask – curiousMind

+1

Android не позволяет вам делать интернет-вызовы в основном потоке, чтобы не блокировать его и предлагать плохой пользовательский интерфейс. Система заставляет вас делать это в другом потоке ... вот что вы должны делать. – Fustigador

ответ

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

или AsyncTask ... – IceJOKER

+0

Спасибо! Работал для меня –

+0

Всегда приветствую. –

2

Вы не можете выполнять свои сетевые вызовы в своем MainThread. Вы должны использовать asynctask для своих сетевых операций. Вы можете найти более подробную информацию об этом по ссылке ниже:

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

Также я Recommand вам использовать сетевую библиотеку для обработки сетевых операций. Вы можете найти хорошую библиотеку для сетевых операций по ссылке ниже:

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

0

Это исключение, которое выдается, когда приложение пытается выполнить операцию сети на ее главном потоке. Приложения, ориентированные на SDK Honeycomb или выше, могут создавать сети в своих основных потоках цикла событий, чтобы избежать медлительности в отношении нерегулярных ситуаций, связанных с сетями. вы можете ответить на Documentation.

Чтобы решить эту проблему у вас есть варианты, как: 1.using AsyncTasks 2. Нити 3. Обработчики

0

Я хотел бы, чтобы обеспечить решение для вас здесь. Для этого я хотел бы указать несколько пунктов, прежде чем вы поймете решение.

  1. Все андроид компоненты (Activity, Service, BroadcastReceiver, фрагмент и все, что наглядно показывает данные), в потоке пользовательского интерфейса или основной поток, чтобы понять это читать дальше.

  2. Каждое приложение для Android запускается на собственном процессе и имеет для него уникальный идентификатор пользователя. Когда когда-либо установлено приложение для Android, ему предоставляется уникальный идентификатор пользователя. Всякий раз, когда приложение запускается, ему предоставляется отдельное пространство памяти и путь для выполнения программы. Этот процесс состоит из собственной памяти, называемой кучей. Этот процесс похож на отдельную среду, предоставляемую вашему приложению для запуска кода или кода процесса.

  3. Нить, с другой стороны, является вспомогательным процессом или легким процессом. Он возникает в процессе. Когда когда-либо создается поток, ему предоставляется часть памяти (стек). Процесс может порождать множество потоков.

  4. Нить не может получить доступ к другой памяти потоков (стек), она является частной для конкретного потока. Но они могут получить доступ к памяти процесса (памяти кучи). Подумайте, что память кучи является глобальной памятью.

  5. Всякий раз, когда процесс создается для вашего приложения, создается один поток, который является обязательным. Этот поток называется основным потоком. В android это, возможно, также называют потоком пользовательского интерфейса. Поскольку эти потоки обрабатывают все компоненты пользовательского интерфейса, которые вы видите (например, активность, фрагмент и службы (даже несмотря на то, что служба выполняется на фоне, она запускается в потоке пользовательского интерфейса) и т. Д.).

  6. Каркас для Android создан таким образом, что они хотят обрабатывать все операции пользовательского интерфейса в основном потоке, придавая ему высокий приоритет обработке компонентов пользовательского интерфейса. Поскольку пользовательский интерфейс является тем, который показан пользователю, и пользователю не понравится приложение, если оно заморожено без обработки пользовательского интерфейса.

  7. Это причина, по которой вы получаете исключение «NetworkOnMainThread». Поскольку Android ограничивает выполнение длительных операций, таких как доступ к сети, доступ к файлам, доступ к базе данных и эти процессы, выполняемые в потоке пользовательского интерфейса. Поскольку для обработки пользовательского интерфейса потребуется много времени, чтобы откликаться, поскольку он не дает возможности компонентам пользовательского интерфейса обрабатывать.

Надеюсь, вы понимаете, почему вы получаете такие исключения сейчас. Длительные операции не должны ограничивать работу потока пользовательского интерфейса. поэтому он должен быть перенесен из потока пользовательского интерфейса в другой новый поток (переместите код, в котором вы создаете HttpClient, пока не получите от него ответ). Android также предлагает другую альтернативу для этого. Вы можете создать AsyncTask, который обрабатывает процесс создания потоков для вас. Вы можете просто написать код и передать результат в поток пользовательского интерфейса. Узнайте больше об этом.

Примечания: Все потоки обращаются к памяти процесса. Но процесс не может получить доступ к памяти другого процесса, если у него нет одинакового идентификатора пользователя. Значит, если это не одно из ваших приложений. Это можно сделать с помощью интерфейса AIDL.

Я надеюсь, что это решение помогло вам понять, какое исключение вы получите и решите.

+0

Если вы хотите создать поток или AsyncTask, я могу привести пример для него. –

+0

благодарит за информацию –