0

I'm trying to implement a thread on a function that starts an HttpClient because it's recomended according to d.android.com So I have implemented a thread but, it doesn't seem to run as if I remove the thread code I see results.

This is my code:

@Override
public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.chat_box);// sd
    TextView inbox = (TextView) findViewById(R.id.inbox);
    final Functions function = new Functions();
    final SharedPreferences prefs = PreferenceManager
            .getDefaultSharedPreferences(getBaseContext());
    where = prefs.getString("chat", "null");

    class SendThread extends Thread {
           public void run(){
                //getInbox() runs an http client
               listOfMessages = function.getInbox(where);

           }
        }
    SendThread sendThread  = new SendThread();
    sendThread.start();

    inbox.setText(listOfMessages);

}

Like I said above, if I remove my thread code, then it works perfectly. Any ideas on what I'm doing wrong? This is my first time using threads, sorry for any rookie mistakes.

I don't get any errors (at least I don't see any) but, I don't see the output that I get without the thread code inserted.

2
  • 1
    Don't (try to) alter the UI from a thread that isn't the UI thread. Also, inbox.setText(listOfMessages) is probably executed before listOfMessages = function.getInbox(where);. Commented Apr 25, 2012 at 0:36
  • How could it execute before? How should I go about altering the UI, I'm trying my best not to touch any of the views. Commented Apr 25, 2012 at 0:43

2 Answers 2

2

I agree with the others: 1) you didn't allow time for the thread to finish, and 2) you must modify the UI on the main thread. I figured you might want to see a concrete solution, so here you go:

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

    final Functions function = new Functions();
    final SharedPreferences prefs = PreferenceManager
            .getDefaultSharedPreferences(getBaseContext());
    where = prefs.getString("chat", "null");
    new AsyncTask<String, Void, String>() {
        @Override
        protected String doInBackground(String... args) {
            return function.getInbox(args[0]);
        }

        @Override
        protected void onPostExecute(String result) {
            TextView inbox = (TextView) findViewById(R.id.inbox);
            inbox.setText(result);
        }

    }.execute(where);
}

The use of AsyncTask makes this super simple: it's the Android-recommended way to do simple tasks off the main thread. When execute() is called, a new thread is created and it calls doInBackground(). Then the result is returned on the main thread to the onPostExecute method. So you don't have to deal with runOnUiThread or anything else.

One thing to be aware of in this case: in the case of something like an orientation change, your Activity will be destroyed and recreated, and so the call getInbox() will be called again. This may or may not be a problem, depending on how long the method actually takes. If it's unacceptable, you need something like a static AsyncTask, but then you run into the problem of attaching back to the new Activity. I'm just mentioning that, not because you have to handle it right now, but just so you're aware.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks. Your entire explanation and code was very helpful. I just have one last question. How would I go about about running this thread over and over?
You need to create a new AsyncTask every time. If you want to do this many times, AsyncTask is probably not the best approach. For client-server communication, I like to use IntentService.
0

You got the result of listOfMessages from the thread, but you didn't post that list to your inbox TextView. The thread may take a while to be completely executed, but the code

inbox.setText(listOfMessages);

in the bottom will be executed once the thread is started.

So, you need to call inbox.setText(listOfMessages); once your thread got the latest listOfMessages. BUT, you can not do any UI operation(like setText) in a non-ui thread.

There are many choices: 1.You can use handler class, in your thread code, when you got the listOfMessages, you can use a handler and post a message to your UI thread. You can google handler for samples.

  1. If the code above is in your activity, you can use a helper method call runOnUiThread in activity. which is something like.

    MyActivity.this.runOnUiThread(new Runnable() { inbox.setText(listOfMessages); });

Hope this will help you.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.