【问题标题】:Marmalade Core Storage (s3eSecureStoragePut & s3eSecureStorageGet) not persisting果酱核心存储 (s3eSecureStoragePut & s3eSecureStorageGet) 不持久
【发布时间】:2016-05-12 10:26:30
【问题描述】:

我有一个使用 Marmalade Core 制作的最小应用程序。它创建一个 web 视图,然后使用 s3eSecureStoragePut 和 s3eSecureStorageGet 发送要存储和检索的数据。

在我关闭应用程序并重新打开它之前,这一切正常。再次加载后,我尝试加载它返回为空白的数据。有谁知道为什么会发生这种情况?它是使用 GCC ARM Debug for Android 构建/部署的

这是我的 C++

#include "s3e.h"
#include "s3eDevice.h"
#include "IwDebug.h"
#include "s3eWebView.h"
#include "IwGx.h"
#include "Iw2D.h"
#include <string>
#include <sstream>

s3eWebView* webView;
bool pageLoaded;
const char* rom = "rom://index.html";

struct SStoreData {
    std::string key;
};

static int loadedCallback(s3eWebView* instance, void* sysData, void* userData) {
    pageLoaded = true;
    return 1;
}

static int javaScriptCallback(s3eWebView* instance, void* systemData, void* userData) {
//cast the data to string for easier handling
std::string data = (char*) systemData;
char jsFunc[128];
//check if page has loaded to prevent errors
if (pageLoaded) {
    if (!std::strncmp(data.c_str(), "saveKey", std::strlen("saveKey")))  {
        std::string key = data.substr(data.find("|") + 1, data.length());
        SStoreData *toSave = new SStoreData;
        toSave->key = key;
        s3eSecureStoragePut (toSave, sizeof (*toSave));
    } else if ("loadKey" == data) {
        SStoreData *toLoad = new SStoreData;
        s3eSecureStorageGet (toLoad,sizeof(*toLoad));
        sprintf(jsFunc, "dataLoaded(\"%s\", \"key\");", toLoad->key.c_str());
        s3eWebViewSendJavaScript(webView, jsFunc);
    } else {

        IwTrace(JS_CALLBACK, ("DID NOT RECEIVE ANYTHING"));
    }
}
return 1;
}


void init() {
//init vars
webView = s3eWebViewCreate(false);
pageLoaded = false;

//register callbacks
s3eWebViewRegister(S3E_WEBVIEW_FINISHED_LOADING, loadedCallback, NULL, webView);
s3eWebViewRegister(S3E_WEBVIEW_FROM_JAVASCRIPT, javaScriptCallback, NULL, webView);

//navigate to the webpage
s3eWebViewNavigate(webView, rom);
//display the webview
s3eWebViewShow(webView, 0, 0, IwGxGetDisplayWidth(), IwGxGetDisplayHeight());
}

void destroy() {
if (webView) {
    s3eWebViewDestroy(webView);
    webView = NULL;

    //unregister callbacks
    s3eWebViewUnRegister(S3E_WEBVIEW_FINISHED_LOADING, loadedCallback, webView);
    s3eWebViewUnRegister(S3E_WEBVIEW_FROM_JAVASCRIPT, javaScriptCallback, webView);
}
delete rom;

//gives me warning so I'm leaving it out.
//delete pipHandler;
}

// Main entry point for the application
int main()
{
    //Initialise graphics system(s)
    //Initialise graphics system(s)
    Iw2DInit();

    //Init
    init();

    // Loop forever, until the user or the OS performs some action to quit the app
    while (!s3eDeviceCheckQuitRequest()) {
        //Update the input systems
        s3eKeyboardUpdate();
        s3ePointerUpdate();


    // Your rendering/app code goes here.


    // Sleep for 0ms to allow the OS to process events etc.
        s3eDeviceYield(0);
    }

    destroy();

    //Terminate modules being used

    // Return
    return 0;
}

这里是 webview 的 html/js

<!DOCTYPE html>
<html>
<head>
    <title>Storage Spike</title>
</head>
<body onload="main();">
  <div>Loaded value:<span id="loadedKey">(loaded value goes here)</span></div>
  <input type="text" id="inputKey" value="123key" placeholder="enter key to save"/>
  <button id="saveKey">Save</button>
  <button id="loadKey">Load</button>
  <br>
  <script>
    function main()
    {
      var saveKey = document.getElementById("saveKey");
      var loadKey = document.getElementById("loadKey");
      var inputKey = document.getElementById("inputKey");

      saveKey.addEventListener("click", function() {
        var key = inputKey.value;
        s3e.exec("saveKey|" + key);
      });

      loadKey.addEventListener("click", function() {
         s3e.exec("loadKey");
      });

    }

    function dataLoaded(data, type)
    {
      console.log(data);
      console.log(type);
      var loadedKey = document.getElementById("loadedKey");
      if(type === "key")
        loadedKey.innerHTML = data;
      else
        console.log("type error");
    }

  </script>
</body>
</html>

任何帮助将不胜感激,

亲切的问候

【问题讨论】:

    标签: android c++ webview marmalade


    【解决方案1】:

    问题是您试图直接保存 std::string 的实例。

    std::string 实例只不过是三个指针,它们描述了它用来存储实际字符串数据的内存。当应用程序关闭或用于存储数据的内存被释放时,这些指针就失去了意义。

    您需要将实际的字符串数据保存到 s3eSecureStorage 才能持久保存。为此,您需要序列化 ​​std::string 实例。进行序列化的一种简单方法是先保存字符串的长度,然后保存实际的字符串数据。

    要将字符串序列化并保存到 s3eSecureStorage,您可以这样做:

    std::string input = "exampledata";
    uint16 inputSize = static_cast<uint16>(input.size());
    uint16 bufferSize = static_cast<uint16>(sizeof(uint16) + inputSize);
    buffer = new char[bufferSize];
    std::memcpy(buffer, &inputSize, sizeof(uint16));
    std::memcpy(buffer + sizeof(uint16), input.c_str(), inputSize);
    s3eSecureStoragePut(buffer, bufferSize);
    delete[] buffer;
    

    要从 s3eSecureStorage 获取数据并反序列化字符串,您可以这样做:

    std::string output;
    uint16 dataSize = 0;
    s3eSecureStorageGet(&dataSize, sizeof(uint16));
    if (dataSize > 0) {
        uint16 bufferSize = static_cast<uint16>(dataSize + sizeof(uint16));
        char* buffer = new char[bufferSize];
        s3eSecureStorageGet(buffer, bufferSize);
        output.resize(dataSize);
        std::memcpy(&output[0], buffer + sizeof(uint16), dataSize);
        delete[] buffer;
    }
    

    如果要存储多个值,序列化需要稍微复杂一些,但基本思路是一样的。

    显然,当没有任何内容保存到 s3eSecureStorage 时,您还需要使用某种错误处理。

    您发布的代码在应用程序的一次执行中起作用的原因是您使用 new 分配了 SStoreData 实例并且从未发布它。当您从 s3eSecureStorage 加载指针时,它们仍将指向保存字符串数据的已分配内存。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-12-20
      • 2011-08-11
      • 1970-01-01
      • 1970-01-01
      • 2015-02-03
      • 1970-01-01
      • 2013-08-19
      • 2013-07-11
      相关资源
      最近更新 更多