任何人都可以给我任何关于如何调试以下内容的线索。
我有一个混合的java / scala android项目,我正在Intellij中工作,我通过Proguard处理它作为run config的一部分。
当我运行应用程序时,我收到错误:
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)
我猜这是由于Proguard剥离太多造成的。
我确实有一个扩展AsyncTask的类,我知道这个类肯定是罪魁祸首,因为当我注释掉它的使用时,问题就消失了。
我的AsyncTask是:
object CheckNetworkStatusOnStartup {
class Payload(var mainActivity: MainActivity) {
var isConnected: java.lang.Boolean = false
}
}
类CheckNetworkStatusOnStartup扩展了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>
}
}
它在MainActivity中被调用:
new CheckNetworkStatusOnStartup().execute(new CheckNetworkStatusOnStartup.Payload(this))
我尝试过添加两者:
-keep class * extends android.os.AsyncTask {
*;
}
和
-keep public class com.mypackage.MyClass extends android.os.AsyncTask
到proguard配置文件但是没有区别。
那些“保证”的陈述应该足够吗?
任何人都可以给我任何关于如何进行的指示吗?
修改
根据Eric的建议,在编译的类上运行javap会得到以下输出:
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();
}
在进程apk上运行dexdump表明缺少doInBackground(但是onPastExecute没有)。
为了调查问题是由Proguard和Scala之间的交互引起的,我编写了java版本的代码(我刚刚注意到它略有不同,因为Payload是CheckNetworkStatusOnStartup的内部类,但我没有认为这很重要)。 java版工作正常!这是javap输出:
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...);
}
注意doInBackground的方法定义之间的区别:
Scala: public com.ovaphone.Payload doInBackground(scala.collection.Seq<com.ovaphone.Payload>);
VS
Java: protected com.ovpahone.Payload doInBackground(com.ovaphone.Payload...);
因此,Scala已将varargs转变为Seq。也许那令人困惑的Proguard?任何想法?
作为一种解决方法,我已经在我的项目中包含了该类的java版本,但是很快就能让Scala版本正常工作。
答案 0 :(得分:2)
这可能有所帮助。
http://piotrbuda.eu/2012/12/scala-and-android-asynctask-implementation-problem.html
签名问题我猜错了。
我自己也遇到了同样的问题,更改签名解决了我的问题。
答案 1 :(得分:1)
您应确保ProGuard获得合适的Android运行时(android.jar)。根据您的构建过程,它会自动添加(例如Android Ant,Gradle,Eclipse),或者您必须使用选项-libraryjars
自行添加(例如自定义构建)。
请注意,您可以查看ProGuard正在应用的配置
-printconfiguration config.txt
然后,您应该检查-injars
和-libraryjars
选项。
如果没有正确的运行时jar,ProGuard通常会打印出许多警告,默认情况下拒绝继续。它需要运行时类来分析应用程序的结构。例如,在这种情况下,它需要知道运行时接口方法,因此它不会从实现中删除它们。