1

我刚刚实现了一个简单的应用程序,它随机改变屏幕颜色并在文本视图中显示颜色的十六进制代码。经过大量搜索(尤其是 stackoverflow 上的许多帖子),我几乎有了可以满足我需求的代码;只有一个差异。当我单击以重新启动可运行的颜色闪烁时,它会从停止的位置“恢复”,即它最初不会完全延迟,但似乎只会延迟我停止它时可能停止的时间。

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

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),任何想法或建议都值得赞赏。我确信我的代码写得非常糟糕而且效率低下。

4

1 回答 1

1

好的,我通过遵循 AOSP 桌面时钟示例找到了一个解决方案,该示例说明了它如何在屏幕保护程序模式下每分钟左右移动时间显示。我认为关键是 Handler 的 removeMessages 方法(这是一个方法,对吗?)。此外,我没有让 Runnable 不断发布 UI 更新,而是让调用的 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 活动中的循环,从处理程序中删除消息,向处理程序发送延迟消息

于 2013-03-20T18:02:45.403 回答