java 如何在使用 postDelayed() 循环的 Android 中停止 Runnable?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13723874/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 13:47:02  来源:igfitidea点击:

How to stop Runnable in Android that's looping using postDelayed()?

javaandroidmultithreadingpostdelayed

提问by Amit Prajapati

I need to stop a Runnablefrom running when an image is clicked in my Android app. I'm running this Runnablerepeatedly using ImageView.postDelayed():

Runnable在我的 Android 应用程序中单击图像时,我需要停止运行。我正在Runnable反复使用ImageView.postDelayed()

r = new Runnable() {
    public void run() {
        imgview.setImageResource(imageArray[i]);
        i++;
        if (i >= imageArray.length) {
            i = 0;
        }
        imgview.postDelayed(r, 20); // set to go off again in 3 seconds.
        // imgview.setOnClickListener(this);
    }

};
imgview.postDelayed(r, 20); // set first time for 3 seconds

But under certain conditions I want to stop it from running, after it's already started. Here's the full code for my activity:

但在某些情况下,我想在它已经启动后阻止它运行。这是我的活动的完整代码:

    public class MainActivity extends Activity  {

        int i = 0;

        ImageView imgview, imgview2;
        Handler handler = new Handler();
        Runnable r;
        MediaPlayer mMediaPlayer;
        int[] imageArray = { R.drawable.f1, R.drawable.f2, R.drawable.f3,
                R.drawable.f4, R.drawable.f5, R.drawable.f6, R.drawable.f7,
                R.drawable.f8, R.drawable.f9, R.drawable.f10, R.drawable.f11,
                R.drawable.f12, R.drawable.f13, R.drawable.f14, R.drawable.f15,
                R.drawable.f16, R.drawable.f17, R.drawable.f18, R.drawable.f19,
                R.drawable.f20, R.drawable.f21, R.drawable.f22, R.drawable.f23,
                R.drawable.f24, R.drawable.f25, R.drawable.f26, R.drawable.f27,
                R.drawable.f28 };

        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.tapp_activity);

            imgview = (ImageView) findViewById(R.id.imageView1);

            mMediaPlayer = new MediaPlayer();
            mMediaPlayer = MediaPlayer.create(MainActivity.this, R.raw.water);
            mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);



            imgview2 = (ImageView) findViewById(R.id.imageView2);

            imgview2.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub




                    if(i==0)
                    {
                    mMediaPlayer.setLooping(true);
                    mMediaPlayer.start();
                    i=1;
                    r = new Runnable() {
                        public void run() {
                            imgview.setImageResource(imageArray[i]);
                            i++;
                            if (i >= imageArray.length) {
                                i = 0;
                            }
                            imgview.postDelayed(r, 20); // set to go off again in 3 seconds.
                            // imgview.setOnClickListener(this);
                        }

                    };
                    imgview.postDelayed(r, 20); // set first time for 3 seconds
                    }
                    else
                    {
                    i=0;

                    mMediaPlayer.stop();
                    imgview.setBackgroundResource(R.drawable.tapstill);
                    }



                }
            });


        }


        @Override
        protected void onDestroy() {
            // TODO Auto-generated method stub
            super.onDestroy();
            mMediaPlayer.stop();

        }



    }

What can I change in my code so that my Runnablestops running in the elsecondition of my onClick()method?

我可以更改代码中的哪些内容,以便Runnableelse我的onClick()方法条件下停止运行?

回答by cHao

You might try removing the callback.

您可以尝试删除回调。

imgview.removeCallbacks(r);

In order for this to work, though. you'd have to ensure that ris the same Runnableas the one you posted. You could do this by creating it once, possibly in onCreate. Since the Runnabledoesn't have any dependency on the ClickListeneranyway, this shouldn't be a problem.

但是,为了使其起作用。您必须确保它rRunnable您发布的相同。您可以通过创建一次来做到这一点,可能在onCreate. 由于无论如何Runnable都不依赖于ClickListener,因此这应该不是问题。

You might also need to do some synchronization in order to prevent the case where you're removing a currently running callback, though, now that i think about it. The volatile boolean runningidea is probably less complex overall.

您可能还需要进行一些同步,以防止您删除当前正在运行的回调的情况,但是,现在我想到了这一点。这个volatile boolean running想法总体上可能不那么复杂。

回答by Juvanis

You can control your run()method with a boolean flag:

您可以run()使用布尔标志来控制您的方法:

boolean running = true;
 ...

r = new Runnable()
{
         public void run() 
         {
             if(running)
             {
                 imgview.setImageResource(imageArray[i]);
                 i++;
                 if (i >= imageArray.length) {
                     i = 0;
                 }
                 imgview.postDelayed(r, 20); 
             }
         };
}

If you set running = falselater on, your thread will be idle and that's what you want.

如果您running = false稍后设置,您的线程将处于空闲状态,这就是您想要的。

回答by Nirav Tukadiya

You can do it by

你可以通过

         Thread.stop();