Android: Proguard NoSuchMethodError - android

I recently activated ProGuard for my Eclipse Android project. After adding external libs and dynamically referenced classes to the proguard.cfg, I don't get any errors when building the apk. I get however a NoSuchMethodError when I try to start the installed app.
I narrowed it down to a specific method called in the onCreate method of the main activity. To simplify things, here's what the class and method look like (I left out a lot of code, but I think this should illustrate it):
public class TestMain extends TabActivity implements OnSharedPreferenceChangeListener{
...
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
testMethod();
}
}
testMethod() is defined as follows:
private void testMethod() {
int charsLeft = maxPostMessageLength - someEditText.length();
...
}
When I remove the "someEditText.length()" part, the app starts. So, the way I see it, the method that can't be found is the EditText.length() method. Strangely, though, the app also starts when I remove "someEditText.length()" from the testMethod and put it directly into the onCreate method:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
test = someEditText.length();
testMethod();
}
Does anyone know how I can get rid of this error and why I can call someEditText.length() directly in the onCreate method but not in a method called by the onCreate method?
Without using Proguard the app works fine, of course.
Edit:
I tried the -dontshrink, -dontobfuscate and the -dontoptimzie options in the proguard.cfg. With -dontoptimize the app starts without errors.
Still, it would be interesting what exactly causes this specific error.

The Proguard documentation proudly states: "The ProGuard tool shrinks, optimizes, and obfuscates your code by removing unused code and renaming classes".
Well, I gave up with the 'shrinking' part of it after getting runtime errors like you describe. I added the line
-dontshrink
to the proguard.cfg
You can see which routines have been removed from your code by inspecting the file usage.txt.
I'm happy to say that in my projects it's always missing, meaning that the code is obfuscated but nothing has been removed. I don't get any runtime errors now.

I accidentally stumbled upon a possible solution. Well, it totally works in my case, so this IS a solution to the original problem:
Today, I implemented some code with #Override annotations, which didn't work, at first. Luckily, someone else already had the same problem and an easy Eclipse-related solution:
'Must Override a Superclass Method' Errors after importing a project into Eclipse
Now, I thought, well, if I was always using Java level 1.5 before, why not try ProGuard again, without the -dontoptimize option, now that I set it to 1.6. Can't hurt...
And what can I say, now the app starts and I don't get the strange error when EditText.length() is called in a method.

The optimizer may remove the method invocation and the method if it comes to the conclusion that the method doesn't have any side-effects. It should never create inconsistent code though, and I'm not aware of a problem like this. You should check if it persists with the latest version of ProGuard. Otherwise, you should file a bug report on the ProGuard site, preferably with a small example that illustrates the problem.

I had a similar problem to the OP and it ended up being a proguard config option I set -allowaccessmodification, removing this solved the issue.

Related

Proguard rule for Huawei push client

I have Unable to create application im.app.android.core.AppDemoApplication: e3.b: com.pushserver.android.huaweiPushClient cant cast com.myApp.android.push_lib.huawei.HcmPushClient to PushClient error
What proguard rule should I add? I have tried -keep class com.myApp.android.push_lib.** { *; } but after that I just see the blank screen - no crash, just stuck when trying to start.
Not really an answer, but too long for a comment. I'll update this answer in case we make progress.
1. What is the "normal bug"?
can't cast com.myApp.android.push_lib.huawei.HcmPushClient to PushClient
This means that somewhere in your code you are assigning/passing an instance of HcmPushClient to something that is expecting it to be a PushClient. I would assume that PushClient is some class that you defined in your project, but is does not extend from HcmPushClient. Try to find this piece of code and fix it or add it here to your question.
2. What does ProGuard have to do with this?
Actually, I think not much. If ProGuard would create this error, the message would look more like
can't cast com.myApp.android.push_lib.a.b to c
But since all class names in the error message are the original ones, it does not seem like ProGuard is making issues here. BUT: You can still decypher the message a little bit, because this part is obfuscated:
Unable to create application im.app.android.core.AppDemoApplication: e3.b:
e3.b refers to a class that was obfuscated by ProGuard. To find out what class it is, you can check the file /build/outputs/mapping/release/mapping.txt in your project folder. This is a simple text file that stores the information what class name was renamed to what obfuscated name. In this file search for -> e3 to find the class that was renamed to e3. Somewhere close to this line, you should also be able to find out what exactly e3.b is. Could be a method, could also be a member variable or an inner class.
I hope these two points will bring you closer to make the app run.

GradleDetector: `checkDslPropertyAssignment` isn't executed

I'm writing some custom lint and decided to add a detector for the Gradle files.
So I've extended the GradleDetector(), overridden checkDslPropertyAssignment method, and added some test to check the logic inside checkDslPropertyAssignment. So far all works well.
However, if I name the gradle file differently in the test case, checkDslPropertyAssignment doesn't get executed. For example:
lint().files(
gradle("test.gradle", gradleFile)
)
If I skip "test.gradle", everything seems to be working.
Am I misusing something here, or is there a bug in the GradleDetector?
Thanks!

