Android:notifyDataSetChanged()在更改方向后没有更新listview

问题描述:

我有一个半复杂的问题,希望这里的某个人能够帮助我。Android:notifyDataSetChanged()在更改方向后没有更新listview

在点击事件中,我创建了一个线程并基于this方法开始了一个长时间运行的操作。在长时间运行的任务完成后,它会回调到另一种方法,它不后的处理程序:

@Override 
public void contentSearchModelChanged(Model_ContentSearch csm, ArrayList<Class_Reminder> newRemindersList) { 
    remindersList = newRemindersList; 
    mHandler.post(mUpdateDisplayRunnable); 
} 

其中要求一个Runnable:最后

// post this to the Handler when the background thread completes 
private final Runnable mUpdateDisplayRunnable = new Runnable() { 
    public void run() { 
    updateDisplay(); 
    } 
}; 

,这里是我的updateDisplay()方法是这样做的:

private void updateDisplay() { 
    if (csModel.getState() != Model_ContentSearch.State.RUNNING) { 
     if(remindersList != null && remindersList.size() > 0){ 
       r_adapter = new ReminderAdapater(Activity_ContentSearch.this, remindersList, thisListView); 
       thisListView.setAdapter(r_adapter); 
       r_adapter.notifyDataSetChanged(); 
     } 
    } 
} 

当我正常这样做时,它会很好用。但是,如果我在长时间运行的运行时更改方向,则不起作用。它确实使回调正确,而且remindersList确实有其中的项目。但是当它到达这条线时:

r_adapter.notifyDataSetChanged(); 

没有任何反应。奇怪的是,如果我再做一次提交并让它再次运行整个过程(不改变方向),它实际上会更新视图两次,一次用于上一次提交,另一次用于下一次提交。因此,该视图会随着第一次提交的结果更新一次,然后再次提交第二次提交的结果。所以adapater DID获取数据,它不会刷新视图。

我知道这与方向改变有关,但我不能为了我的生活找出原因。谁能帮忙?或者,任何人都可以提出一种处理方向变化的线程的替代方法?

巴拉

的问题是,当你改变方向的新活动从一开始(的onCreate)纺起来。您长时间运行的流程可以处理旧的(不再可见的)活动。您正在更新旧活动,但由于它不在屏幕上,因此您不会看到它。

这不是一个容易解决的问题。有一个图书馆可以帮助你。它被称为DroidFu。这里是一个博客贴子,(比我更准确地)描述你所看到的和DroidFu库如何阻止它的根本原因:http://brainflush.wordpress.com/2009/11/16/introducing-droid-fu-for-android-betteractivity-betterservice-and-betterasynctask/

编辑:(用于跟踪活动的活动添加代码)

在您的应用程序类补充一点:

private Activity _activeActivity; 
public void setActiveActivity(Activity activity) { 
    _activeActivity = activity; 
} 
public Activity getActiveActivity() { 
    return _activeActivity; 
} 

你们的活动,补充一点:

@Override 
public void onResume() { 
    super.onResume(); 
    ((MyApplicationClassName)getApplication()).setActiveActivity(this); 
} 

现在你可以得到有效活性状况通过调用MyApplicationClassName.getActiveActivity();

这不是DroidFu如何做到的。 DroidFu在onCreate中设置活动活动,但我不觉得这是非常健壮的。

+0

嗯......这似乎很有帮助,但似乎没有很多文件?我讨厌将我的实现改为使用DroidFu,而不知道如何解决问题,因为它不是“典型”的做事方式。 – Bara 2010-06-21 06:13:03

+0

是的,它似乎是一个旧的废弃图书馆,但前提似乎很好。你可以做到这一点,而不使用库。基本上,Application对象跟踪活动Activity(使用onResume)。然后,当您准备好通知您的适配器时,您将从应用程序中获得活动的Activity,检查它是否是您期望的活动的实例,如果是,则进行投射并通知。 – 2010-06-21 13:53:57

+0

跟踪“活动活动”的代码究竟是什么?也就是说,我应该做一些像CurrentActivity act = new CurrentActivity();然后将行为传递给Application类? – Bara 2010-06-23 02:38:52

我有一个类似的问题,有一个耗时的线程sendEmptyMessage到一个处理程序,它又在ListAdapter上调用notifyDataSetChanged。它工作得很好,直到我改变方向。

我解决了它通过在UI线程中声明第二个处理程序,并将第一个处理程序sendEmptyMessage创建到此处理程序,该处理程序又在ListAdapter上调用notifyDataSetChanged。将ListAdapter声明为静态。

我是个新手,所以我不知道这是否是一个丑陋的解决方案,但它的工作对我来说...

从Jere.Jones描述我会承担这个工作原理:在长期运行过程sendEmptyMessage从旧Activity发送到句柄,而后者又将EmulateMessage发送到新Activity中的句柄。