From fd119e986d531345c2df3022ea9d968bb7fd3858 Mon Sep 17 00:00:00 2001 From: Dmitri Plotnikov Date: Mon, 17 Jan 2011 09:46:23 -0800 Subject: [PATCH] Delivering null cursor to loader callbacks. ContentProviders are allowed to return null and both of our contact directories (Focus and Exchange) actually do when they find no data to return. The problem is that when LoaderManager receives a result from a loader, it checks if the result is the same as previously received. That's fine, as long as the loader always returns a different result. Now consider a loader that returns null when it cannot produce the result. What we are seeing is that if the loader is rapidly restared and returns null twice in a row, the null is never delivered to the callbacks. In the case of the reported bug, the scenario is this: 1. We look for "foo" 2. Data for "foo" comes from a directory and we display it 3. We hit backspace twice in rapid succession. Each time we hit backspace, the loader is restared, but since we do this very fast, the second restart overrides the first. So far so good. 4. The directories are programmed to return null if the query string is less than 3 characters long, so the loader returns null twice. 5. Loader manager looks at the final result, compares it to the previous result and since they are the same (both null) concludes that it does not need to deliver either of them. 6. The UI attempts to show the stale data and blows up Bug: 3352125 Change-Id: I3e5bc505faa03f72ebe5cb010377a740f5c7d5b6 --- core/java/android/app/LoaderManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/java/android/app/LoaderManager.java b/core/java/android/app/LoaderManager.java index 5f8c0984982d1..1ef011c31646f 100644 --- a/core/java/android/app/LoaderManager.java +++ b/core/java/android/app/LoaderManager.java @@ -353,7 +353,7 @@ class LoaderManagerImpl extends LoaderManager { // Notify of the new data so the app can switch out the old data before // we try to destroy it. - if (mData != data) { + if (data == null || mData != data) { mData = data; if (mStarted) { callOnLoadFinished(loader, data);