8/18/2016

Generate javadoc using gradle

In your build.gradle file, adding the below snipet of code can generate the java doc of your module

configurations {
    javadocDeps
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile "com.android.support:support-annotations:${rootProject.ext.androidSupportSdkVersion}"    javadocDeps "com.android.support:support-annotations:${rootProject.ext.androidSupportSdkVersion}"}

task generateJavadocs(type: Javadoc) {
    source = android.sourceSets.main.java.srcDirs
    classpath += project.files(android.getBootClasspath()
            .join(File.pathSeparator))

    classpath += configurations.javadocDeps    failOnError false    destinationDir = file("../javaDoc/")
    exclude {
        it.file.path.contains('aidl')
    }
}


8/02/2016

Auto-generating enum/constants for different languages like c++, java, python, and so on

  In the past, speaking of cross-language tools to serialize and auto-generate structured data, you might use Protobuf to do that, Recently, I start to use flatbuffers to serialize/deserialize and auto-generate my data structure. There are a lot of comparisons on Protobuf, json, and flatbuffers, you can refer to the below links:
Why consider flatbuffer over json
How much is flatbuffer faster protobuf
Primay differences between protbuf and flatbuffers

Today, I am going to demonstrate how to use flatbuffers to auto-generate enum/constants for different languages like c++, java, python, and so on.

Clone flatbuffers
git clone https://github.com/google/flatbuffers
cd flatbuffers
Depending on your platform, use one of e.g.
$ cmake -G "Unix Makefiles"
$ cmake -G "Visual Studio 10"
$ cmake -G "Xcode"
Start to build
$ make
After making it, there is one of executable files, called flatc. Now, we can use flatc to genereate different source files for different language using flatbuffers's interface definition language(IDL).

Create an IDL file
vi resultcode.fbs
namespace tzutalin.common;
enum ResultCode { SUCCESS = 0, TIME_OUT, UNKNOWN_ERROR }
Use the below command to generate its c++ header, python, and Java file.
$ ./flatc --cpp --python --java -b resultcode.fbs

After generating, it creates ./resultcode_generated.h, ./tzutalin/common/ResultCode.py, and ./tzutalin/common/ResultCode.java.

resultcode_generated.h:
// automatically generated by the FlatBuffers compiler, do not modify
#ifndef FLATBUFFERS_GENERATED_RESULTCODE_TZUTALIN_COMMON_H_
#define FLATBUFFERS_GENERATED_RESULTCODE_TZUTALIN_COMMON_H_
#include "flatbuffers/flatbuffers.h"
namespace tzutalin {
namespace common {
enum ResultCode {
  ResultCode_SUCCESS = 0,
  ResultCode_TIME_OUT = 1,
  ResultCode_UNKNOWN_ERROR = 2,
  ResultCode_MIN = ResultCode_SUCCESS,
  ResultCode_MAX = ResultCode_UNKNOWN_ERROR
};
inline const char **EnumNamesResultCode() {
  static const char *names[] = { "SUCCESS", "TIME_OUT", "UNKNOWN_ERROR", nullptr };
  return names;
}
inline const char *EnumNameResultCode(ResultCode e) { return EnumNamesResultCode()[static_cast<int>(e)]; }
}  // namespace common
}  // namespace tzutalin
#endif  // FLATBUFFERS_GENERATED_RESULTCODE_TZUTALIN_COMMON_H_
ResultCode.py
# automatically generated by the FlatBuffers compiler, do not modify
# namespace: common
class ResultCode(object):
    SUCCESS = 0
    TIME_OUT = 1
    UNKNOWN_ERROR = 2
ResultCode.java:
// automatically generated by the FlatBuffers compiler, do not modify
package tzutalin.common;
public final class ResultCode {
  private ResultCode() { }
  public static final byte SUCCESS = 0;
  public static final byte TIME_OUT = 1;
  public static final byte UNKNOWN_ERROR = 2;
  public static final String[] names = { "SUCCESS", "TIME_OUT", "UNKNOWN_ERROR", };
  public static String name(int e) { return names[e]; }
}

8/01/2016

Restore missing tools/status/menu bar in Ubuntu 16.04

  Recently, I upgraded my Ubuntu from 14.04 to 16.04. It works well after upgrading. But someday my toolbar and menu bar are missing after I updating some packages and rebooting. Then, I try to enable Unity Launcher again, my toolbar and menu are back. The below steps are what I do

1. $ sudo apt install compizconfig-settings-manager
2. $ ccsm
3. Enable Ubuntu Unity Plugin. It will ask some questions because enabling it conflicts with another one.

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

6/28/2016

Fail to remount user/userdebug device after Andriod M

  After Android M, by default, Android OS will turn on system verified boot for user or userdebug build. It means it will fail to change or push any files under system partition.

  If your ROM is userdebug, you can use the below commands to remount system partition which will be able to read/write.
  $ adb root 
  $ adb disable-verity 
  $ adb reboot 
  $ adb wait-for-device 
  $ adb remount
adb disable-verity/enable-verit can only be executed if your ROM is userdebug, and you cannot remount system partition if your image is user build.

  If you can flash the image by yourself, you can build eng ROM which eng build will disable verified boot. Alternatively, you can disable verified boot by setting ro.secure to be 0 even if it is userdebug build. You can change the value of ro.secure in [AOSP]/build/core/main.mk, you can refer to the below screenshot.

6/25/2016

Old versions of Android NDK and ndk download script

6/17/2016

OpenCL on Android

Introduction and setup
  In android, Android/Google doesn't support OpenCL officially. Fortunately, many chip vendors like Qualquam90/ Nvidia/ Intel / MTK provide their libraries to support OpenCL on Android. 

  To use OpenCL on Android. If you want to use OpenCL, you need to check if there is OpenCL library on the device. You can download apps from Google Play to query OpenCL information like the version of OpenCL, device type, and benchmark tests. You can also go through List of Android Device with OpenCL support to see the benchmarks. 
The OpenCL libraries for the major chip vendors can be found in the devices. The followings are the location of the OpenCL library:

Qualquam(QUALCOMM Adreno)/Intel(HD Graphics)/Nvidia
/system/vendor/lib/libOpenCL.so
or /system/lib/libOpenCL.so (older devices)
ARM Mali:
/system/vendor/lib/egl/libGLES_mali.so
or /system/lib/egl/libGLES_mali.so
PowerVR:
/system/vendor/lib/libPVROCL.so
  1. Create NDK project to include OpenCL headers, compile your C/C++ code and link to CL shared library, and test them on the device as executable. Moreover, you can write JNI glue code and Java code to run on Java layer.

Quick setup and use Boost.Compute which is a GPU/parallel-computing library for C++ based on OpenCL.

You can refer to Boost.Compute-AndroidIf you like it, please give a star to this git repository.









Image annotation tool / Create bounding box for training images