经过一个多月的研究,我得出结论,在文件位于localhost(直接从assets文件夹中读取)的webview中,无法在高于2.3的android版本中设置cookie。
我经历了使用cookie存储的多种选择,包括使用HTML的localstorage。我被认为可以相信,这里的整个问题都是安全性。如果要在本地主机上创建cookie或localstorage,则其他应用程序可以访问该存储,因此是主要的安全威胁。
我的最终问题是尝试通过Java与Java的双向通信来桥接Webview,并且在此过程中还需要存储数据。我的解决方案是利用
JavascriptInterface
这个想法如下:
- 解析数据以在javascript中起作用
- Javascript调用特殊的Javascript函数,例如“ setData(myDataName,myData)”
- Java有一个侦听此函数的函数,它将接受javscript设置的参数,并且还可以将值返回给javascript。
- 将数据解析为Java之后,java会将其存储在资产中的一系列文件中。
- 当调用javascript函数“ getData(myDataName)”时,Java用相同的方法返回数据。
我发现这非常有用:Android JavascriptInterface
文档,在Android
2.3中处理JavascriptInterface
我发现的唯一主要“问题”是Android
2.3(已在3.0中修复)中一个相当严重的错误,该错误有效地破坏了JavascriptInterface。上面的第二个链接描述了我发现的最佳解决方法。
这是一个如何使双向通信正常工作的示例(虽然很杂乱,但是可以工作):
自定义网络界面类:
public class webViewInterface { //@JavascriptInterface //for SDK 12+ public String showToast(String myText) { Toast.makeText(context, myText, Toast.LENGTH_LONG).show(); return myText; } }主类:受保护的void onCreate(Bundle
savedInstanceState){super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);engine = (WebView) findViewById(R.id.web_engine);context = this;WebSettings webSettings = engine.getSettings();webSettings.setJavascriptEnabled(true);engine.setWebViewClient(new WebViewClient());engine.loadUrl("file:///android_asset/" + page);boolean javascriptInterfaceBroken = false;try { if (Build.VERSION.RELEASE.startsWith("2.3")) { javascriptInterfaceBroken = true; } } catch (Exception e) { // Ignore, and assume user javascript interface is working correctly. }// Add javascript interface only if it's not broken // @TODO: write the workaround for < 2.3 devicesif (!javascriptInterfaceBroken) { engine.addJavascriptInterface(new webViewInterface(), "MainActivityInterface");}//disables text selectionengine.setonLongClickListener(new View.onLongClickListener() { public boolean onLongClick(View v) { return true; }}); }HTML:
<html><head></head><body><input type="button" value="Say hello" onClick="showAndroidToast();" /><script type="text/javascript"> function showAndroidToast() { document.write(MainActivityInterface.showToast("eureka!")); }</script></body></html>


