-2

I want to develop an app that allows me to upload data from form of an android app as a text file in server here is the mainactivity class

    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();
        }
    }

}

It comes up with an exception at line 53 httpclient.execute(httppost);

the exception says android.app.NetworkOnMainThreadException How do i solve this

curiousMind
  • 2,812
  • 1
  • 17
  • 38
Ram Kumar
  • 23
  • 3

4 Answers4

3

Just use a thread.

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

thread.start(); 

call the httpClient in this thread.

Chandan kushwaha
  • 941
  • 6
  • 26
2

You can't do your network calls in your MainThread. You should use an asynctask for your network operations. You can find more information about it from the link below:

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

Also i recommand you to use a network library to handle your network operations. You can find a good library for your network operations from the link below:

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

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
savepopulation
  • 11,736
  • 4
  • 55
  • 80
0

This exception that is thrown when an application attempts to perform a networking operation on its main thread. Applications targeting the Honeycomb SDK or higher are allowed to do networking on their main event loop threads to avoide sluggishness on unresponsive situatons related to networs. you can reffer to Documentation.

To resolve this you have options like : 1.Using AsyncTasks 2. Threads 3. Handlers

srv_sud
  • 647
  • 1
  • 9
  • 26
0

I would like to provide a solution for you here. For this i would like to point few points before you understand the solution.

  1. All android components(Activity,Service,BroadcastReceiver,Fragment and anything that visually shows data) run in the UI Thread or Main Thread, to understand this read further.

  2. Every Android Application run on its own process and have a unique userID for it. When ever an android application is installed it is given a unique user ID. Whenever the application runs it is given a separate Memory space and path for program execution. This process consists of its own memory called Heap. The process is like a separate environment given to your application to run code or process code.

  3. A thread on the other hand is a sub process or lightweight process. It is spawned inside the process. When ever a thread is created it is given some part of memory (stack). A process can spawn many number of threads.

  4. A thread can not access another threads memory (stack) , it is private to the particular thread. But they can access the Process memory (heap memory). Think heap memory as a global memory.

  5. Whenever a process is created for your application a single thread is created, which is mandatory. This thread is called a main thread. In android it maybe also referred as UI thread. Because this threads processes all the UI components that you see(Like activity,Fragment and Services(even though service is run on the background, it is run on UI Thread), etc).

  6. Android framework is created in such a way that they wanted to handle all the UI operations on the Main thread giving it high priority to process UI components. Because the UI is the one shown to the user and the user will not like an application if it is frozen without processing the UI.

  7. This is the reason you get a "NetworkOnMainThread" exception. Because Android restricts running long running operations like network access, file access, database access and those processings run on the UI Thread. Because it will take much time to process restricting the UI to be responsive, as it doesn't give an opportunity for the UI components to process.

I hope you understand why you get such exceptions now. Long running operations should not restrict UI thread operation. so it should be moved from UI thread to another new thread(Move the code where you create a HttpClient until you receive a response from it). Android also offers another alternative for this. You can create an AsyncTask, which handles the thread creation process for you. You can just write you code and pass the result to the UI thread. Learn more about it.

Notes: All threads access the process memory. But a process cannot access another process's memory unless it has the same USER ID. Means unless it is from one of your application. This can be done using AIDL interface.

I hope this solution helped you to understand the exception you get and solve them.

Raaja SN
  • 382
  • 3
  • 14