Can anyone give me any clues on how to debug the following.
I have a mixed java / scala android project that I'm working on in Intellij and I process it through Proguard as part of run config.
When I run the app I get the error:
07-24 12:36:35.879 21731-21779/com.ovaphone E/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #1
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:299)
at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at java.lang.Thread.run(Thread.java:856)
Caused by: java.lang.AbstractMethodError: abstract method not implemented
at android.os.AsyncTask.doInBackground(AsyncTask.java)
at android.os.AsyncTask$2.call(AsyncTask.java:287)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
I'm guessing it's caused by Proguard stripping out too much.
I do have one class that extends AsyncTask, and I know this class is definitely the culprit as when I comment out its use the problem disappears.
My AsyncTask is:
object CheckNetworkStatusOnStartup {
class Payload(var mainActivity: MainActivity) {
var isConnected: java.lang.Boolean = false
}
}
class CheckNetworkStatusOnStartup extends AsyncTask[CheckNetworkStatusOnStartup.Payload, Void, CheckNetworkStatusOnStartup.Payload] {
override def doInBackground(params: Payload*): Payload = {
val payload = params(0)
<checks the network status and sets Payload.isConnected>
payload
}
override def onPostExecute(payload: Payload) {
<updates network status on screen of MainActivity>
}
}
And it's called in the MainActivity by:
new CheckNetworkStatusOnStartup().execute(new CheckNetworkStatusOnStartup.Payload(this))
I've tried adding both:
-keep class * extends android.os.AsyncTask {
*;
}
and
-keep public class com.mypackage.MyClass extends android.os.AsyncTask
to the proguard config file but neither make a difference.
Should those '-keep' statements be sufficient?
Can anyone give me any pointers on how to proceed?
Edit
Following Eric's suggestion, running javap on the compiled class gives the following output:
public class com.ovaphone.CheckNetworkStatusOnStartup extends android.os.AsyncTask<com.ovaphone.Payload, java.lang.Void, com.ovaphone.Payload> {
public com.ovaphone.Payload doInBackground(scala.collection.Seq<com.ovaphone.Payload>);
public void onPostExecute(com.ovaphone.Payload);
public com.ovaphone.Payload doInBackground(com.ovaphone.Payload[]);
public void onPostExecute(java.lang.Object);
public com.ovaphone.CheckNetworkStatusOnStartup();
}
Running dexdump on the process apk shows that doInBackground is missing (but onPastExecute is not).
To investigate if problem was being caused by the interaction between Proguard and Scala, I wrote java version of the code (I've just noticed it's slightly different, in that Payload is an inner class of CheckNetworkStatusOnStartup, but I don't think that is significant). The java version works fine! Here's the javap output:
class com.mysimplet.CheckNetworkStatusOnStartup extends android.os.AsyncTask<com.mysimplet.CheckNetworkStatusOnStartup$Payload, java.lang.Void, com.mysimplet.CheckNetworkStatusOnStartup$Payload> {
com.mysimplet.CheckNetworkStatusOnStartup();
protected com.mysimplet.CheckNetworkStatusOnStartup$Payload doInBackground(com.mysimplet.CheckNetworkStatusOnStartup$Payload...);
protected void onPostExecute(com.mysimplet.CheckNetworkStatusOnStartup$Payload);
protected void onPostExecute(java.lang.Object);
protected java.lang.Object doInBackground(java.lang.Object...);
}
Notice the difference between the method definitions for doInBackground:
Scala: public com.ovaphone.Payload doInBackground(scala.collection.Seq<com.ovaphone.Payload>);
vs
Java: protected com.ovpahone.Payload doInBackground(com.ovaphone.Payload...);
So, Scala has transformed the varargs into a Seq. Maybe that's confusing Proguard? Anyone any ideas?
As a workaround, I've included the java version of the class in my project, but it would be nice to get the Scala version working soon.