Android:停止运行并重新启动它

时间:2013-03-20 01:46:36

标签: android runnable

我刚刚实现了一个简单的应用程序,该应用程序随机更改屏幕颜色并在文本视图中显示颜色的十六进制代码。经过大量的搜索(特别是stackoverflow上的很多帖子),我几乎有代码可以做我想要的;只有一个差异。当我点击重新启动颜色闪烁的runnable时,它会从它停止的地方'恢复',即它最初不会完全延迟,但似乎只会延迟我停止时可能停止的时间。

我的完整代码如下。目前,我有一个短按启动屏幕颜色闪烁runnable,并长按停止它。

package com.example.colorflashingproject;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.view.Menu;
import android.view.View;
import android.os.Handler;
import android.widget.TextView;

public class MainActivity extends Activity {

//initialize a boolean variable (true or false only) 
//to check whether the overlay is tinted or not
boolean isTinted = false;
boolean colorIsFlashing = false;

//initialize a handler that we will use to loop a section of code
//that constantly changes the color of the screen
public Handler mHandler = new Handler();

//this creates the UI and screen view, and sets up some
//other aspects of the program
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    //set the current view in the user interface as our xml file:
    setContentView(R.layout.activity_main);

    //set the background color, and the initial overlay tint:
    ((View)findViewById(R.id.background_view)).setBackgroundColor(0xFF000000);
    ((View)findViewById(R.id.overlay_view)).setBackgroundColor(0x00000000);

    //create the overlayView variable that replesents our overlay for tinting
    View overlayView = findViewById(R.id.overlay_view);

    //implement a method that will listen for a short press
    overlayView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //implement function to change tint of our overlay
            if (!colorIsFlashing) {
                colorIsFlashing = true;
                mHandler.post(startColorFlashing);
            } else {

            }
        }
    });     

    //implement a method that will listen for long press:
    overlayView.setOnLongClickListener(new View.OnLongClickListener() {
        @Override
        public boolean onLongClick(View v) {

            //stop the color flashing if it was started:
            if (colorIsFlashing) {
                colorIsFlashing = false;
                stopColorFlashing();
            }

            //return true tells the system that the long press registered
            //return false doesn't. A false return would cause
            //the long click to register as a short click as well
            return true;
        }
    });

}


//this function generates a random color and sets it to the screen
public void randomChangeTint(){
    //generate random color components:
    int randa = (int) Math.round((int) 0xff * (float) Math.random());
    int randr = (int) Math.round((int) 0xff * (float) Math.random());
    int randg = (int) Math.round((int) 0xff * (float) Math.random());
    int randb = (int) Math.round((int) 0xff * (float) Math.random());
    int randColor = Color.argb(randa, randr, randg, randb); 

    //convert color integer to string:
    String strColor = String.format("#%08X", randColor);

    //set overlay to our generated random color:
    ((View)findViewById(R.id.overlay_view)).setBackgroundColor(randColor);
    ((TextView)findViewById(R.id.textView2)).setText(strColor);
}


//this is our 'runnable' that randomly sets the screen color over
//an interval of time in milliseconds (timeInterval)
public Runnable startColorFlashing = new Runnable(){
    //set overlay view to randomly switch colors
    int timeInterval=600;
    public void run() {
        if (colorIsFlashing){
            randomChangeTint();
        } else {

        }
        mHandler.postDelayed(this, timeInterval);
    }
};


//this method stops the color flashing:
public void stopColorFlashing() {

    //pauses the runnable:
    mHandler.removeCallbacksAndMessages(startColorFlashing);

    //re-initializes the runnable as an empty one
    startColorFlashing = new Runnable(){
        public void run() {
            //empty, nothing here
        }
    };
}
}

如果我遗漏了

    //re-initializes the runnable as an empty one
    startColorFlashing = new Runnable(){
        public void run() {
            //empty, nothing here
        }
    };

stopColorFlashing()的一部分,然后连续多次短按屏幕似乎一遍又一遍地开始运行,并在停止后再用短按重新启动它,它再次开始闪烁,似乎从那里恢复停了我希望它能够“重新开始”。

我已经尝试过Thread.start()和Thread.pause()的一些东西,但是无法解决这个问题。有没有办法'杀死'或'摧毁'一个可运行的?

