0

I am new to connecting to server With async thread and I am facing the below error:

java.lang.runtimeexception can't create handler inside.thread that has not called looper

I know I read SO answers about it but I couldnt know how to fix it .

My aim of the code is to insert into the database "id" , and "name" with async thread. any help will be appreciated

package com.example.zproject;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
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 org.json.JSONObject;

import android.app.Activity;
import android.opengl.Visibility;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity implements OnClickListener{

    private EditText value;
    private Button btn;
    private ProgressBar pb;
    EditText namet;
    EditText idt;
    String name;
    String id;
    String line;
    String result;
    InputStream is;
    int code;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        namet=(EditText)findViewById(R.id.editText1);
        btn=(Button)findViewById(R.id.button1);
        pb=(ProgressBar)findViewById(R.id.progressBar1);
        pb.setVisibility(View.GONE);
        btn.setOnClickListener(this);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;

    }

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


                pb.setVisibility(View.VISIBLE);
                new MyAsyncTask().execute(name);        


    } 

    private class MyAsyncTask extends AsyncTask<String, Integer, Double>{

        @Override
        protected Double doInBackground(String... params) {
            // TODO Auto-generated method stub
            postData(params[0]);
            return null;
        }

        protected void onPostExecute(Double result){
            pb.setVisibility(View.GONE);
            Toast.makeText(getApplicationContext(), "command sent", Toast.LENGTH_LONG).show();
        }
        protected void onProgressUpdate(Integer... progress){
            pb.setProgress(progress[0]);
        }

        public void postData(String valueIWantToSend) {
            // Create a new HttpClient and Post Header
            HttpClient httpclient = new DefaultHttpClient();
            HttpPost httppost = new HttpPost("http://justedhak.comlu.com/receiver.php");

            try {
                // Add your data

                 name = namet.getText().toString();
                 id = idt.getText().toString();
                List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
                nameValuePairs.add(new BasicNameValuePair("id",id));
                nameValuePairs.add(new BasicNameValuePair("name",name));
                //nameValuePairs.add(new BasicNameValuePair("myHttpData", valueIWantToSend));
                httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
                HttpResponse response = httpclient.execute(httppost);
                HttpEntity entity = response.getEntity();
                  is = entity.getContent();
                // Execute HTTP Post Request
                Log.d("Message", "> " + entity);
            } catch (ClientProtocolException e) {
                // TODO Auto-generated catch block
            } catch (IOException e) {
                // TODO Auto-generated catch block
            }
                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());
                }


        }

    }
}
Community
  • 1
  • 1
Moudiz
  • 7,211
  • 22
  • 78
  • 156
  • 2
    the use of a Toast on a thread different from the UI Thread makes Android cry – Blackbelt Jul 01 '15 at 15:47
  • @Blackbelt okay I removed it. – Moudiz Jul 01 '15 at 15:48
  • 1
    http://stackoverflow.com/questions/16760971/trying-to-fix-networkonmainthreadexception-but-gives-toast-error/16761020#16761020 – codeMagic Jul 01 '15 at 15:49
  • @codeMagic I am not finding helpful tutorial that I cant Post and Get with async thread, do you know a tutorial that I can insert into the database with async ? .. what am doing now is combining tutorials but its not helping – Moudiz Jul 01 '15 at 15:58
  • This answer I gave on [How to use AsyncTask](http://stackoverflow.com/questions/18898039/using-asynctask/18898105#18898105) should give you a good start. But basically, don't do UI operations in `doInBackground()` or any method called by it. That answer and the docs linked in it should explain that and other things about it. – codeMagic Jul 01 '15 at 16:01
  • @codeMagic yes I read about the 4 steps of async and I add the HTTPclient , HTTPpost ,HTTP response and Json in post data. but it didnt work for me. is there an answers covers where to put the HTTP ? and how to connect to sever – Moudiz Jul 01 '15 at 16:05
  • 1
    That should all go in `doInBackground()` as you have. But the problem you currently have is as stated above. Fix that then if you have another issue, after researching, post a new question. – codeMagic Jul 01 '15 at 16:07
  • @codeMagic well yes after removing the toast the error disappeared. I got error regarding the connection, I guess i can solve it. anyway thanks for you help. – Moudiz Jul 01 '15 at 16:10

1 Answers1

1

doInbackground() is executing postData() method, don´t use the Toast at this point, the operation in the main UI is causing this problem, change for a LogCat message...

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

                        if(code==1)
                        {
                    Toast.makeText(getBaseContext(), "Inserted Successfully",
                        Toast.LENGTH_SHORT).show(); //*INCORRECT
                        }
                        else
                        {
                     Toast.makeText(getBaseContext(), "Sorry, Try Again",
                        Toast.LENGTH_LONG).show();  //*INCORRECT
                        }
                }
...
...

Like some friends have suggested, if you want to show some messages to the user You could call publishProgress() and show the Toast in onProgressUpdate().

Jorgesys
  • 124,308
  • 23
  • 334
  • 268
  • I'm not sure that switching to a log message is the best solution to give here. If the Toast is meant for the user to see and not just for debugging then this isn't really an effective solution – codeMagic Jul 01 '15 at 15:54
  • yes i Agree with you, but he can use the publishProgress() method to display the messages to the user. – Jorgesys Jul 01 '15 at 15:58
  • 1
    it is one time showing, so I guess onPostExcecute would be a more appropriated place – Blackbelt Jul 01 '15 at 16:01
  • I understand what he can/can't do but he obviously doesn't. My point is that demonstrating that, as is already done in many answers, would be better than suggesting to switch to log statements. @Blackbelt agreed, orb – codeMagic Jul 01 '15 at 16:01