AndroidAnnotations cannot find symbol class

I'm using AndroidAnnotations in an Android Studio gradle project. I currently get error output from AA during compilation that says:
cannot find symbol class MyActivity_
The error output does not prevent building the application - its not really a compile error because the class is there, it seems that it is just an unfortunate timing issue with the compilation process.
Is there anything I can do to avoid these false-positive errors from AA? When there are "fake" errors shown every time I compile, its very easy to miss the real errors.
I had same error. To solve it I have revert my last changes and it has worked again.
I think it was either wrong optimized import(you must import generated classes eg. xxx_) or I injected layout by id what was not existed in the layout xml
Update
I figured it. My problem was what I had use private mofidier instead of proteced in
#ViewById(R.id.list)
private ListView list;
Try to see if you missed to fix some errors in the class MainActivity or in someone of his Bean member that you have annoted.
The problem doesn't have to be in MainActivty, but it is probably because of a private modifier which is used with Android Anotations (in injection, method declaration etc) somewhere in your code

Cannot call 'SetContentView' on new activity - Android Mono

I've had a search for this problem but nothing seems to help me to solve this particular error I am getting.
I am writing my first Android app and am coming across a java.lang.RuntimeException whenever I call SetContentView on a new activity.
There is nothing in the logcat which helps (an activity idle timeout is all because it falters on the call).
My activity Login has a layout set during OnCreate which works fine, but any subsequent calls fall over. Here's some code ;)
[Activity(Label = "Usage")]
public class Usage : TabActivity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
//**FALLS OVER HERE**
SetContentView(Resource.Layout.Usage);
The Resource.Designer.cs has a record of my layout:
// aapt resource value: 0x7f030002
public const int Usage = 2130903042;
...and when I reference that layout by it's int value it falls back to the previous activity without hitting any breakpoints in the Usage activity.
Anyone got any thoughts or can point me in the direction of a similar post?
Legends!
UPDATE
I tried a whole stack of fixes I found on forums etc but nothing would fix this. I put the whole thing on the backburner while I worked on something else, came back to it and now it works...wish I could say what it was that made it work to help others out but I can't explain it! COULD have been an update to a new version of MonoDroid?
As stated in my comment to Stuart's answer, this problem appears to have resolved itself. I revisited the project all this time later and think that it might have just been a case of cleaning the project and rebuilding all. I have not had this problem since.
Sorry that this is not a detailed answer, I would suggest trying the ol' clean and rebuild.
I've recently had some issues when working in VS2010 where the resource ids are being not kept perfectly in-sync with the resource files and the java ids.
To resolve these, I generally find the quickest way is to add a new id to one of the layout xml files - this then causes a regeneration or the resources.cs file which then means the app works again.
If that doesn't help, then please post more info about what the message inside the RuntimeException is,
Although it's very late response, but someone who might be getting this sort of error. Wrap it with try-catch and it gives more details about the exception. I spent few hours before figuring out to do that

Android using AndroidAnnotations in Library Project Eclipse

I'm making a paid/free version of my app so have a 'Library Project' that the two apps use.
I'm trying to use Android Annotations to clean up my code:
http://code.google.com/p/androidannotations/
Unfortunately when I use this in my shared library project, one of my projects gets the error in Eclipse:
The type xActivity_ is already defined xActivity_.java /ProjectName/.apt_generated/lib/activities/
Because Android Annotations automatically creates a new activity with an extra '_' in the folder .apt_generated one of the apps is allowed to create this file, but the other gets the error "already defined".
Is there a way in Eclipse to resolve this? Or is it a problem with the Android Annotations?
This seems to be an AndroidAnnotations bug, and should be reported on the dedicated bug tracker.
AndroidAnnotations wasn't designed with this use case in mind, but this is still a very valid use case. The problem seems to be that the activity is generated in the shared library project, when it should be generated in each depending project, am I right ?
(please answer in the bug tracker)
This question is quite old, but I thought that I should mention android annotations now supports being used in libaries:
https://github.com/excilys/androidannotations/wiki/Library-projects
One caveat is that due to the way android library projects generate the R class, you cannot reference resouces directly inside the annotations. Eg, you cant do this:
#EActivity(R.layout.myLayout)
public class MyActivity extends Activity {
#Click(R.id.myButton1, R.id.myButton2})
public void someButtonClicked() {
}
}
Instead you must do this:
#EActivity(resName="myLayout")
public class MyActivity extends Activity {
#Click(resName={"myButton1", "myButton2"})
public void someButtonClicked() {
}
}
I just knew AndroidAnnotations (which seems a great tool!) but I think that if you do this using different projects (sharing the same library) your problem should be solved.

Categories

Resources