QA@IT
«質問へ戻る

質問を投稿

Scala(sbt-android-plugin)でAndroidのAsyncTaskを使いたい

sbt-android-pluginを使用し、ScalaにてAndroidアプリを作成しているのですが、android.os.AsyncTask<Params, Progress, Result> を使用しようとすると書き方が悪いのかAbstractMethodErrorとなってしまい困っています。

下記のURL先のようにJavaで可変長引数メソッドを上書きしてみるとうまくいくのですが、Scalaだけで何とかする方法はありませんでしょうか?
https://gist.github.com/1175555

今回作成したサンプルのソース

package jp.ponko2.android.sample

import _root_.android.app.Activity
import _root_.android.os.Bundle
import _root_.android.os.AsyncTask
import _root_.android.os.AsyncTask.Status
import _root_.android.widget.{TextView, Toast}
import _root_.android.view.Window

class MainActivity extends Activity {
  private lazy val mTask = new TestTask

  override def onCreate(savedInstanceState: Bundle) {
    super.onCreate(savedInstanceState)

    requestWindowFeature(Window.FEATURE_PROGRESS)
    requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS)

    val values = Seq(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

    setContentView(new TextView(this) {
      setText(values.mkString(" + ") + " = ")
    })

    mTask.execute(values:_*)
  }

  override protected def onDestroy() {
    super.onDestroy()

    if (mTask.getStatus == Status.RUNNING) {
      mTask cancel true
    }
  }

  private class TestTask extends AsyncTask[Int, Int, Int] {
    override protected def onPreExecute() {
      setProgressBarVisibility(true)
      setProgressBarIndeterminateVisibility(true)
    }

    override protected def doInBackground(values: Int*): Int = {
      val count = values.length
      var total = 0
      for (i <- 0 until count) {
        publishProgress(((i / count.toFloat) * 10000).toInt)
        Thread.sleep(500)
        total += values(i)
      }
      total
    }

    override protected def onProgressUpdate(progress: Int*) {
      setProgress(progress(0))
    }

    override protected def onPostExecute(result: Int) {
      setProgressBarVisibility(false)
      setProgressBarIndeterminateVisibility(false)
      Toast.makeText(MainActivity.this, result.toString, Toast.LENGTH_LONG).show()
    }
  }
}

ログ

FATAL EXCEPTION: AsyncTask #1
java.lang.RuntimeException: An error occured while executing doInBackground()
    at android.os.AsyncTask$3.done(AsyncTask.java:278)
    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:208)
    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:264)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
    ... 5 more

実行環境

  • Scala 2.9.2
  • sbt 0.12.0
  • android-plugin 0.6.2
sbt-android-pluginを使用し、ScalaにてAndroidアプリを作成しているのですが、`android.os.AsyncTask<Params, Progress, Result>` を使用しようとすると書き方が悪いのかAbstractMethodErrorとなってしまい困っています。

下記のURL先のようにJavaで可変長引数メソッドを上書きしてみるとうまくいくのですが、Scalaだけで何とかする方法はありませんでしょうか?
https://gist.github.com/1175555

### 今回作成したサンプルのソース
```scala
package jp.ponko2.android.sample

import _root_.android.app.Activity
import _root_.android.os.Bundle
import _root_.android.os.AsyncTask
import _root_.android.os.AsyncTask.Status
import _root_.android.widget.{TextView, Toast}
import _root_.android.view.Window

class MainActivity extends Activity {
  private lazy val mTask = new TestTask

  override def onCreate(savedInstanceState: Bundle) {
    super.onCreate(savedInstanceState)

    requestWindowFeature(Window.FEATURE_PROGRESS)
    requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS)

    val values = Seq(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

    setContentView(new TextView(this) {
      setText(values.mkString(" + ") + " = ")
    })

    mTask.execute(values:_*)
  }

  override protected def onDestroy() {
    super.onDestroy()

    if (mTask.getStatus == Status.RUNNING) {
      mTask cancel true
    }
  }

  private class TestTask extends AsyncTask[Int, Int, Int] {
    override protected def onPreExecute() {
      setProgressBarVisibility(true)
      setProgressBarIndeterminateVisibility(true)
    }

    override protected def doInBackground(values: Int*): Int = {
      val count = values.length
      var total = 0
      for (i <- 0 until count) {
        publishProgress(((i / count.toFloat) * 10000).toInt)
        Thread.sleep(500)
        total += values(i)
      }
      total
    }

    override protected def onProgressUpdate(progress: Int*) {
      setProgress(progress(0))
    }

    override protected def onPostExecute(result: Int) {
      setProgressBarVisibility(false)
      setProgressBarIndeterminateVisibility(false)
      Toast.makeText(MainActivity.this, result.toString, Toast.LENGTH_LONG).show()
    }
  }
}
```

### ログ
```
FATAL EXCEPTION: AsyncTask #1
java.lang.RuntimeException: An error occured while executing doInBackground()
	at android.os.AsyncTask$3.done(AsyncTask.java:278)
	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:208)
	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:264)
	at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
	... 5 more
```

### 実行環境
* Scala 2.9.2
* sbt 0.12.0
*  android-plugin 0.6.2