Search code examples
javaandroidandroid-asynctaskhttpwebrequest

Change text in textbox from webrequest ASYNCTASK Android Application


I am trying to update a textbox in the XML file of the Android application but don't know how to access it outside of the MainActivity Class. I am new to Android application and I have to work on a project for school in which the Android App will communicate with a Raspberry Pi via HttpRequest. I am trying to do a httpget request from the raspberry pi, and grab the values from the Pi and update it on the screen of the Android App. I just don't know how to update the textbox from another class. I am really confused =/ any help is appreciated. Thanks.

The variable HttpStuff is the textbox I am trying to update. When I press the button it should call the webrequest class and grab the response, and then on the postExecute() method I want it to update the textbox with the result.

Here is my code that I tried to implement:

public class MainActivity extends ActionBarActivity {

TextView HttpStuff;
Button refreshButton;
Button Connect;
EditText ipText;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    refreshButton = (Button)findViewById(R.id.refreshbutton);
    Connect = (Button)findViewById(R.id.connect);
    ipText = (EditText)findViewById(R.id.raspberryiptext);
    HttpStuff = (TextView) findViewById(R.id.datadisplay);



    Connect.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            try {
                Toast.makeText(MainActivity.this, "Connecting....", Toast.LENGTH_SHORT).show();
                RequestTask httpget = new RequestTask();
                httpget.execute("http://" + ipText.getText());
                //setContentView(R.layout.activity_main);
                //HttpStuff.setText(response);
            } catch (Exception d) {
                //Toast.makeText(MainActivity.this, "Failed!!", Toast.LENGTH_SHORT).show();
                //setContentView(R.layout.ip_configuration);
            }
        }
    });
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}

class RequestTask extends AsyncTask {

@Override
protected String doInBackground(String... uri) {
    HttpClient httpclient = new DefaultHttpClient();
    HttpResponse response;
    String responseString = "";
    try {
        response = httpclient.execute(new HttpGet(uri[0]));
        StatusLine statusLine = response.getStatusLine();
        if(statusLine.getStatusCode() == HttpStatus.SC_OK){
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            response.getEntity().writeTo(out);
            responseString = out.toString();
            out.close();
        } else{
            //Closes the connection.
            response.getEntity().getContent().close();
            throw new IOException(statusLine.getReasonPhrase());
        }
    } catch (ClientProtocolException e) {
        //TODO Handle problems..
    } catch (IOException e) {
        //TODO Handle problems..
    }
    return responseString;
}

@Override
protected void onPostExecute(String result) {

MainActivity test = new MainActivity();
    test.HttpStuff.setText(result);


}

Solution

  • When you create a new instance of the activity, you won't affect the real activity object (which is managed by the android system) as they're treated as 2 different objects by the virtual machine;

    Solution 1: Make the TextView public and static, then access it this way within the onPostExecute method:

    MainActivity.HttpStuff.setText(result)
    

    Solution 2: Add a Context object as field in the RequestTask class and as a parameter in the constructor like this:

    public class RequestTask extends AsyncTask...{
        private Context context;
        //.........
        public RequestTask(Context context){
            this.context = context;
        }
        //.........
        //Now in the onPostExecute, just use the Context object to grab the view
        public void onPostExecute(String result){
           TextView httpStuff = (TextView) context.findViewById(R.id.datadisplay);
           httpStuff.setText(result);
        }
    

    You can also pass the TextView directly as an argument instead of the Context object, however using Context would be better especially when you want to handle more than one view on your external task class.