2011/6/22 Vadim Khondar <vadim.khon...@gmail.com>

> But code that sets ProgressBar value and text of TextView within this
> method does not cause screen redraw.
>

Then there is a problem with how you update the UI.

Since list view recycles item views, you may not be updating the view you
think you are updating.

In general, I can tell you this architecture works (and there is a lot of
envidence besides just my saying so - e.g. the Market application with its
download progress updates).

In my code, the callbacks are all pure Java (not Intents), state changes
originate from worker threads and are marshalled to the UI thread within the
service by using a Handler.

The code that updates {Expandable}ListView iterates its children until it
finds a child layout that matches the current state change, calls
findViewById to get the relevant views, and calls regular UI changing
methods to reflect the state change (setText, setProgress, setVisibility,
etc.)

The key methods are: getFirstVisiblePosition and getLastVisiblePosition in
AdapterView.

-- Kostya



> Also I've tried to explicitly call invalidate() on views which need to
> be updated with no luck.
>
> There are people with the same problem on the internet (several
> threads on stackoverflow etc) but the only valuable advices are
> related to usage of broadcast reciever and interacting with activity
> from service through intents.
> So that is why I wonder are there workable alternatives to that approach?
>
> I register listener as anonymous class within custom adapter:
>
> public View getView(int position, View contentView, ViewGroup parent) {
>                Object item = mDownloads.get(position);
>                LayoutInflater li = (LayoutInflater)
> mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
>
>                                        if (contentView == null) contentView
> =
> li.inflate(R.layout.active_download_row, null);
>                                        tvDownloadSize = (TextView)
> contentView.findViewById(R.id.tvSize);
>                                        pbDownloadProgress = (ProgressBar)
> contentView.findViewById(R.id.pbProgress);
>
>  mDownloadService.registerDownloadMonitor(d, new IDownloadMonitor() {
>
>                                                public void
> onStop(Integer... progresses) {
>
>  pbDownloadProgress.setProgress(progresses[0]);
>
>  tvDownloadSize.setText("0 kb");
>                                                }
>
>                                                public void onStart() {}
>
>                                                public void onProgress(final
> Integer... progresses) {
>                                                        ((Activity)
> mContext).runOnUiThread(new Runnable() {
>                                                                public void
> run() {
>
>  Log.d("DOWN", "IDownloadMonitor::onProgress
> Activity::runOnUiThread Runnable::run " + Thread.currentThread());
>
>  pbDownloadProgress.setProgress(progresses[0]);
>
>  pbDownloadProgress.postInvalidate();
>
>  tvDownloadSize.setText(progresses[0].toString() + " kb");
>                                                                }
>                                                        });
>
>
>  Log.d(mContext.getPackageName(), "Download id " + d.getID() + "
> progress is " + progresses[0]);
>                                                }
>
>                                                public void onFinish(File
> result) {
>
>  notifyDataSetChanged();
>                                                }
>
>                                                public Object
> getMonitorTag() {
>                                                        return
> mContext.getPackageName();
>                                                }
>                                        });
>
>                return contentView;
>        }
>
> And here is snip of logcat:
>
> D/DOWN (  226): DownloadTask::doInBackground Thread[AsyncTask #1,5,main]
> D/DOWN (  226): DownloadTask::onProgress Thread[ActivityThread,5,main]
> D/DOWN (  226): IDownloadMonitor::onProgress Activity::runOnUiThread
> Runnable::run Thread[ActivityThread,5,main]
> D/com.play.downloader(  226): Download id 24 progress is 2
> D/DOWN (  226): DownloadTask::onProgress Thread[ActivityThread,5,main]
> D/DOWN (  226): IDownloadMonitor::onProgress Activity::runOnUiThread
> Runnable::run Thread[ActivityThread,5,main]
> D/com.play.downloader(  226): Download id 24 progress is 4
> D/DOWN (  226): DownloadTask::onProgress Thread[ActivityThread,5,main]
>
> That ActivityThread is actually main and was intentionally renamed by
> me with Thread.currentThread().setName("ActivityThread"); from within
> onCreate() of Activity whose controls I'm trying to update so that to
> see whether methods really run on the main thread.
>
>
> 2011/6/22 Kumar Bibek <coomar....@gmail.com>:
> > Have you tried logging your listener calls? See if those are actually
> > being called.
> >
> >
> > On Jun 19, 4:46 am, "Vadim S. Khondar" <vadim.khon...@gmail.com>
> > wrote:
> >> Hello to everyone.
> >>
> >> I have an application with service doing background work by
> >> instantiating AsyncTasks and activity displaying progress of that
> >> work.
> >>
> >> As soon as updates are expected to be quite often I preferred to make
> >> connection between service and activity through listener rather than
> >> via broadcast intents/receiver.
> >> General lifecycle of application as intended by design I've tried is
> >> the following:
> >> Activity starts -> binds to service in onCreate -> registers listener
> >> to the particular AsyncTask within service after bind succedes ->
> >> receives updates -> unregisters listener in onPause -> unbinds in
> >> onDestroy
> >> This works fine (log shows it works as expected) but I've got a
> >> problem with updating UI in activity.
> >>
> >> I understand that activity UI updates must be performed on UI-thread.
> >> And that I've checked first and it seem to be ok, as soon as code with
> >> updates within listener runs on main thread just like activity's on*()
> >> methods. To ensure this I've also tried to wrap code in listener with
> >> posting runnable to runOnUiThread() of my activity. That also gives
> >> nothing (UI updates happen in one instance of emulator and do not
> >> happen in another and also on real device, however screen is updated
> >> if I scroll contents down and back).
> >>
> >> So the question is whether described scenario is possible on Android
> >> or should I just use broadcast receiver as the only way to accomplish
> >> my goal?
> >>
> >> Thanks in advance.
> >
> > --
> > You received this message because you are subscribed to the Google
> > Groups "Android Developers" group.
> > To post to this group, send email to android-developers@googlegroups.com
> > To unsubscribe from this group, send email to
> > android-developers+unsubscr...@googlegroups.com
> > For more options, visit this group at
> > http://groups.google.com/group/android-developers?hl=en
>
>
>
> --
> Best regards,
>  Vadim
>
> God, grant me the serenity to accept the things I cannot change,
> courage to change the things I can,
> and wisdom always to tell the difference.
> Rainhold Niebuhr
>
> --
> You received this message because you are subscribed to the Google
> Groups "Android Developers" group.
> To post to this group, send email to android-developers@googlegroups.com
> To unsubscribe from this group, send email to
> android-developers+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/android-developers?hl=en
>

-- 
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

Reply via email to