Scala Android AsyncTask will not call publishProgress callback, "onProgressUpdate"

I spent too many hours on this, and so far I have continued to live without the publishProgress () function ... fortunately, onPostExecute also works in the UI thread, so I had to create N threads for every image I want to upload instead one large thread that was supposed to update the listview. So, not fatal, but real annoyance.

First of all, the big thianks to these pages to provide a deeper understanding and paths [links 2!] Have a clean Scala implementation ...

(1) http://blog.nelsonsilva.eu/2009/10/31/scala-on-android-101-proguard-xmlparser-and-function2asynctask , which is a workaround for: issues.scala-lang.org browse SI -1459 (New users limited to 2 links)

(2) va.eu/2009/10/31/ scala-on-android-101-proguard-xmlparser-and-function2asynctask, which is a workaround for: SAME AS ABOVE

(3) http://www.assembla.com/code/scala-eclipse-toolchain/git/nodes/docs/android-examples/android-sdk/Wiktionary/src/com/example/android/wiktionary/MyAsyncTask.java ? rev = f2fdb3144d0225487cafc7d628adf64889772db4

Unfortunately, none of them seemed to work for me on Scala 2.8.1 with Android 2.2.2 running Android-x86 on a virtual field, Ubuntu 11.04.

Here is my actual code, the garbage was deleted, just the main thing ... if someone can tell me how to make the call receive the call, I will be very happy, and it's not even Christmas. I spent hours on it and I can’t get it to work at all, I tried every option like “Progress”, since using AnyRef really works, but any other type doesn’t work like “Params” type, see (2) above for details on this one.

Alas, I get preExecute (not shown), doInBackground and postExecute, but you should not post progress callbacks. :(

Code...

private class FeedLoaderTask(val activity: ActivityFeedReader) extends android.os.AsyncTask[AnyRef, Seq[FeedEntry], Seq[FeedEntry]] { /** @brief dialog to show our progress */ private var dlgBusy:ProgressDialog = null; override def onPreExecute() { dlgBusy = ProgressDialog.show(...) } override protected def doInBackground(params: AnyRef*): Seq[FeedEntry] = { // resorted to AnyRef for reasons explained above although val url = params.apply(0).asInstanceOf[String] log.d("FeedLoaderTask: doInBackground: " + url) val feeds = new FeedReader(url).extract log.d("Got them, total: " + feeds.length) publishProgress()//feeds) // <--- seems to "call" but does not arrive feeds } protected def onProgressUpdate(feeds: Seq[FeedEntry]): Void = { // work damn you, WORK! log.d("FeedLoaderTask: onProgressUpdate: " + feeds.length) return null } override protected def onPostExecute (feeds: Seq[FeedEntry]) { dlgBusy.dismiss() dlgBusy = null feeds.length match { case 0 => messageAndTerminate(R.string.rss_failed_msg) case _ => listAdapter = new FeedListAdapter(...) activity.setListAdapter(listAdapter) ...blah blah more code... } } } 

So, I have a job (maybe even a better way) to do what I want, but I hate that I can’t do what I want.

It would be nice to see how he was beaten ... this is my first Android application, and I almost finished it once in Java, but I got so freaking with all the typed and cool ones that I started with a scratch and taught me Scala in the same time. I know Erlang, LISP and Haskell to help. All I can say is “LEARN Scala NOW!” ... XML support is awesome, my RSS parsing source code (four classes!) Is now in a single file and about 80 lines of code using the XML API to find elements, extract attributes, etc.

All the best :)

+4
source share
3 answers

I just tried something similar and, well, I ran into the same question as you. I solved it with

defining class as

 class FeedLoaderTask(val activity: ActivityFeedReader) extends AsyncTask[AnyRef, AnyRef, Seq[FeedEntry]] 

and my onProgressUpdate as:

 override def onProgressUpdate(params: AnyRef*) { val feeds = params(0).asInstanceOf[Seq[FeedEnty]] ... } 

As you can see, it is similar to the doInBackground () method (note that you do not need to explicitly refer to apply () in Scala, and void methods do not need to declare the type of the return value, but "=").

+2
source

protected override def onProgressUpdate (progress: Seq [FeedEntry] *) {}

You probably want to specify your AsyncTask as AsyncTask [AnyRef, FeedEntry, Seq [FeedEntry]]

So you can do

protected override def onProgressUpdate (channels: FeedEntry *)

instead

0
source

It is useful to do the conversion between arguments and .... By creating a new java class that mixes both, I could achieve the result:

 import scala.collection.mutable.ArrayBuffer; import android.os.AsyncTask; public abstract class MyAsyncTask<U, V, W> extends AsyncTask<U, V, W> { @Override protected W doInBackground(U ... args) { int count = args.length; ArrayBuffer<U> res = new ArrayBuffer<U>(count); for (int i = 0; i < count; i++) { res.$plus$eq(args[i]); } return doInBackground1(res); } // Method to override in the scala file protected abstract W doInBackground1(ArrayBuffer<U> args); ArrayBuffer<V> res = new ArrayBuffer<V>(); @Override protected void onProgressUpdate(V ... args) { int count = args.length; res.ensureSize(count); res.clear(); ArrayBuffer<V> res = new ArrayBuffer<V>(count); for (int i = 0; i < count; i++) { res.$plus$eq(args[i]); } onProgressUpdate1(res); } // Method to override in the scala file protected abstract void onProgressUpdate1(ArrayBuffer<V> args); } 
0
source

All Articles