Project: titanium
Issue TIMOB-17798: Android: App crashes in TiResponseCache.peek()
My app is crashing when I use Google Play Services to deliver doubleclick ads. {code:title=console output|borderStyle=solid} [ERROR] : TiDownloadManager: (pool-4-thread-1) [18,3778] Exception downloading http://wwwcache.wral.com/asset/news/local/2014/09/26/14018104/14018104-1411727089-320x180.jpg [ERROR] : TiDownloadManager: java.lang.ClassCastException: com.android.okhttp.HttpResponseCache cannot be cast to org.appcelerator.titanium.util.TiResponseCache [ERROR] : TiDownloadManager: org.appcelerator.titanium.util.TiResponseCache.peek(TiResponseCache.java:187) [ERROR] : TiDownloadManager: ti.modules.titanium.ui.widget.TiUIImageView$1.postDownload(TiUIImageView.java:119) [ERROR] : TiDownloadManager: org.appcelerator.titanium.util.TiDownloadManager$DownloadJob.run(TiDownloadManager.java:151) [ERROR] : TiDownloadManager: java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) [ERROR] : TiDownloadManager: java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) [ERROR] : TiDownloadManager: java.lang.Thread.run(Thread.java:841) [DEBUG] : dalvikvm: DexOpt: --- END 'ads646200884.jar' (success) --- {code} (the URL listed in the output is an image that I am loading into an ImageView, so I inferred that the TiDownloadManager is handling the loading of ImageView images) The problem only goes away if I disable DFP ads (I'm using my own ti.dfp module - https://github.com/jpriebe/ti.dfp). I found it strange that it was crashing, because this code was working just a few days ago, and the module had not been changed, nor had I really done anything to the app and the way it handles ImageViews. I scoured android source code, tweets, and forum posts, and I've learned that in android 4.4, Square's okhttp code is supposedly incorporated into HttpUrlConnection. However, I've never found any code for com.android.okhttp.HttpResponseCache. The only code I can find is for com.squareup.okhttp.HttpResponseCache, not "com.android". com.squareup.okhttp.HttpResponseCache extends java.net.ResponseCache, just like TiResponseCache does. But the code in TiResponseCache.peek() is only expecting to get back a TiResponseCache object when it calls getDefault(). Changing that might not be trivial, since it depends on the cacheDir member variable of the returned object, and that's not part of the java.net.ResponseCache class. Here's what I think has happened -- google released Google Play Services 6.1.09 on September 23, 2014. It automatically updated on my device. Inside the new Google Play Services is a call to ResponseCache.setDefault(), and they're setting that default to a com.android.okhttp.HttpResponseCache object. Titanium assumes that the default system ResponseCache is the one that it set in TiApplication.java, and it doesn't handle things well when somebody else messes with the default. I don't know what the fix is for this -- I'll leave that to the android platform experts in your employ. But I think it is a critical issue, and will become more obvious in the coming days as this Play Services update propagates. Any app that is using Google Play Services (or at least the DFP portion of it) and the TiDownloadManager will crash.
Story points: 5