Невозможно ничего защитить от декомпиляции, можно повысить ее сложность и уменьшить ее рентабельность. Превратить в "Неуловимого Джо".
Исходить необходимо из рентабельности. Смотреть на свое приложение глазами того самого хитрого умельца. Для начала: что он вообще хочет? Ему нужен рабочий код целиком, рабочий участок кода, или просто достаточно подсмотреть принцип (несколько строчек), или что? Если несколько строчек, то "портить" имена классов и методов почти что не имеет смысла.
По ситуации уже определяетесь, какого результата хотите достичь, и выбираете приемы. А их очень много.
На Android можно часть написать на JNI - в ассемблере и машинных кодах копаться тяжело, а C++ не всегда декомпилируется достаточно корректно, особенно, если скомпилировать библиотеку только под armeabi, а не под несколько разных архитектур.
Кстати, декомпиляторы Java тоже не бывают идеальными, ну, а smali - это тоже тяжело, но в нативе все в целом гораздо тяжелее.