Okay, actually, you can disregard that last comment.
"Thou shalt not modify the UI from a background thread, for that is
the way of sin" pretty explicitly gives me my answer.   I gotta say,
this is pretty inconvenient.  Must be the reason that Electrum Drum
Machine (the only other Android drum sequencer I've seen) doesn't give
the user any visual indication of playback position.
Thanks all the same, though
-Nick Zaillian

On Aug 30, 5:39 pm, Nick_Zaillian <[email protected]> wrote:
> Alright, I have made the appropriate changes to my SeqSwitch class so
> that I no longer call setBackgroundResource from my onDraw (and in
> fact no longer override onDraw at all).  Now, Mark, I have written an
> audio pattern playback implementation using a Handler that runs in my
> main Activity and, while it works, it is way less smooth and reliable
> than the implementation using the Timer/separate thread.  I tried to
> wade through the docs for AsyncTask and I could not tell whether or
> not it would allow me to update the UI from my separate Timer thread.
> Will it, or do I just have to choose between having smooth audio
> playback in a separate thread but no visual feedback and having less
> reliable audio playback in my UI thread with visual feedback?
> Thanks again,
> Nick Zaillian
>
> On Aug 30, 4:13 pm, Romain Guy <[email protected]> wrote:
>
> > You should call setBackgroundResource() but NOT from onDraw(). Just
> > call this method from setIlluminated() for instance.
>
> > On Sun, Aug 30, 2009 at 1:06 PM, Nick_Zaillian<[email protected]> wrote:
>
> > > Mark and Romain,
> > > Thanks.  That was a much prompter response than I either expected or
> > > deserved.
> > > Romain, I am not sure that I totally understand what you've said.  How
> > > am I to set the background in accordance with the state of isChecked
> > > and isIlluminated from within onDraw if not by calling
> > > setBackgroundResource()?  I guess this post probably belongs in the
> > > Android Beginner's group.
> > > Thanks,
> > > Nick Zaillian
>
> > > On Aug 30, 2:59 pm, Romain Guy <[email protected]> wrote:
> > >> Do not call setBacgroundResource() in onDraw()! You are loading and
> > >> setting an image every time your view is drawn. You are actually
> > >> creating a infinite "loop";
>
> > >> onDraw() -> setBacgroundResource() -> invalidate() -> onDraw() ->
> > >> setBacgroundResource() -> etc.
>
> > >> On Sun, Aug 30, 2009 at 11:47 AM, Nick_Zaillian<[email protected]> 
> > >> wrote:
>
> > >> > Hey all,
> > >> > I am writing an app that emulates a drum machine with a step
> > >> > sequencer.  For those unfamiliar with step sequencers, a step
> > >> > sequencer is basically a set of switches where the state of each
> > >> > switch indicates whether or not a sound is to be played at a
> > >> > particular point in a pattern.  I've already got audio playback
> > >> > working using SoundPool and can play patterns (represented as objects
> > >> > containing boolean arrays mapped to audio resources) by stepping
> > >> > through these patterns using a timer.  What I am trying and struggling
> > >> > to do at present is to write my UI.  I have subclassed ToggleSwitch
> > >> > and made a custom switch called SeqSwitch which, in addition to
> > >> > ToggleSwitch's isChecked field, also holds an isIlluminated field.
> > >> > I've written another class called SwitchController that takes an array
> > >> > of these switches and has a method (which I've called runSwitches)
> > >> > that, with each call, advances one switch, illuminates the current
> > >> > switch, and unilluminates the previous switch (the idea is that, when
> > >> > the user plays his pattern, the button representing the current step
> > >> > will illuminate, letting him know the current position of playback in
> > >> > the sequence).  The SeqSwitches seem to render and behave fine in
> > >> > response to clicks.  My SwitchController.runSwitches method also works
> > >> > so long as I place it in a click handler of a button in my main
> > >> > Activity.  When, however, I pass it into the runnable (called
> > >> > PatternPlayTask) that I give to my Timer (which then calls
> > >> > SwitchController.runSwitches every 300 milliseconds as it steps
> > >> > through the pattern), it stops working.  I have used the debugger to
> > >> > make sure that the object I am passing into the runnable is the same
> > >> > as the one for which the call to SwitchController.runSwitches was
> > >> > working in the main activity and have found that definitely it is.
> > >> > Does anybody have any idea what's going on here.  Hopefully I am just
> > >> > doing something totally stupid, here.  I've pasted the code for my
> > >> > ToggleButton subclass below, if that helps:
>
> > >> > package com.drummachine;
> > >> > import android.widget.*;
> > >> > import android.view.*;
> > >> > import android.content.Context;
> > >> > import com.drummachine.Instrument;
> > >> > import android.util.*;
> > >> > import android.content.res.TypedArray;
> > >> > import android.graphics.Canvas;
> > >> > import android.graphics.Paint;
> > >> > import android.graphics.drawable.*;
> > >> > import android.util.AttributeSet;
> > >> > import android.view.View;
>
> > >> > public class SeqSwitch extends ToggleButton {
>
> > >> >        //SeqSwitch holds an isIlluminated state.
> > >> >        //if isIlluminated is true, onDraw will render an illuminated
> > >> >        //button image as the SeqSwitch's drawable (currently the same 
> > >> > image
> > >> > used for
> > >> >        //a ToggleButton whose isChecked == true)
> > >> >        public boolean isIlluminated;
>
> > >> >        public SeqSwitch(Context context)
> > >> >        {
> > >> >                super(context);
> > >> >                isIlluminated = false;
>
> > >> >        }
>
> > >> >        //constructor called when params are taken from XML layout
> > >> >    public SeqSwitch(Context context, AttributeSet attributes) {
> > >> >        super(context, attributes);
>
> > >> >        TypedArray a = context.obtainStyledAttributes(attributes,
> > >> >                R.styleable.SeqSwitch);
>
> > >> >       isIlluminated = false;
> > >> >       super.setBackgroundResource
> > >> > (R.drawable.seqswitchbackgroundsoneoff);
>
> > >> >        a.recycle();
> > >> >    }
>
> > >> >    public void setIlluminated(boolean state)
> > >> >    {
> > >> >        isIlluminated = state;
> > >> >        this.invalidate();
>
> > >> >    }
>
> > >> >    //yes, I know having illumniate() and unIlluminate() methods is
> > >> > redundant
> > >> >    //when I have a setIlluminated(boolean) method, but I am presently
> > >> > too lazy
> > >> >    //to rearrange code elsewhere that presently relies on these two
> > >> > methods.
> > >> >    public void unIlluminate()
> > >> >    {
> > >> >        isIlluminated = false;
> > >> >        this.invalidate();
> > >> >    }
>
> > >> >    public void illuminate()
> > >> >    {
> > >> >        isIlluminated = true;
> > >> >        this.invalidate();
> > >> >    }
>
> > >> >    public boolean switchIsIlluminated()
> > >> >    {
> > >> >        return isIlluminated;
> > >> >    }
>
> > >> >    /**
> > >> >     * renders a image of a switch with an illuminated LED if either
> > >> > the SeqSwitch's isChecked or
> > >> >     * isIllumniated == true.  Otherwise it renders a drawable of a
> > >> > button with an unIlluminated LED
> > >> >     */
> > >> >    public void onDraw(Canvas canvas)
> > >> >    {
> > >> >        if(super.isChecked() == true || this.isIlluminated == true)
> > >> >        {
> > >> >                super.setBackgroundResource
> > >> > (R.drawable.seqswitchbackgroundsoneonon);
> > >> >        }
> > >> >        else
> > >> >        {
> > >> >                super.setBackgroundResource
> > >> > (R.drawable.seqswitchbackgroundsoneoff);
> > >> >        }
>
> > >> >    }
> > >> > }
>
> > >> > Thanks,
> > >> > Nick Zaillian
>
> > >> --
> > >> Romain Guy
> > >> Android framework engineer
> > >> [email protected]
>
> > >> Note: please don't send private questions to me, as I don't have time
> > >> to provide private support.  All such questions should be posted on
> > >> public forums, where I and others can see and answer them
>
> > --
> > Romain Guy
> > Android framework engineer
> > [email protected]
>
> > Note: please don't send private questions to me, as I don't have time
> > to provide private support.  All such questions should be posted on
> > public forums, where I and others can see and answer them
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to