droid-fu
droid-fu copied to clipboard
NullPointerException when using disk cache and expiration time for url is reached
First, the Stack Trace :
09-06 20:00:46.842: DEBUG/HttpCache(736): MEM cache hit for http://oscope.org/t/time.php 09-06 20:00:50.272: DEBUG/HttpCache(736): DISK cache expiration for file /data/data/org.foo/cache/cachefu/http_cache/http+oscope+org+t+time+php 09-06 20:00:54.273: WARN/System.err(736): java.lang.NullPointerException 09-06 20:00:54.283: WARN/System.err(736): at com.github.ignition.support.http.cache.CachedHttpResponse$ResponseData.access$0(CachedHttpResponse.java:25) 09-06 20:00:54.293: WARN/System.err(736): at com.github.ignition.support.http.cache.CachedHttpResponse.getResponseBodyAsString(CachedHttpResponse.java:55) 09-06 20:00:54.293: WARN/System.err(736): at org.foo.AndroidTestingActivity$GetTime.doInBackground(AndroidTestingActivity.java:46)
Scenario:
- Use BetterHttp or IgniteHttp to get a cacheable time string from "http://oscope.org/t/time.php"
- Set the expiry time to something short like 1 minute
- Wait for expiry time to elapse and make the same call again.
- Watch for nullpointerexception
- Making the same call again gets the time from the url correctly (only after the NPE in step four occurs).
Code Samples
The Activity :
public class AndroidTestingActivity extends Activity
@Override
protected void onCreate(Bundle savedInstanceState) {
BetterHttp.setContext(this);
// one minute expiry time
BetterHttp.enableResponseCache(this, 25, 1L, 1, AbstractCache.DISK_CACHE_INTERNAL);
BetterHttp.setupHttpClient();
ImageLoader.initialize(this);
ImageLoader.setMaxDownloadAttempts(2);
setContentView(R.layout.droidfu);
super.onCreate(savedInstanceState);
findViewById(R.id.go).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
new GetTimeAsyncTask().execute();
}
});
new GetTimeAsyncTask().execute();
}
private class GetTimeAsyncTask extends AsyncTask<Void, Void, String>{
@Override
protected String doInBackground(Void... params) {
try {
String url = "http://oscope.org/t/time.php";
BetterHttpRequest request = BetterHttp.get(url, true);
BetterHttpResponse resp = request.send();
String time = resp.getResponseBodyAsString();
return time;
} catch (ConnectException ex) {
} catch (Exception ex) {
ex.printStackTrace();
Log.e("org.foo", "doInBackground:");
Log.e("org.foo", "UNCAUGHT: " + ex.getClass().getName () + ": " + ex.getMessage());
Log.e("org.foo", "UNCAUGHT:" + ex.getMessage());
Log.e("org.foo", "UNCAUGHT:" + "ex" , ex);
}
return null;
}
@Override
protected void onPostExecute(String result) {
Log.w("org.foo", "result = " + result);
TextView txt = (TextView) findViewById(R.id.text);
if (txt != null && result!=null){
txt.setText(result);
}
}
}
XML file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:id="@+id/text" android:layout_height="wrap_content"
android:layout_width="wrap_content" />
<Button android:id="@+id/go" android:text="go"
android:layout_height="wrap_content" android:layout_width="wrap_content" />
</LinearLayout>
Some other Notes
- This doesnt occur if disk cache is not enabled.
- This occurs on a few devices I have (HTC Thunderbolt, Droid X, Galaxy Tab IO, and the emulator)
- I'm still starting to learn GIT and MAVEN. Otherwise, I'd prolly have a fix.
Thanks! Will look into it
Did some more experimenting with Droidfu library and found a possible clue for root cause.
If you check that the responseCache has that particular key(url) the npe never gets thrown.
So I guess you have to request the same resource over and over and over until the cache time expires for this to happen. Thinking about it this might be an edge case for more natural uses.
Some more example code related to above:
protected String doInBackground(Void... params) {
try {
String url = "http://oscope.org/t/time.php";
HttpResponseCache responseCache = BetterHttp.getResponseCache();
if (responseCache != null){
ResponseData cachedData = responseCache.get(url);
String log = "IN cache ";
if (cachedData == null ){
log = "MISSING";
}
Log.d("org.foo", log);
}
BetterHttpRequest request = BetterHttp.get(url, true);
BetterHttpResponse resp = request.send();
String time = resp.getResponseBodyAsString();
return time;
} catch (ConnectException ex) {
} catch (Exception ex) {
ex.printStackTrace();
Log.e("org.foo", "doInBackground:");
Log.e("org.foo", "UNCAUGHT: " + ex.getClass().getName() + ": "
+ ex.getMessage());
Log.e("org.foo", "UNCAUGHT:" + ex.getMessage());
Log.e("org.foo", "UNCAUGHT:" + "ex", ex);
}
}
I'll try to see if this is the same case for IgniteHttp as well tommorrow.