我将尝试将我的代码总结如下:
我希望看到我的GridView刷新3次,每次对notifyDataSetChanged()的调用都会刷新一次。
但是,我只看到它在步骤6之后刷新,当和从来没有看到Tile B变黄。
这里发生了什么事?我猜想有一些API是我不知道的。
谢谢
更新
即使在研究了下面描述的Handler方法之后,我仍然没有成功地实现这一点。因此,在我的UI线程中,我创建了一个新的GridOperationQueue类,它扩展自线程:
public class GridOperationQueue extends Thread {
private Handler handler;
@Override
public void run() {
Looper.prepare();
handler = new Handler();
Looper.loop();
}
public void addTaskToQueue(final GridUpdateTask task)
{
Log.d(this.getClass().toString(), "Current thread is ID " + Thread.currentThread().getId());
handler.post(new Runnable()
{
@Override
public void run() {
Log.d(this.getClass().toString(), " Handler task's current thread is ID " + Thread.currentThread().getId());
task.run();
}
});
}
public void clearQueue(){
handler.removeCallbacksAndMessages(null);
}}
因此,我的UI线程调用提供新任务对象的addTaskToQueue。其思想是,任务的处理将在一个单独的线程上执行,并在它完成之后在UI线程上调用一个notifyDataSetChanged()。但是,我已经添加了一些日志记录,当我的任务运行时,它们仍然在主thread....how上运行,这会是吗?请参见以下日志记录:
GridOperationQueue(4393): Current thread is ID 1
GridOperationQueue(4393): Current thread is ID 1
GridOperationQueue(4393): Current thread is ID 1
GridOperationQueue$1(4393): Handler task's current thread is ID 9
TileOperationService$1(4393): Current thread is ID 9
MyActivity(4393): Current thread is ID 9
GridOperationQueue$1(4393): Handler task's current thread is ID 9
TileOperationService$2(4393): Current thread is ID 9
MyActivity(4393): Current thread is ID 9
GridOperationQueue$1(4393): Handler task's current thread is ID 9
TileOperationService$3(4393): Current thread is ID 9
MyActivity(4393): Current thread is ID 9为什么任务仍然在主线程上运行?
发布于 2011-11-03 03:00:06
我假设您正在对onClick方法进行所有这些更改。onClick方法在UI线程中运行.因此,当onClick中的代码正在运行时,UI线程不能更改,并且因为它很忙,所以不能改变颜色。事实上,notifyDataSetChanged只是设置了一个标志,告诉Android随时更新对视图的更改;notifyDataSetChanged并不强制进行更新,但简单地告诉android是需要的。因此,您只需告诉android它需要更新视图三次.但是,当android能够实际进行更新时(这是在完成onClick方法之后),它只能看到最近对瓷砖颜色的更改。
你怎么才能避开这一切?这取决于你到底想做什么。例如,如果单击视图时希望瓷砖颜色A更改为瓷砖颜色B,然后在单击视图后更改为瓷砖颜色C 500 ms,请执行以下操作
Handler handler; // instance var
public onCreate(Bundle savedInstanceState) {
...
handler = new Handler();
}
// in your onClick method, wherever it may be (pseudocode)
public void onClick(View v) {
1) set tile color to color B
2) call notifyDataSetChanged
3) schedule a color change in 500 ms:
handler.postDelayed(new Runnable() {
public void run() {
1) set tile color to color C
2) call notifyDataSetChanged
}
}), 500);发布于 2011-11-03 00:19:53
你应该看看从计时器中更新UI。问题是,当您调用notifyDataSetChanged()时,您只会触发一个到GUI的标志。当适配器获得重绘时,它会检查是否设置了标志并采取了行动。当您调用通知时,它不会直接采取任何行动。
如果您想直接更新GUI,您应该了解类Handler (参见前面的链接),这样您就可以将更新发布到界面上。
发布于 2011-11-03 01:26:13
也许我误解了你的问题,但似乎你正在更新一倍于Tile B的颜色(问题的第3和第5步相同)。如果是这样的话,你只会看到最后的颜色(红色)和黄色永远不会显示,当然。
或者,在步骤5中,您的意思是"Tile C“。
即使UI更改了3次,您也可能会在每次调用中重写每个颜色。
1)所以你的三个瓷砖是‘默认’颜色
2)你把地砖A更新成绿色
3)调用notifyDataSetChanged()
(网格视图被正确更新)
4)将Tile B更新为黄色
5)调用notifyDataSetChanged()
(网格视图将标题B更新为黄色,但将标题A重写为“默认”颜色。
6)将Tile C更新为红色
7)调用notifyDataSetChanged()
(网格视图将标题C更新为红色,但将标题A和B重写为“默认”颜色。
这可能就是问题所在。
另外,请记住,正如其他人所提到的,notifyDataSetChanged()不直接做任何事情。它只在满足理想条件时发出刷新UI的信号。
https://stackoverflow.com/questions/7988819
复制相似问题