-1

So, on a button click, I create a new thread and then I am sending data to an asp.net script and after sending the data, I am "clearing" the EditText field. But, after I send the data, the textview is not cleared and the app freezes and sometimes crashes. Here is my Activity code:

http://www.mstreetllc.com/Lab.asp

package com.example.testphp;

import java.io.IOException;

import org.apache.http.client.ClientProtocolException;

import java.util.ArrayList;
import java.util.List;

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


// import everything you need
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends Activity {

Button sendButton;

EditText msgTextField;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // load the layout
    setContentView(R.layout.fragment_main);

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

    sendButton.setOnClickListener(new OnClickListener() {
        public void onClick(View v) {
            Thread thread = new Thread(new Runnable(){
                @Override
                public void run() {
                    try {
                        // get the message from the message text box
                        String msg = msgTextField.getText().toString();

                        // make sure the fields are not empty
                        if (msg.length() > 0) {
                            HttpClient httpclient = new DefaultHttpClient();
                            HttpPost httppost = new HttpPost("http://www.mstreetllc.com/Lab.asp");
                            try {
                                List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(
                                        2);
                                nameValuePairs.add(new BasicNameValuePair("id", "12345"));
                                nameValuePairs.add(new BasicNameValuePair("message", msg));
                                httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
                                httpclient.execute(httppost);
                                msgTextField.setText(""); // clear text box
                            } catch (ClientProtocolException e) {
                                // TODO Auto-generated catch block
                            } catch (IOException e) {
                                // TODO Auto-generated catch block
                            }

                        } else {
                            // display message if text fields are empty
                            Toast.makeText(getBaseContext(), "All field are required",
                                    Toast.LENGTH_SHORT).show();
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });

            thread.start(); 
        }
    });

}


}

I'm not sure if it is the thread or the sending of the data that is making it freeze. Any ideas?

Logcat:

05-28 09:45:32.325: W/System.err(32478): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
05-28 09:45:32.341: W/System.err(32478):    at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:5908)
05-28 09:45:32.341: W/System.err(32478):    at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:869)
05-28 09:45:32.341: W/System.err(32478):    at android.view.ViewGroup.invalidateChild(ViewGroup.java:4253)
05-28 09:45:32.341: W/System.err(32478):    at android.view.View.invalidate(View.java:10489)
05-28 09:45:32.341: W/System.err(32478):    at android.widget.TextView.invalidateRegion(TextView.java:4591)
05-28 09:45:32.341: W/System.err(32478):    at android.widget.TextView.invalidateCursor(TextView.java:4534)
05-28 09:45:32.341: W/System.err(32478):    at android.widget.TextView.spanChange(TextView.java:7412)
05-28 09:45:32.341: W/System.err(32478):    at android.widget.TextView$ChangeWatcher.onSpanAdded(TextView.java:9103)
05-28 09:45:32.341: W/System.err(32478):    at android.text.SpannableStringBuilder.sendSpanAdded(SpannableStringBuilder.java:979)
05-28 09:45:32.341: W/System.err(32478):    at android.text.SpannableStringBuilder.setSpan(SpannableStringBuilder.java:688)
05-28 09:45:32.341: W/System.err(32478):    at android.text.SpannableStringBuilder.setSpan(SpannableStringBuilder.java:588)
05-28 09:45:32.349: W/System.err(32478):    at android.text.Selection.setSelection(Selection.java:76)
05-28 09:45:32.349: W/System.err(32478):    at android.text.Selection.setSelection(Selection.java:87)
05-28 09:45:32.349: W/System.err(32478):    at android.text.method.ArrowKeyMovementMethod.initialize(ArrowKeyMovementMethod.java:302)
05-28 09:45:32.349: W/System.err(32478):    at android.widget.TextView.setText(TextView.java:3759)
05-28 09:45:32.349: W/System.err(32478):    at android.widget.TextView.setText(TextView.java:3629)
05-28 09:45:32.349: W/System.err(32478):    at android.widget.EditText.setText(EditText.java:80)
05-28 09:45:32.349: W/System.err(32478):    at android.widget.TextView.setText(TextView.java:3604)
05-28 09:45:32.349: W/System.err(32478):    at com.example.testphp.MainActivity$1$1.run(MainActivity.java:68)
05-28 09:45:32.349: W/System.err(32478):    at java.lang.Thread.run(Thread.java:841)
nick
  • 309
  • 1
  • 5
  • 15

5 Answers5

1

Only the UI thread can make changes to the UI. Any changes to views in your thread need to be done in runOnUIThread blocks or sent to the UI thread via a handler.

Gabe Sechan
  • 90,003
  • 9
  • 87
  • 127
1

The problem with your code is the

msgTextField.setText("");

As cited in the error message, you cannot access your view hierarchy from an alternative thread. Only the main UI thread can access it.

You might want to look into AsyncTask class which is exactly what you need for distant server access. You would then execute the code on the doInBackground() method and then modify the view onPostExecute().

0

The Problem is, that you are trying to update the UI-Thread from a Non-UI-Thread.

You could try as following (not tested):

public void onClick(View v) {
  new Thread(new Runnable() {
    public void run() {
      msgTextField.post(new Runnable() {  //<-- This instead of your setText();
        public void run() {
          mImageView.setText("");
        }
      });
    }
  }).start();
}

References:

Android Developers

Developers.Android.com

Update UI from Thread

How to set text of text view in another thread

Community
  • 1
  • 1
UeliDeSchwert
  • 1,146
  • 10
  • 23
0

You should create an AsyncTask and handle the HttpPost there.

public  class  Post extends AsyncTask<String, Void, Void> {

    private  Activity   callingActivity   =   null;

    public Post(Activity  paramActivity) {
        callingActivity    =    paramActivity;
    }

    protected Void doInBackground(String... msg) {
        if (msg[0].length() > 0) {
            HttpClient httpclient = new DefaultHttpClient();
            HttpPost httppost = new HttpPost("http://www.mstreetllc.com/Lab.asp");
            try {
                List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
                nameValuePairs.add(new BasicNameValuePair("id", "12345"));
                nameValuePairs.add(new BasicNameValuePair("message", msg[0]));
                httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
                httpclient.execute(httppost);
            } 
            catch (ClientProtocolException e) {
                // TODO Auto-generated catch block
            } 
            catch (IOException e) {
                // TODO Auto-generated catch block
            }
        }
    }

    protected void onPostExecute(Void result) {
        EditText  msgTextField  =  (EditText) callingActivity.findViewById(R.id.msgTextField); 
        msgTextField.setText("");      
    }
}

To call this AsyncTask, simply write:

new Post(this).execute(msg);

For more on AsyncTasks: http://developer.android.com/reference/android/os/AsyncTask.html

EdmDroid
  • 1,350
  • 1
  • 11
  • 25
-2

i think the problem in the HTTP request.

use another library for network request like Volley or httpSync

Muhamet Aljobairi
  • 1,627
  • 4
  • 19
  • 25