我是java的新手(我知道matlab),任何想法或建议都值得赞赏。我确信我的代码编写得极其糟糕且无效。

1 个答案:

答案 0 :(得分:1)

好的,我找到了一个解决方案,按照AOSP的Deskclock示例,了解它如何在屏幕保护模式下每隔一分钟移动时间显示。我认为关键是Handler的removeMessages方法(这是一个方法,对吗?)。此外,我没有一个不断发布UI更新的Runnable,而是简单地使用被调用的UI更新方法generateRandomColor()向处理程序发送延迟消息,然后再次调用方法generateRandomColor(),从而导致循环。我认为这可能仍然不是最好的方式,但它简洁而有效。

以下代码完全符合我的要求。我希望这可以帮助那些寻找处理程序类似问题的人......

package com.example.testproject04;

/* import necessary libraries for 
 * our objects classes and widgets 
 * that we use here
 */
import android.os.Bundle;
import android.app.Activity;
import android.graphics.Color;
import android.view.View;
import android.os.Handler;
import android.widget.TextView;
import android.os.Message;

/* declare the main class/activity of this program */
public class MainActivity extends Activity {

/* initialize a boolean variable (true or false only) to 
 * check whether the screen is flashing new colors or not */
boolean colorIsFlashing = false;

/* update interval in milliseconds */
public int updateDelay = 800; 

/* 'message' to change color (used by handler) */
int CHANGE_COLOR_MSG = 0x0; 

/* this creates the UI and screen view, 
 * and sets up some other aspects of the program */
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    /* set the current view in the 
     * user interface as our xml file:
     */
    setContentView(R.layout.activity_main);

    /* set the background color, 
     * and the initial overlay tint:
     */
    ((View)findViewById(R.id.background_view)).setBackgroundColor(0xFF000000);
    ((View)findViewById(R.id.overlay_view)).setBackgroundColor(0x00000000);

    /* create the overlayView variable that 
     * represents our overlay for tinting
     */
    View overlayView = findViewById(R.id.overlay_view);

    /* implement a method that will listen for a short press, 
     * when short press occurs, if the screen is not currently 
     * flashing, it will start flashing periodically
     */
    overlayView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (!colorIsFlashing){
                colorIsFlashing = true;
                mHandler.sendEmptyMessageDelayed(CHANGE_COLOR_MSG, updateDelay);
            } 
        }
    }); 

    /* implement a listener for long presses on the screen, 
     * when a long press occurs, 
     * if the screen is flashing, it will stop 
     */
    overlayView.setOnLongClickListener(new View.OnLongClickListener() {
        @Override
        public boolean onLongClick(View v) {
            if (colorIsFlashing) {
                colorIsFlashing = false;
                mHandler.removeMessages(CHANGE_COLOR_MSG);
            }
            return true;
        }
    }); 

}

/* initialize a handler that we will use 
 * to change the color of the screen 
 */
private final Handler mHandler = new Handler() {
    @Override
    public void handleMessage(Message m) {
        if (m.what == CHANGE_COLOR_MSG) {
            generateRandomColor();
        }
    }
};

/* this function generates a random color
 *  and sets it to the screen 
 */
public void generateRandomColor(){
    if (!colorIsFlashing) return;

    /* generate random color components: */
    int randa = (int) Math.round((int) 0xff * (float) Math.random());
    int randr = (int) Math.round((int) 0xff * (float) Math.random());
    int randg = (int) Math.round((int) 0xff * (float) Math.random());
    int randb = (int) Math.round((int) 0xff * (float) Math.random());
    int randColor = Color.argb(randa, randr, randg, randb); 

    /* convert color integer to string: */
    String strColor = String.format("#%08X", randColor);

    /* set overlay to our generated random color
     *  and update textview to display color in hex code
     */
    ((View)findViewById(R.id.overlay_view)).setBackgroundColor(randColor);
    ((TextView)findViewById(R.id.textView2)).setText(strColor);

    mHandler.sendEmptyMessageDelayed(CHANGE_COLOR_MSG, updateDelay);
}

}

额外的搜索标签/信息:在UI线程中循环代码,使用处理程序停止android活动中的循环,从处理程序中删除消息,将延迟消息发送到处理程序