Java 如何在android中将侦听器放置在线程中

Java 如何在android中将侦听器放置在线程中,java,android,multithreading,Java,Android,Multithreading,我有一个简单的android应用程序,它的操作栏上有一个菜单。选择项目后,我调用函数startStreaming()。在该函数中,我设置了twitter状态监听器,因此每当有新tweet出现时,我都会更改图形界面。这个程序不知怎么起作用了,但我得到了一些警告,比如: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can

我有一个简单的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,所以我想我可以使用一个单独的
线程及其方法
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); 
      }
  } 
公共类SearchTwitter扩展活动{
私有列表视图模型;
private ExampleViewModel myRow;
专用适配器;
@凌驾
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.search);
}
@凌驾
公共布尔值onOptionsItemSelected(菜单项项){
开关(item.getItemId()){
案例R.id.stream_标签:
startStreaming();
返回true;
违约:
返回super.onOptionsItemSelected(项目);
}   
}
私有void startStreaming(){
TwitterStream TwitterStream=新建TwitterStreamFactory().getInstance();
twitter4j.StatusListener侦听器=新twitter4j.StatusListener(){
@凌驾
public void onStatus(twitter4j.Status状态){//新帖子到达
如果(viewModels.size()>1){
adapter.viewmodels().remove(viewmodels.size()-1);
字符串tweetText=status.getText();
myRow=新的ExampleViewModel(tweetText);
viewModels.add(myRow);
adapter.notifyDataSetChanged();//更新UI
}
}
};
FilterQuery FilterQuery=新建FilterQuery();
字符串[]查询={“#WorldCup2014”};
filterQuery.track(查询);
twitterstream.addListener(listener);
过滤器(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))
是您使用的每个活动的根视图


关于定期事件,您可能会在

上看到,只需使用
Runnable和rununuithread即可

runOnUiThread(new Runnable(){

    public void run() {
       //do something
    }

});
这将允许您从onStatus回调中的主线程更新UI,并应修复您的问题


我甚至不担心3秒的延迟。在我看来,这个tweet侦听器只是在收到新tweet时更新。既然如此,为什么还要耽搁呢?只要在每次有东西调用onStatus时更新

只需在UI Stuff中发布runnable,你是说在
onClick
方法中吗?侦听器呢,我应该在
run
方法中设置它吗?不-run方法是你想要在UI线程上运行的方法。这只是更新ListView的部分。您可以将其添加到侦听器回调中,然后将通知适配器更改的部分放在run中。但是那个听众呢,我应该把它放在哪里呢?对不起,我不明白。侦听器是否工作不正常?怎么了?是的,它在工作。我按照您的建议做了,但出现了一些错误
无法在未调用looper.prepare()的线程内创建处理程序