2013-03-20 65 views
1

我剛剛實現了一個簡單的應用程序,它隨機更改屏幕的顏色並在文本視圖中顯示顏色的十六進制代碼。經過大量搜索(特別是在stackoverflow上的很多帖子)後,我幾乎有代碼可以做我想做的事情;只有一個差異。當我點擊重新開始顏色閃爍的runnable時,它會從其停止的位置「恢復」,即它不會在最初完成延遲,但似乎只會延遲停止它時可能停止的時間。Android:停止可運行並重新啓動它

我的完整代碼如下。目前,我有一個短按開始屏幕顏色閃爍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 
     } 
    }; 
} 
} 

如果我離開了stopColorFlashing()的

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

部分,然後,通過短按屏幕多次連續似乎開始可運行一遍又一遍,並停止之後再短按重新啓動它,它會再次開始閃爍,似乎從停止的位置恢復。我希望它能夠「重新開始」。

我已經嘗試了一些與Thread.start()和Thread.pause()的東西,但無法弄清楚。有沒有辦法「殺死」或「銷燬」可運行的?

我是新來的java(我知道matlab),任何想法或建議表示讚賞。我確定我的代碼寫得非常糟糕,而且效率不高。

回答

1

好吧,我找到了一個解決方案,按照AOSP桌面時鐘的例子,它是如何在屏幕保護程序模式下每分鐘左右移動時間顯示的。我認爲的關鍵是Handler的removeMessages方法(這是一個方法,是否正確?)。另外,我只是簡單地使用被調用的UI更新方法generateRandomColor()向處理程序發送延遲的消息,然後再次調用generateRandomColor()方法,從而導致循環,而不是讓Runnable發佈UI更新。我認爲這可能還不是最好的方式,但它簡潔而且有效。

下面的代碼完全符合我的要求。我希望這可以幫助別人尋找與處理類似問題......

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系統活動停止循環,從處理程序中刪除郵件,發送延時給處理者的信息

+0

這一切看起來都很複雜,只是讓顏色發生變化。爲什麼不只是一個在預定時間點火的計時器? – greenapps 2013-03-21 08:43:25

+0

我還沒有學會如何製作一個計時器......猜測將不得不考慮它!感謝指針... – jdods 2013-03-21 21:37:34

相關問題