Java bytecode can be easily decompiled.
It's possible to use obfuscators to make it difficult to reverse engineer bytecode.
But, it doesn't give 100% guarantee from reverse engineering - decompiled code will be just messy.
Android development tools include Proguard obfuscator - you can use it.
The best way to protect code is to move some parts of it to native part (NDK, C++).
Best regards.
---------- Post added at 02:37 PM ---------- Previous post was at 02:20 PM ----------
There is dirty trick here. You can move some part(logic) of your code in native lib. It will complicate the decompilation. Because not so many reversers familiar with arm assembler. But I'm agree, it's not possible to fully protect app from cracking.
I agree with you, that not many people know it.
But, Arm assembler is easy to understand. If somebody understands x86 assembler, he can understand Arm assembler too.
IDA is a great tool for reverse engineering. If you have understanding of Arm assembler, you can use IDA to check how it's hard to reverse engineer your software.
Some tips:
Don't make simple to understand function names, such as checkLicense, isLicenseValid, isTrialValid, isItemBrought. Make names, that will confuse. For example: function that check license or trial will be loadIcons or something like this.
Don't make functions easily to patch. For example, your function check if item in your game is brought, and it returns bool. Someone can replace a few asm instructions, and func will always return true. It's better to make not only one check from different places. If one check func is patched, others are not. And it will make your app cracking more difficult.
Scramble strings. Strings, such as urls, message texts, log messages, can make cracking more easy. For example, your app gets the list of brought items from your server. Server url can be used to identify the place, where check is performed. Cracker can reveal logic and patch your app. The same is with messages and log messages. These strings can be used to identify place in code and what your app perform in this place. Make xor for all chars in such strings, and it will be more difficult to find it.
I hope this help you.
Best regards,