android - AsyncTask.doInBackground - Android Scala 项目中抽象方法未实现错误

标签 android scala proguard

任何人都可以给我任何关于如何调试以下内容的线索。

我有一个混合的 java/scala android 项目,我正在 Intellij 中处理它,我通过 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 的类,而且我知道这个类绝对是罪魁祸首,因为当我注释掉它的使用时,问题就消失了。

我的异步任务是:

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 版本能够尽快运行那就太好了。

最佳答案

这可能会有所帮助。

http://piotrbuda.eu/2012/12/scala-and-android-asynctask-implementation-problem.html

签名问题我大胆猜测一下。

我自己也遇到了同样的问题,更改签名解决了我的问题。

关于android - AsyncTask.doInBackground - Android Scala 项目中抽象方法未实现错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24934022/

相关文章:

android - 如何在 proguard 中保留包级 kotlin 函数?

android - 当我导出应用程序时出现混淆错误

android - FFMPEG 图像到视频 - 命令中出现 'file not found' 错误 - 我确信这很明显

java - KitKat FloatingActionButton 有额外的边距

scala - 如何在具有隐式参数的函数上调用 Private

scala - 使用列名数组聚合 Spark 数据框,保留名称

android - 在不下载图像的情况下计算图像的尺寸/大小

android - 如何在Android开发者控制台上删除应用程序

scala - 将 A => M[B] 转换为 M[A => B]

Android Proguard Release导致不执行for-loop