I have created an application that uses twitter 4j i am trying to run on different threads to make it faster but i got that errors
08-03 16:02:02.138: E/AndroidRuntime(439): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
08-03 16:02:02.138: E/AndroidRuntime(439): at android.view.ViewRoot.checkThread(ViewRoot.java:2802)
08-03 16:02:02.138: E/AndroidRuntime(439): at android.view.ViewRoot.invalidateChild(ViewRoot.java:607)
08-03 16:02:02.138: E/AndroidRuntime(439): at android.view.ViewRoot.invalidateChildInParent(ViewRoot.java:633)
08-03 16:02:02.138: E/AndroidRuntime(439): at android.view.ViewGroup.invalidateChild(ViewGroup.java:2505)
08-03 16:02:02.138: E/AndroidRuntime(439): at android.view.View.invalidate(View.java:5139)
08-03 16:02:02.138: E/AndroidRuntime(439): at android.widget.AbsListView.resetList(AbsListView.java:1011)
08-03 16:02:02.138: E/AndroidRuntime(439): at android.widget.ListView.resetList(ListView.java:493)
08-03 16:02:02.138: E/AndroidRuntime(439): at android.widget.ListView.setAdapter(ListView.java:422)
08-03 16:02:02.138: E/AndroidRuntime(439): at android.app.ListActivity.setListAdapter(ListActivity.java:267)
08-03 16:02:02.138: E/AndroidRuntime(439): at a.a.a.StatusListActivity.loadHomeTimeline(StatusListActivity.java:91)
08-03 16:02:02.138: E/AndroidRuntime(439): at a.a.a.StatusListActivity.access$0(StatusListActivity.java:84)
08-03 16:02:02.138: E/AndroidRuntime(439): at a.a.a.StatusListActivity$2.run(StatusListActivity.java:78)
here it’s my code
public class StatusListActivity extends ListActivity{
private Otweet app;
private Twitter twitter;
private OAuthHelper authhelper;
private LoadMoreListItem headerView;
private LoadMoreListItem FooterView;
private StatusListAdapter adapter;
protected ProgressDialog progressdialog;
private Handler handler=new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
app=(Otweet)getApplication();
twitter=app.gettwitter();
System.setProperty("twitter4j.http.useSSL","false");
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.main);
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
if(!app.isAuthorized())
{
beginAuthorization();
}
else
{
if(null==getListAdapter())
loadHomeTimelineifnotloaded();
}
}
public void beginAuthorization()
{
Intent intent=new Intent(StatusListActivity.this,AuthorizationActivity.class);
startActivity(intent);
}
private void loadHomeTimelineifnotloaded() {
// TODO Auto-generated method stub
// progressdialog=ProgressDialog.show(StatusListActivity.this,"Load home timeline","loading");
Thread LoadHomeTimeline=new Thread(){
public void run()
{
loadHomeTimeline();
handler.post(FinishedLoadingTasks);
}
};
LoadHomeTimeline.start();
}
private void loadHomeTimeline()
{
try {
ArrayList<Status> status=twitter.getHomeTimeline();
adapter=new StatusListAdapter(this, status);
setListAdapter(adapter);
setloadMoreViews();
setListAdapter(adapter);
getListView().setSelection(1);
} catch (TwitterException e) {
// TODO Auto-genera ted catch block
e.printStackTrace();
Toast.makeText(getApplicationContext(), "jj", Toast.LENGTH_SHORT).show();
}
}
private Runnable FinishedLoadingTasks=new Runnable() {
public void run() {
// TODO Auto-generated method stub
finishedLoadinglist();
}
};
public void finishedLoadinglist()
{
setloadMoreViews();
setListAdapter(adapter);
getListView().setSelection(1);
// progressdialog.dismiss();
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
// TODO Auto-generated method stub
if(v.equals(headerView))
{
headerView.showProgress();
try {
headerView.showProgress();
loadnewerTweets();
} catch (TwitterException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else if
(v.equals(FooterView))
{
FooterView.showProgress();
try {
LoadOlderTweets();
} catch (TwitterException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private void LoadOlderTweets() throws TwitterException {
// TODO Auto-generated method stub
FooterView.hideProgress();
ArrayList<Status> statii=twitter.getHomeTimeline(new Paging().maxId(adapter.getLastId()));
adapter.appendOlder(statii);
}
private void loadnewerTweets() throws TwitterException {
// TODO Auto-generated method stub
//try {
headerView.showProgress();
setProgressBarIndeterminateVisibility(true);
Thread loadMoreThread=new Thread()
{
public void run()
{
try {
ArrayList<Status> statii = twitter.getHomeTimeline(new Paging().sinceId(adapter.getFirstId()));
Runnable finishedLoadingNewerTask=new LoadNewerResults(statii);
handler.post(finishedLoadingNewerTask);
} catch (TwitterException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
// }
// catch (TwitterException e) {
// TODO Auto-generated catch block
// throw new RuntimeException("Unable to load home timeline",e);
// }
}
protected void finishedLoadingNewer(ArrayList<Status> statii)
{
adapter.appendNewer(statii);
headerView.hideProgress();
setProgressBarIndeterminateVisibility(false);
getListView().setSelection(1);
}
private class LoadNewerResults implements Runnable
{
private ArrayList<Status> statii;
public LoadNewerResults(ArrayList<Status> statii)
{
super();
this.statii=statii;
}
public void run() {
// TODO Auto-generated method stub
finishedLoadingNewer(statii);
}
}
private void setloadMoreViews() {
// TODO Auto-generated method stub
headerView=(LoadMoreListItem)getLayoutInflater().inflate(R.layout.load_more, null);
headerView.showHeaderText();
FooterView=(LoadMoreListItem)getLayoutInflater().inflate(R.layout.load_more,null);
FooterView.showFooterText();
getListView().addHeaderView(headerView);
getListView().addFooterView(FooterView);
}
}
I have searched for these errors and i found that i have to run something on the main thread.can someone fix it and explain it to me ?Thanks very much
all Ui operations need to be done on UI thread so from other threads you can call runonUithread to update Ui elements from other threads.
But in your case I think you would be better off using Asynctask and update Ui elements in Onprogressupdate and OnpostExecute.