How to make my android app clean? - android

In my Java code, I use the Debug flag to control debug model, if is debug ,there are some extra functions,such as:sway the phone show a activity to change app version. Now I want to erase these code when publishing the code to market.
Like the code below, is there a way to make VersionSwitchService.class code is null and other code is running normal?
I mean that even if, someone decompiles the apk, VersionSwitchService.class code is seen as blank.
if (isDEBUG) {
VersionSwitchService.libStart(this, new LibVersionSwitch() {
#Override
public void versionSwitchToOnline() {
//...
}
#Override
public void versionSwitch(String version) {
//...
}
});
}

If you make isDebug final static:
final static boolean isDebug = false;
the Java compiler will complete remove the parts of code that are unreached. Sp in your example, the 'then'-part is completely omitted and thus not available in your apk.
Furthermore, when creating a (release) apk build, the Android tools will strip all methods and classes that are unused. So, if your VersionSwitchService class is only used for debugging, it will not present (due to the combination of the static final debug constant)

Related

Flutter release APK is not working but debug APK is working

My debug APK is working fine but release APK is not working after building it from the command flutter build apk. What can be the real issue here?
In debug mode, any global variables or methods will work perfectly but in case of release mode, only native code is compiled. So let's assume we are getting some unformatted text and we want to format it and return so if you have a global function to format text like below it will work fine in debug mode but might cause problems in release mode.
Code with global function.
// Global Function
String formatText(String unformattedText){
// ....
return formattedText;
}
Widget _showFormattedText(String unformattedText) {
final fd = formatText(unformattedText);
return Text(fd);
}
Instead of this we should follow best practices and wrap everything inside a class which is present globally.
// Code with class method.
class CustomFunctions{
static String formatText(String unformattedText){
// ....
return formattedText;
}
}
Widget _showFormattedText(String unformattedText) {
final fd = CustomFunctions.formatText(unformattedText);
return Text(fd);
}

Is DexGuard tamper and Environment detection helpful?

I am very new to DexGuard and Proguard. I was going through their documentation and sample examples. They have dexguard_util which helps you detect if the application is tampered with and also helps in detecting if it is running in the environment it is supposed to run. The document suggests that this tamper and environment detection be encrypted using the following code is dexgaurd-project.txt.
-encryptclasses A$D
-encryptstrings A$D
follwing is the activity
public class A extends Activity
{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
new D().c();
}
private class D
{
public void c()
{
//some code to which detects the tampering and environment and takes action accordingly
}
}
}
What if a hacker inject this line of code.
public class A extends Activity
{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
//code commented by hacker
//new D().c();
}
private class D
{
public void c()
{
//some code to which detects the tampering and environment and takes action accordingly
}
}
}
Then my application will run without running those tests which I think is a big problem. Is my understanding of how reverse engineering works wrong or there are better ways of doing this. Please share better methods of doing this if they exist. Thanks in advance. Note that public class A cannot be encrypted as it is an entry point and is kept using this command in progaurd-project.txt
-keep class somepackage.A
When it comes to anti-tampering, it is important to keep in mind that their goal is not to stop any and all potential tampering efforts, but, rather, it's just a matter of raising the security bar of the target high enough to dissuade most attackers.
With that said, the
A bit of a tangent:
The document suggests that this tamper and environment detection be encrypted using the following code is dexgaurd-project.txt.
Class encryption does prevent basic static analysis of the application package, e.g. simply unzipping the package and loading it in jd-gui. However, as this answer shows, it's trivial to circumvent: one only has to hook into the static method that decrypts the apk on load, and dump it. But this allows the security bar to be raised.
Now back to your original question:
What if a hacker inject this line of code.
As an attacker, that would be the next step. However, that would require repackaging the app, and signing it with the hacker's signing key. Therefore, it is necessary to combine Dexguard's anti-tampering measures like checking the apk signature.
Is DexGuard tamper and Environment detection helpful?
In summary, yes, it is helpful in as far as it raises the bar above the vast majority of apps out there. But it's no silver bullet.

Android registerOnSharedPreferenceChangeListener() not working

I've got a really weird one. I have 2 apps, a free app and a paid app, both using basically the same code, with the exception of some code to show ads in the free one.
For some reason, registerOnSharedPreferenceChangeListener() doesn't run in the free version. What's even weirder... if I put a breakpoint at that line of code, and run the debugger, it registers fine. Without the breakpoint there, it never registers. Any idea what would cause this? Maybe something that differs in the project settings? I've been trying to fix this all day!
code:
SharedPreferences.OnSharedPreferenceChangeListener prefsListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
#Override
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
if(key.equals(AUTORESPONSEGLOBAL))
{
ARCheckBox.setChecked(settings.getBoolean(AUTORESPONSEGLOBAL, false));
if(ARCheckBox.isChecked())
{
//green 0xaarrggbb a=alpha
AR_label.setTextColor(0xff00ff00);
}
else
{
//red
AR_label.setTextColor(0xffff0000);
}
}
if(key.equals(CLOCK24))
{
updateTime();
}
}
};
settings.registerOnSharedPreferenceChangeListener(prefsListener);
OK, I'm still not sure why it was working in one project and not the other... but I fixed it.
I was declaring SharedPreferences.OnSharedPreferenceChangeListener prefsListener = new SharedPreferences.OnSharedPreferenceChangeListener() { ... }; in onCreate(). I changed it to it's own separate method, and it seems to work fine now. I changed both projects to work this way, to keep things consistent.

