I have spent too many hours on this and I have so far continued to live without the publishProgress() feature… fortunately the onPostExecute also runs in the UI thread so I have had to create N threads for every image I want to load instead of one big thread that was to update the listview. So, not fatal but a real annoyance.
First of all, big thianks to these pages for providing more insight and ways to [reference 2!] have a pure 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
Sadly, none of them seemed to work for me on Scala 2.8.1 with Android 2.2.2 running Android-x86 on Virtual box, Ubuntu 11.04.
Here’s my actual code, garbage removed, just the essentials… if somebody can tell me how to make the callback get called I will be very happy and it’s not even Christmas yet. I’ve spent hours on the this and cannot get it to work at all, I have tried every variation of “Progress” type, as using AnyRef actually works but any other type doesn’t work as the “Params” type, see (2) above for the details on that one.
Alas, I get the preExecute (not shown), doInBackground and postExecute but no publish progress callbacks to be seen. 🙁
The 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 work-around (maybe even a better way) of doing what I want but I hate not being able to do what I want.
This would be a nice one to see solved as its’s beaten me… this is my first Android app and I nearly finished it once in Java but I got so frikking cheesed off with all the typing and cruft that I started from scratch and taught myself Scala at the same time. I know Erlang, LISP and Haskell so that helped. All I can say is “LEARN SCALA NOW!”… the XML support is awesome, my original RSS parsing 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,
🙂
I just tried something similar and, well, ran into the same issue as you did.
I solved it with
defining the class as
and my onProgressUpdate as:
As you can see, it is similar to the doInBackground() method (note that you do not necessarily need to explicitly call apply() in Scala and void methods do not need to declare a return type and the “=”).