如何在android中的线程中放置一个监听器

时间:2014-07-08 14:52:26

标签: java android multithreading

我有一个简单的Android应用程序,其操作栏上有一个菜单。选择项目后,我调用函数startStreaming()。在该函数内部,我设置了twitter状态监听器,因此每当有新的推文发布时,我都会更改图形界面。那个程序以某种方式工作,但我得到一些警告:

android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

那是因为我在错误的线程中改变了gui。我尝试使用AsyncTask所有工作都在onPostExecute完成,但我再次收到同样的警告。

由于我需要一些延迟,这意味着我将每3秒更换一次gui,我认为我可以使用单独的Thread及其方法runOnUiThread,因此我可以使用Thread.sleep(3000)。这也可以解决我的警告。

我想获得一些帮助,以便在一个帖子中放置和修改startStreaming()的内容。

public class SearchTwitter extends Activity {
    private List<ExampleViewModel> viewModels;
    private ExampleViewModel myRow;
    private ExampleAdapter adapter;

    @Override
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.search);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()){
            case R.id.stream_tag:
                startStreaming();
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }   
    }

    private void startStreaming(){
        TwitterStream twitterstream = new TwitterStreamFactory().getInstance();

        twitter4j.StatusListener listener = new twitter4j.StatusListener() {
            @Override
            public void onStatus(twitter4j.Status status) { //new posts arrives 

                if(viewModels.size() > 1){
                    adapter.viewmodels().remove(viewModels.size() - 1);

                    String tweetText = status.getText();
                    myRow = new ExampleViewModel(tweetText);
                    viewModels.add(myRow);

                    adapter.notifyDataSetChanged(); // update UI 
                }
              }
        };

        FilterQuery filterQuery = new FilterQuery();
        String[] query = {"#WorldCup2014"};
        filterQuery.track(query);

        twitterstream.addListener(listener);
        twitterstream.filter(filterQuery); 
      }
  } 

3 个答案:

答案 0 :(得分:1)

如果没有人将View分配给变量,您可以使用

来更改UI
    (findViewById(android.R.id.content)).postDelayed(new Runnable() {
        @Override
        public void run() {
           //Put your change UI logic here
        }
    }, 3000);

(findViewById(android.R.id.content))是您使用的每项活动的根视图。

关于期刊活动,您可以在Best way to periodically executing AsyncTasks in Android

阅读

答案 1 :(得分:1)

只需使用Runnable和runOnUIThread即可。

runOnUiThread(new Runnable(){

    public void run() {
       //do something
    }

});

这将允许您从onStatus回调中的主线程更新UI,并应解决您的问题。

我甚至不担心3秒延迟。听起来像这个推特听众只是在新推文发布时更新。在这种情况下,为什么还要拖延?每次调用onStatus时都要更新。

答案 2 :(得分:0)

您通常不会在自己的线程上调用侦听器。在您注册监听器的线程上调用它们。