Error when minify is enabled, but works otherwise - android

As soon as I enabled minify, this issue started occurring.
-keepclassmembers class * { *** #{viewModel::onResendClick}(android.view.View); }
This method is a part of the viewmodel but this seems to be weird, I am not able to understand or debug this issue.

Related

Abnormal CPU usage - Okio Watchdog

I am using OkHttp (first the original verison, then I upgraded to OkHttp3), some users of my App have been reporting significant battery life loss when the App isn't running.
I ran a profiler and this is the result:
As you can see, Okio Watchdog is running the whole time. At roughly the halfway point, my App is fully in the background. There are no HTTP tasks taking place at this point in time. I started profiling after the last HTTP task ended.
Is it normal that the Watchdog runs throughout like that? If so, am I right in assuming this thread is causing a lot of battery waste? If it isn't normal, could something like a leaked Context keep the Watchdog running?
The Watchdog code runs here, it seems like to runs without a termination condition:
private static final class Watchdog extends Thread {
public Watchdog() {
super("Okio Watchdog");
setDaemon(true);
}
public void run() {
while (true) {
try {
AsyncTimeout timedOut = awaitTimeout();
// Didn't find a node to interrupt. Try again.
if (timedOut == null) continue;
// Close the timed out node.
timedOut.timedOut();
} catch (InterruptedException ignored) {
}
}
}
}
Looks like a severe & unexpected bug in Okio. I'll try to reproduce & fix. If you're able to produce this consistently, please comment on this bug!
https://github.com/square/okio/issues/185
For me it was caused by proguard's optimization. After some investigation - see the okio issue linked above - a workaround (if not final fix?) is to disable optimization or add this to your proguard-rules.pro:
-optimizations !method/marking/static,!method/removal/parameter,!code/removal/advanced
I find a NOTE in this manual
Note: the configuration specifies that none of the methods of class '...' have any side effects
Your configuration contains an option -assumenosideeffects to indicate that the specified methods don't have any side effects. However, the configuration tries to match all methods, by using a wildcard like "*;". This includes methods from java.lang.Object, such as wait() and notify(). Removing invocations of those methods will most likely break your application. You should list the methods without side effects more conservatively. You can switch off these notes by specifying the -dontnote option.
You should specify the method name in the -assumenosideeffects block.
I add this comment at https://github.com/square/okio/issues/185#issuecomment-220520926

onCreate(Unknown Source) for Application class with Proguard (only happens on Samsung devices)

I've been testing my app on Sony and Nexus devices as well as multiple emulators (API 10 - 19) for several weeks and things seem fine, however, two of my testers (who live remotely) are experiencing crashes during startup and ACRA isn't offering the option to send a crash log email, which leads me to believe it's a crash before ACRA is even instantiated. ACRA works as expected on my devices and emulators and offers to send an email (via default app).
Are Samsung phones doing some special initialization? Am I doing anything in the following code which could cause a crash?
#ReportsCrashes(
formKey = "", // This is required for backward compatibility but not used
mailTo = "crash#mydomain.com",
customReportContent = {
ReportField.APP_VERSION_CODE,
ReportField.APP_VERSION_NAME,
ReportField.ANDROID_VERSION,
ReportField.PHONE_MODEL,
ReportField.CUSTOM_DATA,
ReportField.STACK_TRACE,
ReportField.LOGCAT }
)
public class AppState extends Application {
private static final String DIRECTORY_ROOT = Environment.getExternalStorageDirectory();
private static final String DIRECTORY_PICTURES_APP = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsolutePath() + File.separator + "MyApp";
private static final LogConfigurator logConfigurator = new LogConfigurator();
private static final Logger logger = Logger.getLogger(AppState.class);
#Override
public void onCreate() {
super.onCreate();
ACRA.init(this);
// try to create log file and directory; if successful, configure ACRA to include last lines with crash report
if (createLogFile()) {
ACRAConfiguration config = ACRA.getConfig();
config.setApplicationLogFile(LOGGER_FILENAME);
ACRA.setConfig(config);
}
...log4j, database init, etc...
The source for the project is located here on SourceForge.
EDIT #1:
Finally got one of the Samsung Remote Test Lab devices working! Screen still isn't visible, but I can at least see logcat. Here is the reason for the crash:
ERROR AndroidRuntime at org.dumpsterdiver.sync.AppState.onCreate(Unknown Source)
So that means the system is unable to find my Application class? After a bit of Googling similar problems, I think it might be a proguard error (sigh, again), so I've been playing with various suggestions from other answers. None of these have helped so far (still experimenting with various values):
-keep public class org.dumpsterdiver.sync.AppState
-keep public class * extends android.app.Application
-keep public class * extends com.actionbarsherlock.app.SherlockActivity
EDIT #2:
Adding this line to my proguard config file seems to fix the problem:
-keep class * { *; }
But my APK is 500 KB larger (3.7 -> 4.2 MB) and I suspect this probably defeats half the point of using proguard in the first place? Is there a better solution?
After a lot of experimentation, this line was the problem:
-keep public class org.dumpsterdiver.sync.AppState
Changing it to this seems to have done the trick:
-keep public class * extends android.app.Application

False positives: junit.framework.AssertionFailedError: EditText is not found

I have a problem setting up Robotium tests to run on Travis without random false posivities.
Every couple of builds I get
pl.mg6.agrtt.TestActivityTests > testCanEnterTextAndPressButton[test(AVD) - 4.4.2] FAILED
junit.framework.AssertionFailedError: EditText is not found!
at com.robotium.solo.Waiter.waitForAndGetView(Waiter.java:540)
on all my tests.
I have created a simple project on GitHub to show the issue.
You may see how it builds on Travis. Note build #7 failed after modyfing unrelated file.
I'm suspecting this to be caused by emulator being locked or its sceeen dimmed. I could reproduce this issue on local machine by turning connected device's screen off and then running
./gradlew connectedAndroidTest
After modyfing tests I got a different error message, which is somewhat more informative, so I'm adding it just in case someone tries to find a solution:
pl.mg6.agrtt.TestActivityTests > testCanFindViewsEnterTextAndPressButton[test(AVD) - 4.4.2] FAILED
junit.framework.AssertionFailedError: Click at (160.0, 264.0) can not be completed! (java.lang.SecurityException: Injecting to another application requires INJECT_EVENTS permission)
at com.robotium.solo.Clicker.clickOnScreen(Clicker.java:106)
While the root cause of this problem is still unknown to me, after some investigation and with a help from Robotium's author Renas Reda I could confirm what I initially suspected that emulator indeed locks itself.
A workaround I'm using now is this code put in setUp method:
getInstrumentation().runOnMainSync(new Runnable() {
#Override
public void run() {
getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
}
});
Robotium discards invisible views when using enterText(int, String). Instead use getView(int) of Solo to use resulting view in enterText(View, String).
Like this:
public void testCanEnterTextAndPressButton() {
solo.enterText(((EditText) solo.getView(R.id.editText1)), "my login");
solo.enterText(((EditText) solo.getView(R.id.editText2)), "my password");
solo.clickOnView(solo.getView(R.id.button));
}
And if the device screen is locked Robotium fails to run those instructions you gave. You might want to disable screen locking.
By code above my tests pass.
Your guess is probably right. One way to be sure that it is is to catch the exception that is thrown and call
solo.takeScreenshot("screenshotFileName");
and then take a look at the screenshot that is saved to your phone's SD card to see what your phone was doing at the time of the error.
I solved this problem by turning on the device's "Stay Awake" setting so it won't sleep while recharging.

How can I detect in an app that Proguard successfully removed all log calls?

Thanks to Proguard's optimization features I am now able to do as much debug-logging as I which in my code - for production I simply let it strip all this unnecessary code.
That is fine and works (with the latest Proguard version).
But: before I went this way, I had my final static boolean DEBUG constant that "guarded" all my Log.d/Log.v calls. To ensure I did not forget to disable that for signed production apk's, I just had an easily visible add on in my UI main activity that in some corner put an ugly text "DEBUG IS ON".
So, when producing my final apk, all I had to do is install it once - in case I forgot to switch debug mode off, I was reminded by that.
Now, with Proguard doing the work of removing debug-log-calls: how could I DETECT that in my app and control a UI element that states "DEBUG IS ON"?
Any idea?
My first attempt was to try this:
boolean loggingEnabled = false;
Log.d(TAG, (loggingEnabled = true) ? "Logging test" : "");
And I hoped that Proguard would also remove the assignment loggingEnabled=true- but I underestimated Proguard. It removes the call to Log.d, but still does the assignment... :)
You can do a few things:
Check the mapping.txt in proguard's output folder: grep -E '(android/util/|de/ub0r/android/logg0r/)Log.[dv]' */build/proguard/release/dump.txt
Run the app and check if any d/v log is printed.
Decompilte the app and look at the source code for calls to Log.d() and Log.v().
I build a simple wrapper library to make it a little bit more handy:
https://github.com/felixb/ub0rlogg0r
--- EDIT ---
To Check if your logs got stripped, do the following:
Fork ub0rlogg0r.
Add a public static boolean sHasDebugCalls = false; to Log.
Add sHasDebugCalls = true to all the Log.d() and Log.v() methods.
Place a Log.d(TAG, "has debug logs") somewhere in the very beginning of your app.
When creating your UI, test for Log.sHasDebugCalls to decide visibility of the DEBUG reminder.

How to programatically change ACRA 'interaction mode' setting

I'm implementing ACRA in my Android App. I would like to be have it's interaction mode be silent by default, but if I see that a new version of my App is available, "Toast" the user upon crash with a message to update their copy of the App.
However it seems that ACRA interaction mode must be hard coded and loaded once upon init of application. Any way to set the mode at that point not via a hard coded setting? E.g. I'm looking to control the "mode = " setting which is copied below.
#ReportsCrashes(formKey = "xxxxxxxxxxxxxxxx",
mode = ReportingInteractionMode.TOAST,
resToastText = R.string.crash_toast_text)
public class MyApplication extends Application ...
I see that ACRA Issue 85 has added setters for resources for Toast parameters, but does it also have ability to configure interaction mode?
Maybe this? I didn't try but seems useful (at point of start)
http://www.java2s.com/Open-Source/Android/App/acra/org/acra/ErrorReporter.java.htm

Categories

Resources