Does too many log writing decreases android application performance?

I would to know whether logging can decrease application performance?
Also, please give me some tips to increase android application performance.
Yes. Excessive logging affects the performance of any application not just Android.
The developer guide suggests you to deactivate and disabled logging before release:
Turn off logging and debugging Make sure you deactivate logging and
disable the debugging option before you build your application for
release. You can deactivate logging by removing calls to Log methods
in your source files. You can disable debugging by removing the
android:debuggable attribute from the tag in your
manifest file, or by setting the android:debuggable attribute to false
in your manifest file. Also, remove any log files or static test files
that were created in your project.
Also, you should remove all Debug tracing calls that you added to your
code, such as startMethodTracing() and stopMethodTracing() method
calls.
So, you should suppress the logs in "release" or "production" build of your App.
Turn off it in Android Manifest by setting debuggable:
<application android:icon="#drawable/icon"
android:label="#string/app_name"
android:debuggable="false">
Another way
Create your own logger class and check for debugging mode before executing log. It allows single point modification between debugging mode and deployed application and allows extra things to do such as writing to log file.
import android.util.Log;
public class MyLog {
private static final boolean isDebug = false;;
public static void i(String tag, String msg) {
if (isDebug) {
Log.i(tag, msg);
}
}
public static void e(String tag, String msg) {
if (isDebug) {
Log.e(tag, msg);
}
}
}
For further info read http://rxwen.blogspot.com/2009/11/logging-in-android.html
and The SO QAs :
Log.d and impact on performance
Android Logging - How to clear for better performance
use 'if' statement before log writing.
you can disable log when application release.
example :
public class LogTest extends Activity {
private static final String TAG = "YOUR_LOG_TAG_NAME";
private static final boolean mDebug = true;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//--[Start Log example]-----------------------------------------
if(mDebug) Log.d(TAG, "Log Write Test");
//--[End Log example]-----------------------------------------
}
}
Any text output in excess will slow down your application, even with a desktop application. Excessive logging does slow things down, but you would basically need an insane amount of data being sent through, which by the way, isn't that hard to do with a for or while loop. Things that happen in the background while logging sometime include string manipulation, text rendering, cache management, data filtering, log length limiting, and the list goes on.
There's several ways to remove logcat from your final app, especially those involving ProGuard. ProGuard didn't work for me, but there's plenty of brilliant ideas out there on how to remove them including scripting programs like sed.

Log.d and impact on performance

I'm not entirely sure about what I'm reading in the documentation. Is it ok to leave a bunch of log.d pieces of code scattered about, or should I comment them out so that they don't impact my app's performance.
Thanks,
I'm a little confused because if you read about the log object (documentation) you see this:
"The order in terms of verbosity, from least to most is ERROR, WARN,
INFO, DEBUG, VERBOSE. Verbose should never be compiled into an
application except during development. Debug logs are compiled in but
stripped at runtime. Error, warning and info logs are always kept. "
It almost sounded like it's ok to leave debug messages in there because they are "stripped." Anyway, thanks for the answers, I'll comment them out when I'm done. Not like I need them in there once the app is completed.
Thanks
Log has impact on performance, so it's recommended that you comment it out or log with conditional statements.
For example
public class MyActivity extends Activity {
// Debugging
private static final String TAG = "MyApp";
private static final boolean D = true;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(D) Log.e(TAG, "MyActivity.onCreate debug message");
}
Then in when you publish your release version just change "D" to false
My solution:
Add unguarded log statements wherever you like
Strip them out for release builds
Definitely comment them out. They add up quickly and could noticeably slow down your app, especially if you have them in loops.
Simply use code guard methods.
if (Log.isLoggable(LOG_TAG, Log.DEBUG)) {
Log.d(LOG_TAG, "Your log here");
}
Yes print, println, Log.d, Log.e and all similar methods affect performance.
The solution
create a class named C
class C{
public static String TAG="My_debug_tag";
public static boolean isInTesting=true;
public static void log(String tag, String msg){
if(!isInTesting) return;
Log.d(tag==null?TAG:tag, msg);
}
}
and use these methods for all your logs, and when you are ready to generate final .apk/.aab just set isInTesting=false to disable all logs from this method.

Categories

Resources