-3

I'm having some trouble trying to update automaticaly a view in my android activity. The application display some message like a chat. Im using a ListView to put the message with a ArrayAdapter.

I use this metod to update the ListView

public void loadMessages() {
ArrayList<String> messages = this.dbHelper.getMessages();
conversationArrayAdapter.clear();
conversationArrayAdapter.addAll(messages);
conversationArrayAdapter.notifyDataSetChanged();
}

My idea is to put a thread that call that metod, but when i try to do this i have the following error.

Only the original thread that created a view hierarchy can touch its view.

user2121530
  • 107
  • 1
  • 4
  • 8

4 Answers4

1

because you are trying to access or update UI elements from Thread . to avoid this error you will meed to use runOnUiThread for updating UI from Thread as :

Your_Current_Activity.this.runOnUiThread(new Runnable() {

  @Override
    public void run() {

        // Update UI here    
        loadMessages();                             
    }
});

and second solution is use AsyncTask instead of thread

ρяσѕρєя K
  • 132,198
  • 53
  • 198
  • 213
1

Use this code.

public class MainActivity extends Activity
{
    private Timer autoUpdate;

    @Override
     public void onResume()
     {
        super.onResume();
        autoUpdate = new Timer();
        autoUpdate.schedule(new TimerTask()
        {
            @Override
            public void run()
            {
                runOnUiThread(new Runnable()
                {
                    public void run()
                    {
                        updateScore();
                    }
                });
            }
        }, 0, 5000); // updates each 5 seconds
     }


     @Override
     public void onPause()
     {
         autoUpdate.cancel();
         super.onPause();
     }

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        // initialize view layout
        super.onCreate(savedInstanceState);
        setContentView(R.layout.cleanermain);
        super.onResume();
    }


        private void updateScore()
        {
            // decide output
            // update cricket score
        }
}
Manish Dubey
  • 4,206
  • 8
  • 36
  • 65
0

UI should be updated only from the UI (Main) thread. Here is a solution using AsyncTask.

public void asyncCallWithSchedule() {
        final Handler handler = new Handler();
        Timer timer = new Timer();
        TimerTask doAsynchronousTask = new TimerTask() {
            @Override
            public void run() {
                handler.post(new Runnable() {
                        public void run() {
                            try {
                                new SearchAsync().execute(txtSearch.getText().toString());
                            }
                        });
                }
            };
            timer.schedule(doAsynchronousTask, 0, 2000);
        }
}

AsyncTask class:

private class SearchAsync extends
AsyncTask < String, Object, List < Users >> {

    @Override
    protected List < Users > doInBackground(String...params) {
        // Call DB here   
        return null;
    }

    @Override
    protected void onPostExecute(List < Users > result) {
        super.onPostExecute(result);
        // Update UI here
    }
}
Haris
  • 4,130
  • 3
  • 30
  • 47
0

Simple:

public void loadMessages() {
    ArrayList<String> messages = this.dbHelper.getMessages();
    conversationArrayAdapter.clear();
    conversationArrayAdapter.addAll(messages);

    new Handler(Looper.getMainLooper()).post(new Runnable() {
        public void run() {
            conversationArrayAdapter.notifyDataSetChanged();
        }
    });
}
M-Wajeeh
  • 17,204
  • 10
  • 66
  • 103