【问题标题】:Android: trying to add a wait in between two animations, getting Object not locked by thread before wait() errorAndroid:尝试在两个动画之间添加等待,在等待()错误之前获取对象未被线程锁定
【发布时间】:2014-02-11 19:39:22
【问题描述】:

我是 Android 和 Java 编程新手。我为 Coursera 课程创建了一个应用程序。它有两个重复出现的动画。我希望它们像鼓一样动起来 - 1,2,1,2,1,2,1,2,1,2。

我编写了两个递归方法,它们在用户单击重置按钮之前一直运行。我尝试在方法调用之间添加一个等待,以便第二个在第一个之后立即启动。

这是我的代码中有等待的部分。

mHandler = new Handler(); // .os package class when importing
        mLeftfoot = findViewById(R.id.leftfoot);
        mRightfoot = findViewById(R.id.rightfoot);  
        mFootAnim = AnimationUtils.loadAnimation(this, R.anim.foot); //this looks to the foot.xml file for the animations
        leftstepRecursive();
        try {
            wait(600);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        rightstepRecursive();

我的这部分代码显示了递归方法,据我所知,这些方法可能会写得更好。很多干...

private void leftstepRecursive() {
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                mLeftfoot.startAnimation(mFootAnim);
                if (!pleaseStop)
                    leftstepRecursive();
            }
        }, mIntervalleft);}

    private void rightstepRecursive() {
            mHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    mRightfoot.startAnimation(mFootAnim);
                    if (!pleaseStop)
                        rightstepRecursive();
                }
            }, mIntervalright);

有没有更好的想法来实现这个左、右、左、右、左、右、左、右、左、右、想法?

或者,我可以做些什么来纠正等待?

我也试过这个:

private void rightstepRecursive() {
            mHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    Object testobj = mRightfoot.startAnimation(mFootAnim);
                    synchronized (testobj) {
                        testobj.wait(600);
                    }
                    if (!pleaseStop)
                        rightstepRecursive();
                }
            }, mIntervalright);

@LuigiMendoza。我试过线程(睡眠)。没有错误,但两个动画同时移动不知道为什么......

private void rightstepRecursive() {
            mHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    mRightfoot.startAnimation(mFootAnim);
                    if (!pleaseStop)
                        rightstepRecursive();
                }
            }, mIntervalright);

            try
            {
                Thread.sleep(500);
            } catch (InterruptedException e)
            {
                e.printStackTrace();
            }
}

我也在 Logcat 中重复收到此消息。

02-11 12:15:32.261: I/Choreographer(30480): Skipped 302 frames!  The application may be doing too much work on its main thread.

【问题讨论】:

  • 我不确定在这种情况下您是否应该使用waitThread.sleep
  • 查看我上面的 Thread.sleep ......它不起作用。两个动画同时发生。我希望 mRightfoot 在 mLeftfoot 之后 500 毫秒启动。
  • 请不要在你的问题标题前加上Android,底部的标签绰绰有余。您不想使用Thread.sleep()wait(需要同步,请参阅stackoverflow.com/questions/1036754/…)。无需实际睡眠即可启动正确的方法,只需使用相同的Handler 方法在调用左侧动画的行之后发布延迟消息(600 毫秒后),在延迟 Runnable 中只需调用您想在 600 毫秒后开始的正确方法。
  • 卢克普罗。谢谢!好的,没有更多的 Android 前缀。您能否发布您的代码示例。你的回应应该得到认可。
  • 哦,我的意思是发布任何答案,而不是评论。您应该获得信用而不是 u/Submersed。他/她的回答很有帮助,但并没有直接解决我发布的代码的当前问题。

标签: java android multithreading wait


【解决方案1】:

您应该真正利用Animations 框架和它提供的一些类,例如AnimationListeners 和AnimatorSets。 Animations 框架提供了许多功能,可以真正简化您正在尝试做的事情,例如重复动画、添加延迟、定时动画等。

这里有一个非常简单的例子来给出基本的想法:

AnimatorSet animations;

//Play the animation
private void playAnimation(){       
    //If they haven't stopped the animation, loop it.
        ObjectAnimator anim1 = ObjectAnimator.ofFloat(target, propertyName, values);
        ObjectAnimator anim2 = ObjectAnimator.ofFloat(target, propertyName, values);
        animations = new AnimatorSet();
        animations.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                playAnimation();
            }
        });
        animations.play(anim1).before(anim2);
            animations.start();

}

//Called when cancel is selected
private void stopAnimation(){
    animations.end();
}

【讨论】:

  • 谢谢,乍一看,处理程序/递归方法的代码似乎更容易理解。在我的代码中,实际的动画位于 foot.xml 中,在那里更改动画(滑动、不透明)很容易。您在哪里处理代码中的实际动画?目标、属性名称、值?
  • Target 是对象,因此您的视图,propertyName 是您正在制作动画的内容......所以,这可能是“x”或“y”等,而 values 是您的开始和结束,或者只是结束值(如果您只指定一个值,它会将其视为结束值)。这一切都在文档中。
  • 另外,请注意您也可以在 xml 中创建 objectAnimators。
  • 不确定你是否还在检查这个,但我使用递归方法修复了我的其他方式。在您的示例中,我将在哪里控制 anim1 和 anim2 之间的间隔/速度?
  • 通过设置自定义/不同的Interpolator,见setInterpolator
猜你喜欢
  • 1970-01-01
  • 2012-05-24
  • 1970-01-01
  • 2017-03-17
  • 2014-12-22
  • 2018-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多