AsyncTask.doInBackground-Android Scala项目中未实现抽象方法错误 [英] AsyncTask.doInBackground - abstract method not implemented error in Android Scala project

查看:52
本文介绍了AsyncTask.doInBackground-Android Scala项目中未实现抽象方法错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

任何人都可以给我有关调试以下内容的任何线索.

Can anyone give me any clues on how to debug the following.

我在Intellij中正在处理一个混合的java/scala android项目,我将它作为运行配置的一部分通过Proguard进行处理.

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)

我猜这是由于Proguard剥离过多而引起的.

I'm guessing it's caused by Proguard stripping out too much.

我确实有一个扩展AsyncTask的类,并且我知道这个类绝对是罪魁祸首,因为当我注释掉它的使用时,问题就消失了.

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.

我的AsyncTask是:

My AsyncTask is:

object CheckNetworkStatusOnStartup {
  class Payload(var mainActivity: MainActivity) {
    var isConnected: java.lang.Boolean = false
  }

}

CheckNetworkStatusOnStartup类扩展了AsyncTask [CheckNetworkStatusOnStartup.Payload,Void,CheckNetworkStatusOnStartup.Payload] {

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>
  }

}

它在MainActivity中的调用方式是:

And it's called in the MainActivity by:

 new CheckNetworkStatusOnStartup().execute(new CheckNetworkStatusOnStartup.Payload(this))

我尝试将两者都添加:

-keep class * extends android.os.AsyncTask {
  *;
}

-keep public class com.mypackage.MyClass extends android.os.AsyncTask

到proguard配置文件,但两者都不起作用.

to the proguard config file but neither make a difference.

那些"-keep"语句是否足够?

Should those '-keep' statements be sufficient?

任何人都可以给我有关如何进行操作的任何指示吗?

Can anyone give me any pointers on how to proceed?

修改

按照Eric的建议,在已编译的类上运行javap会给出以下输出:

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();

}

在进程apk上运行dexdump显示缺少doInBackground(但没有onPastExecute).

Running dexdump on the process apk shows that doInBackground is missing (but onPastExecute is not).

要调查问题是否是由Proguard和Scala之间的交互引起的,我编写了Java版本的代码(我刚刚注意到它略有不同,因为Payload是CheckNetworkStatusOnStartup的内部类,但我没有认为很重要). Java版本工作正常!这是javap输出:

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...);
}

请注意doInBackground的方法定义之间的差异:

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...);

因此,Scala将可变参数转换为Seq.也许这会让Proguard感到困惑?任何想法吗?

So, Scala has transformed the varargs into a Seq. Maybe that's confusing Proguard? Anyone any ideas?

作为一种解决方法,我在项目中包含了该类的Java版本,但是最好尽快使Scala版本正常工作.

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.

推荐答案

您应确保ProGuard获得合适的Android运行时(android.jar).根据构建过程的不同,它会自动添加(例如Android Ant,Gradle,Eclipse),或者您必须使用选项-libraryjars(例如自定义构建)自己添加.

You should make sure that ProGuard gets a suitable Android runtime (android.jar). Depending on your build process, it is added automatically (e.g. Android Ant, Gradle, Eclipse) or you have to add it yourself with the option -libraryjars (e.g. custom build).

请注意,您可以看到ProGuard所应用的配置

Note that you can see which configuration ProGuard is applying with

-printconfiguration config.txt

然后应检查-injars-libraryjars选项.

在没有适当的运行时jar的情况下,ProGuard通常会打印出许多警告,并且默认情况下拒绝继续.它需要运行时类来分析应用程序的结构.例如,在这种情况下,它需要知道运行时接口方法,因此不会从实现中删除它们.

Without the proper runtime jar, ProGuard generally prints out many warnings and by default refuses to continue. It needs the runtime classes to analyze the structure of the application. In this case, for instance, it needs to know the runtime interface methods, so it doesn't remove them from your implementation.

这篇关于AsyncTask.doInBackground-Android Scala项目中未实现抽象方法错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