I've got a Xamarin Android project, using a shared PCL library, and I decided to use Akavache as a temporary data store (to store some simple login state info, to save relogging in every time).
So I added the Akavache and Akavache.Sqlite3 nuget packages to the Shared Library (and to the Xamarin.Android project). I set the BlobCache.ApplicationName
, even called EnsureInitialized
(tho that doesn't seem to do more than log a message).
I deployed the app to the device. Launched it manually (so there's no wiping of data and preferences etc.). Data is cached (and retrieved) as long as the app is running. It throws exceptions (as expected) if keys are missing. All works perfectly.
Then I shut the app down (at one stage I even rebooted the phone). When I relaunched it, the cache is either empty, or reinitialised. Either way, everything I cached is gone.
I had a look in the debugger at where the caching sqlite3 files are stored, and the app tells me they're apparently at data/data/packagename/cache/xyzblobs.db
. I cannot see those files, because they're in an internal system cache/app files directory, so I have no idea whether they're being wiped or not.
I've turned on the WRITE_EXTERNAL_STORAGE (and READ_) permissions. No dice. I've tried using Secure
, UserAccount
and LocalMachine
targets. Nada. None of them work.
As long as the app is running (or in memory) it behaves as expected. The moment the app goes away, so does the cache.
The only thing I haven't done is call the BlobStorage.Shutdown()
method. And that's because I don't know where to call it. I have multiple activities and don't want to be reference counting because stupid.
Edit: Later I forced a call to .Shutdown().Wait()
and that didn't seem to help either.
Has anyone else experienced this? I know of at least one other person who is having exactly the same problem, detailed in over here in the Xamarin forums.
I really don't want to have to pull all the Akavache stuff out, because I've used it before, elsewhere on not-Xamarin-Android, and it's awesome. Otherwise I'll have to start looking at some sort of xplat shared preferences manager, which I'd rather not do because Akavache is supposed to do Just That.
Edit: Here's some of the code:
Initialisation (I have a static shared "AppGlobal" class that I use to keep the singleton type stuff)
public static class SharedAppGlobal
{
static SharedAppGlobal()
{
BlobCache.ApplicationName = SharedAppConstants.SharedAkavacheCacheName;
BlobCache.EnsureInitialized();
}
}
That all works fine, if I fire it up in the debugger and have a look at BlobCache
it tells me I'm using the Sqlite3 storage and the path to it (tho the sqlite3 .db files are not accessible to me on a non-rooted device)
I can invoke the cache get/set with things like
currentCookie = await BlobCache.LocalMachine.GetObject<Cookie>("authCookie");
and write them back with
await BlobCache.LocalMachine.InsertObject("authCookie", cookie);
All Akavache calls are being made in the shared library. And it doesn't matter which store I use (Secure, UserAccount or LocalMachine), the behaviour is the same.
All works perfectly. Then I exit the app. Reopen the app (I can reboot the phone to make sure it's gone), and the cache is empty. Or reset. Or made anew. I don't know which because I can't see the .db files.
I am NOT running under a debugger and redeploying every time. So deployment directories aren't getting clobbered. This happens even when I install an apk. I think it probably has something to do with those db files not being where it says they are, but I'm at a complete loss.
Do I need to implement something at platform-specific level and pass it down to the shared library? I don't think so, because all the dependencies and paths seem to be resolved.
I've wasted hours on this.
Thanks :)