繁体   English   中英

如何在Android的线程中放置侦听器

[英]How to place a listener in a thread in android

我有一个简单的Android应用程序,其操作栏上有一个菜单。 选择该项目后,我将调用函数startStreaming() 在该函数中,我设置了twitter状态侦听器,因此,每当有新的tweet出现时,我都会更改图形界面。 程序可以正常运行,但是我得到一些警告,例如:

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); 
      }
  } 

要在没有一个视图分配给变量的情况下更改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))是您使用的每个活动的根视图。

关于定期事件,您可能会以最佳方式阅读,可以在Android中定期执行AsyncTasks

只需使用Runnable和runOnUIThread。

runOnUiThread(new Runnable(){

    public void run() {
       //do something
    }

});

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

我什至不用担心3秒的延迟。 在我看来,这条Tweet监听器仅在有新Tweet出现时才更新。在这种情况下,为什么还要打扰一下? 每次调用onStatus时都进行更新。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM