1

I'm learning how to build Android apps, and I'm trying to insert data on my database, using Java.

But I had no success doing that, I'm receiving this error:

 android.os.NetworkOnMainThreadException

I searched more about that, and a everybody says that AsynkTask removes this error. How can i adapt my code to AsynkTask? Can you guys explain me how it works?

Thanks

Code

package com.example.turanja;
....
public class register extends Activity {

    String name;
    String id;
    InputStream is=null;
    String result=null;
    String line=null;
    int code;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.register);

        final EditText e_id=(EditText) findViewById(R.id.editText1);
        final EditText e_name=(EditText) findViewById(R.id.editText2);
        Button insert=(Button) findViewById(R.id.button1);

        insert.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub

            id = e_id.getText().toString();
            name = e_name.getText().toString();
            insert();

        }
    });
    }


    public void insert()
    {
        ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();

    nameValuePairs.add(new BasicNameValuePair("id",id));
    nameValuePairs.add(new BasicNameValuePair("name",name));

        try
        {
        HttpClient httpclient = new DefaultHttpClient();
            HttpPost httppost = new HttpPost("http://10.0.2.2/example/insert.php");
            httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
            HttpResponse response = httpclient.execute(httppost); 
            HttpEntity entity = response.getEntity();
            is = entity.getContent();
            Log.e("pass 1", "connection success ");
    }
        catch(Exception e)
    {
            Log.e("Fail 1", e.toString());
            Toast.makeText(getApplicationContext(), "Invalid IP Address",
            Toast.LENGTH_LONG).show();
    }     

        try
        {
            BufferedReader reader = new BufferedReader
            (new InputStreamReader(is,"iso-8859-1"),8);
            StringBuilder sb = new StringBuilder();
            while ((line = reader.readLine()) != null)
        {
                sb.append(line + "\n");
            }
            is.close();
            result = sb.toString();
        Log.e("pass 2", "connection success ");
    }
        catch(Exception e)
    {
            Log.e("Fail 2", e.toString());
    }     

    try
    {
            JSONObject json_data = new JSONObject(result);
            code=(json_data.getInt("code"));

            if(code==1)
            {
        Toast.makeText(getBaseContext(), "Inserted Successfully",
            Toast.LENGTH_SHORT).show();
            }
            else
            {
         Toast.makeText(getBaseContext(), "Sorry, Try Again",
            Toast.LENGTH_LONG).show();
            }
    }
    catch(Exception e)
    {
            Log.e("Fail 3", e.toString());
    }
    }


}
Aniket Thakur
  • 66,731
  • 38
  • 279
  • 289

3 Answers3

0

See the answer here.It shows you a flowchart like

enter image description here

Keeping that in mind ..i will show you how to do this in your code.

Create a new class which extends AsyncTask like..

private class MyTask extends AsyncTask<String, Integer, String> {

    // Runs in UI before background thread is called
    @Override
    protected void onPreExecute() {
        super.onPreExecute();

        // Do something like display a progress bar
    }
    // This is run in a background thread
    @Override
    protected String doInBackground(String... params) {
        String msg="";
        ArrayList<NameValuePair> nameValuePairs = new 
        ArrayList<NameValuePair>();
        nameValuePairs.add(new BasicNameValuePair("id",id));
        nameValuePairs.add(new BasicNameValuePair("name",name));
        try
        {
             HttpClient httpclient = new DefaultHttpClient();
             HttpPost httppost = new HttpPost("http://10.0.2.2/example/insert.php");
             httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
             HttpResponse response = httpclient.execute(httppost); 
             HttpEntity entity = response.getEntity();
             is = entity.getContent();
             Log.e("pass 1", "connection success ");
         }
         catch(Exception e)
         {
             Log.e("Fail 1", e.toString());
             msg="Invalid IP Address";
         }     

         try
        {
             BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
             StringBuilder sb = new StringBuilder();
             while ((line = reader.readLine()) != null)
             {
                 sb.append(line + "\n");
             }
             is.close();
             result = sb.toString();
             Log.e("pass 2", "connection success ");
         }
         catch(Exception e)
         {
              Log.e("Fail 2", e.toString());
         }     
         try
         {
              JSONObject json_data = new JSONObject(result);
              code=(json_data.getInt("code"));
              if(code==1)
              {
                    msg="Inserted Successfully";
              }
              else
              {
                    msg="Sorry, Try Again";
              }
         }
         catch(Exception e)
         {
             Log.e("Fail 3", e.toString());
         }
    }
        return msg;
    }

    // This runs in UI when background thread finishes
    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);

        // Do things like hide the progress bar or change a TextView
             Toast.makeText(getBaseContext(),result,Toast.LENGTH_LONG).show();
    }
}

and add new MyTask().execute(); instead of calling insert();. I moved all the operations that you have done in insert() to doInBackground().

Community
  • 1
  • 1
Lal
  • 14,726
  • 4
  • 45
  • 70
0

This Exception occurs when you try to perform network operations of main UI thread.

Details on the Exception -

The exception that is thrown when an application attempts to perform a networking operation on its main thread.

This is only thrown for applications targeting the Honeycomb SDK or higher. Applications targeting earlier SDK versions are allowed to do networking on their main event loop threads, but it's heavily discouraged.

Documentation

Try doing same in AsyncTask. Sample snippet would look like -

class InsertTask extends AsyncTask<String, Integer, HttpEntity> {

    protected HttpEntity doInBackground(String... data) {
        try {
        
            ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
            nameValuePairs.add(new BasicNameValuePair("id",data[0]));
            nameValuePairs.add(new BasicNameValuePair("name",data[1]));
    
            HttpClient httpclient = new DefaultHttpClient();
            HttpPost httppost = new HttpPost("http://10.0.2.2/example/insert.php");
            httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
            HttpResponse response = httpclient.execute(httppost); 
            HttpEntity entity = response.getEntity();
            return entity;
        } catch (Exception e) {
            //log exception
            return null;
        }
    }

    protected void onPostExecute(HttpEntity id) {
        //further processing
        //perhaps callback to main activity for success/failure
    }
}

and you can execute this AsyncTask as

new InsertTask().execute(dataToInsert);
Community
  • 1
  • 1
Aniket Thakur
  • 66,731
  • 38
  • 279
  • 289
0

I prefer to use services for this kind of work because asyntask has few limitations. Please refer this link: "When the Activity is restarted, your AsyncTask’s reference to the Activity is invalid, so onPostExecute() will have no effect on the new Activity." http://blog.danlew.net/2014/06/21/the-hidden-pitfalls-of-asynctask/

Balvir Jha
  • 47
  • 2