我有一个应用程序,允许用户在线玩游戏或在本地缓存它们。当他们将游戏转换为缓存时,我不希望他们失去进展。
在KitKat之前,您可以设置localstorage目录,但我需要更新的手机来支持此功能。
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
playingField.getSettings().setDatabasePath("/data/data/" + playingField.getContext().getPackageName() + "/databases/");
}
我无法找到替代方法。因此,以下是两个目录:
root@ghost:/data/data/com.myapp.android/app_webview/Local Storage #
ls -la
total 80
drwx------ 2 u0_a165 u0_a165 4096 2017-01-06 11:51 .
drwxrwx--x 4 u0_a165 u0_a165 4096 2017-01-06 11:41 ..
-rw------- 1 u0_a165 u0_a165 4096 2017-01-06 11:51 file__0.localstorage
-rw------- 1 u0_a165 u0_a165 0 2017-01-06 11:51 file__0.localstorage-journal
-rw------- 1 u0_a165 u0_a165 4096 2017-01-06 12:02 http_cdn.myapp.com_0.localstorage
-rw------- 1 u0_a165 u0_a165 0 2017-01-06 12:02 http_cdn.myapp.com_0.localstorage-journal
有没有人解决过这个问题?
我可能会尝试在活动的onPause()
期间同步文件,但我想知道是否有更优雅的解决方案 - 例如整合存储。
答案 0 :(得分:1)
感觉有点脏,但它有效(在KitKat
和更新){/ p>
下面的LocalStorageCopier
课程使用SharedPreferences
商店来跟踪商品(可以随意使用其他任何商品)。 之前,您加载网址(本地或远程),创建LocalStorageCopier
的实例并将其作为JavascriptInterface
添加到您的网络视图中:
webView.setWebViewClient(new WebClient());
storageBackup = new LocalStorageCopier(someContext, someId);
webView.addJavascriptInterface(storageBackup, "backup");
webView.loadUrl (someUrl);
注意:在加载页面之前添加javascript界面非常重要。我正在摸不着为什么“备份是未定义的”,直到我在加载url之前将这一点移动(我在执行备份之前添加它)。
现在您只需要绑定备份和还原操作。
备份:正如您上面提到的,onPause
方法是支持这些内容的好地方。在onPause
内的适当位置添加以下代码:
webView.evaluateJavascript(BACKUP_JAVASCRIPT, new ValueCallback<String>() {
@Override public void onReceiveValue(String s) {
LOG.d("Backed up.");
}
});
其中BACKUP_JAVASCRIPT
为"(function() { console.log('backing up'); backup.clear(); for (var key in localStorage) { backup.set(key, localStorage.getItem(key)); }})()"
现在,每当您的活动暂停时,您的localStorage
都会备份。
恢复以非常类似的方式完成。您需要在加载页面后启动还原操作。这是WebClient
类(下面的代码)的来源。页面加载完成后,您必须抓取LocalStorageCopier
实例中的所有项目并将其放入localStorage
。 RESTORE_JAVASCRIPT
的javascript是:"(function(){console.log('Restoring'); backup.dump(); var len = backup.size(); for (i = 0; i < len; i++) { var key = backup.key(i); console.log(key); localStorage.setItem(key, backup.get(key));}})()"
<强> LocalStorageCopier 强>
public static class LocalStorageCopier {
private final SharedPreferences store;
private String[] keys = null;
private String[] values = null;
private boolean dumped = false;
LocalStorageCopier(final Context context, final String id) {
store = context.getSharedPreferences(id, Context.MODE_PRIVATE);
}
@JavascriptInterface
public synchronized void dump() {
if (dumped) throw new IllegalStateException("already dumped");
final Map<String, ?> map = store.getAll();
final int size = map.size();
keys = new String[size];
values = new String[size];
int cur = 0;
for (final String key : map.keySet()) {
keys[cur] = key;
values[cur] = (String) map.get(key);
++cur;
}
dumped = true;
}
@JavascriptInterface
public synchronized int size() {
if (!dumped) throw new IllegalStateException("dump() first");
return keys.length;
}
@JavascriptInterface
public synchronized String key(final int i) {
if (!dumped) throw new IllegalStateException("dump() first");
return keys[i];
}
@JavascriptInterface
public synchronized String value(final int i) {
if (!dumped) throw new IllegalStateException("dump() first");
return values[i];
}
@JavascriptInterface
public synchronized String get(final String key) {
return store.getString(key, null);
}
@JavascriptInterface
public synchronized void set(final String key, final String value) {
if (dumped) throw new IllegalStateException("already dumped");
store.edit().putString(key, value).apply();
}
@JavascriptInterface
public synchronized void clear() {
store.edit().clear().apply();
keys = null;
values = null;
dumped = false;
}
@Override public synchronized String toString() {
return store.getAll().toString();
}
}
<强> Web客户端强>
class WebClient extends WebViewClient {
@Override public void onPageFinished(WebView view, String url) {
LOG.d("Page finished. Restoring storage.");
view.evaluateJavascript(RESTORE_JAVASCRIPT, new ValueCallback<String>() {
@Override public void onReceiveValue(String s) {
LOG.d("Restored.");
}
});
super.onPageFinished(view, url);
}
}
答案 1 :(得分:0)
也许使用符号链接,两个版本的webview都会使用相同的文件: