7/20/2016

Use Rapidjson in cpp to read/write json file

  In C++, if you want to serialize, deserialize, prettify JSON, there are some libraries to allow you to do that, e.g. JsonCPP and RapidJson. Compare with JsonCpp and Rapidjon, Rapidjson is faster then JsonCPP. Besides, Rapidjson is a header-only library, so it is easy to include Rapidjon using the different build system, and I have tested and used Rapidjon on my Linux application and android native side.

  There is a snippet of code to serialize and deserialize Json file as bellow.

Write
#include <rapidjson/document.h>
#include <rapidjson/prettywriter.h>
#include <rapidjson/stringbuffer.h>
#include <stdio.h>
#include <sys/stat.h>

using namespace rapidjson;
std::stringstream ss_date;
time_t t = time(0);
struct tm * now = localtime(&t);
ss_date << (now->tm_year + 1900) << '-' << (now->tm_mon + 1) << '-'
        << now->tm_mday; 
StringBuffer s;
PrettyWriter<StringBuffer> writer(s);
writer.StartObject();
writer.Key("version");
writer.String("1.0");
writer.Key("data");
writer.String(ss_date.str().c_str());
writer.Key("file");
writer.StartArray();
// m_vWriteFilePath is a vector<std::string> which contains 0.mp3 1.mp3 ...
for (const auto& path : m_vWriteFilePath) {
  writer.String(path.c_str());
}
writer.EndArray();
writer.EndObject();
std::ofstream of(m_indexFilePath);
of << s.GetString();
if (!of.good())
  throw std::runtime_error("Can't write the JSON string to the file!");
Result:
{
    "version": "1.0",
    "data": "2016-7-20",
    "file": [
        "0.mp3",
        "1.mp3",
        "2.mp3",
        "3.mp3",
        "4.mp3"
    ]
}
Read
using namespace rapidjson;
std::stringstream ss;
std::ifstream file(m_indexFilePath);
if (file) {
  ss << file.rdbuf();
  file.close();
} else {
  throw std::runtime_error("!! Unable to open json file");
}
Document doc;
if (doc.Parse<0>(ss.str().c_str()).HasParseError())
  throw std::invalid_argument("json parse error");
// Start parsing json string
std::string version = doc["version"].GetString();
std::string date = doc["data"].GetString();
const Value& array = doc["file"];
for (rapidjson::SizeType i = 0; i < array.Size(); i++) {
  m_vReadFilePath.push_back(array[i].GetString());
}




7/05/2016

dx process limitation (dexOptions is specifying a maximum number of 2 concurrent dx processes, but the Gradle daemon was initialized with 4)

When I enable multidex and executing ./gradlew build command, I meet the problem about 'dx process limitation' when

Error message:

To initialize with a different maximum value, first stop the Gradle daemon by calling ‘gradlew —-stop’.
dexOptions is specifying a maximum number of 2 concurrent dx processes, but the Gradle daemon was initialized with 4.

To fix the problem, I change the maxProcessCount to 1 in my gradle file.



android {

  ...

  dexOptions {

        jumboMode = true // Eabled it to allow a larger number of strings in the dex files

        maxProcessCount 1 // The maximum number of concurrent processes that can be used to dex. Defaults to 4.

        threadCount 1 // Number of threads to use when running dx. Defaults to 4.

        dexInProcess false   //To disable dexing-in-process, add the following code to your module-level build.gradle file:

        preDexLibraries true // Whether to pre-dex libraries. This can improve incremental builds, but clean builds may be slower.

    }

 }

DEX 64K Reference Limit

When the source of your Android app grew too much or you use too much 3rd party libraries, you might meet DEX 64K Reference Limit. As you are building and install your APK, the error happens like below:

Conversion to Dalvik format failed:
Unable to execute dex: method ID not in [0, 0xffff]: 65536

What is DEX 64K Reference Limit 

Android application (APK) files contain executable bytecode files in the form of Dalvik Executable (DEX) files, which contain the compiled code used to run your app. The Dalvik Executable specification limits the total number of methods that can be referenced within a single DEX file to 65,536(64K)—including Android framework methods, library methods, and methods in your own code.

How to resolve or avoid it


1. Use Proguard to shrinks, optimizes and obfuscates your code by removing unused code and renaming classes, fields and methods with semantically obscure names. I won't tell too in this article.

2. Enable multidex.Configure your app build process to generate more than one DEX file

3. Use Jar Jar Links utility repackage Java libraries, remove some unnecessary packages from 3rd parties libraries.


Reference:
https://developer.android.com/studio/build/multidex.html#about