Java 如何在android中将侦听器放置在线程中
我有一个简单的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
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()的线程内创建处理程序