【发布时间】:2014-09-16 00:38:40
【问题描述】:
谁能给我任何关于如何调试以下内容的线索。
我在 Intellij 中有一个混合的 java / scala android 项目,我通过 Proguard 处理它作为运行配置的一部分。
当我运行应用程序时出现错误:
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 配置文件,但两者都没有区别。
那些“-keep”语句就足够了吗?
谁能给我任何关于如何进行的指示?
编辑
按照 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>);
对
Java: protected com.ovpahone.Payload doInBackground(com.ovaphone.Payload...);
因此,Scala 已将可变参数转换为 Seq。也许这让 Proguard 感到困惑?有人有什么想法吗?
作为一种解决方法,我已经在我的项目中包含了该类的 java 版本,但如果 Scala 版本能够尽快运行,那就太好了。
【问题讨论】:
-
你的 AsyncTask 是什么样子的,能贴出代码吗?
-
当然 - 有点长,你想看全部还是只看定义?
-
我已经添加了一个总结版本,希望这就足够了。我认为整个代码会污染线程。谢谢你的帮助,顺便说一句。
-
没问题,我认为您需要像使用 onPostExecute 一样覆盖 doInBackground。
-
好地方!但是,只是添加了它,它似乎没有任何区别。我会更新帖子。