public class SnowflakeWallpaper extends WallpaperService {
// Limit of snowflakes per snowflake type; 4 types * 4 snowflake = 16 total
// Should keep memory usage at a minimal
static int SNOWFLAKE_AMOUNT = 4;
Drawable drawWall;
Rect wallBounds;
// Draw all snowflakes off screen due to not knowing size of canvas at creation
static int SNOW_START = -90;
ArrayList<Snowflakes> snow = new ArrayList<Snowflakes>();
private final Handler mHandler = new Handler();
@Override
public void onCreate() {
super.onCreate();
//WallpaperManager to pull current wallpaper
WallpaperManager wManager = WallpaperManager.getInstance(this);
drawWall = wManager.getFastDrawable();
wallBounds = drawWall.copyBounds();
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public Engine onCreateEngine() {
return new SnowEngine();
}
class SnowEngine extends Engine {
private final Runnable mDrawSnow = new Runnable() {
public void run() {
drawFrame();
}
};
private boolean mVisible;
SnowEngine() {
if(snow.size() < 16){
//Back snowflakes
for(int i = 0; i < SNOWFLAKE_AMOUNT; i++){
snow.add(new Snowflakes(
BitmapFactory.decodeResource(getResources(),
R.drawable.snowflakeback),
SNOW_START,
SNOW_START,
((float)(Math.random() * 2) + 1)) // Fall speed initial setup, back slowest to front fastest potentially
);
}
//MidBack snowflakes
for(int i = 0; i < SNOWFLAKE_AMOUNT; i++){
snow.add(new Snowflakes(
BitmapFactory.decodeResource(getResources(),
R.drawable.snowflakemid),
SNOW_START,
SNOW_START,
((float)(Math.random() * 4) + 1)
));
}
// Mid snowflakes
for(int i = 0; i < SNOWFLAKE_AMOUNT; i++){
snow.add(new Snowflakes(
BitmapFactory.decodeResource(getResources(),
R.drawable.snowflakemidfront),
SNOW_START,
SNOW_START,
((float)(Math.random() * 8) + 1))
);
}
// Front snowflakes
for(int i = 0; i < SNOWFLAKE_AMOUNT; i++){
snow.add(new Snowflakes(
BitmapFactory.decodeResource(getResources(),
R.drawable.snowflake),
SNOW_START,
SNOW_START,
((float)(Math.random() * 16) + 1))
);
}
}
}
@Override
public void onCreate(SurfaceHolder surfaceHolder) {
super.onCreate(surfaceHolder);
}
@Override
public void onDestroy() {
super.onDestroy();
mHandler.removeCallbacks(mDrawSnow);
}
@Override
public void onVisibilityChanged(boolean visible) {
mVisible = visible;
if (visible) {
drawFrame();
} else {
mHandler.removeCallbacks(mDrawSnow);
}
}
@Override
public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
super.onSurfaceChanged(holder, format, width, height);
drawFrame();
}
@Override
public void onSurfaceCreated(SurfaceHolder holder) {
super.onSurfaceCreated(holder);
}
@Override
public void onSurfaceDestroyed(SurfaceHolder holder) {
super.onSurfaceDestroyed(holder);
mVisible = false;
mHandler.removeCallbacks(mDrawSnow);
}
/*
* Update the screen with a new frame
*/
void drawFrame() {
final SurfaceHolder holder = getSurfaceHolder();
/*
* if the snow goes too low or too right, reset;
*/
for(int i = 0; i < snow.size(); i++){
if(snow.get(i).getX() > holder.getSurfaceFrame().width()){
snow.get(i).setX(-65);
}
if(snow.get(i).getY() > holder.getSurfaceFrame().height()){
snow.get(i).setY(-69);
}
}
// Test if the array was just create; true - randomly populate snowflakes on screen
if(snow.get(1).getX() < -70){
for(int i = 0; i < snow.size(); i++){
snow.get(i).setX((int)(Math.random() * getSurfaceHolder().getSurfaceFrame().width() +1));
snow.get(i).setY((int)(Math.random() * getSurfaceHolder().getSurfaceFrame().height() + 1));
}
}
// Change snowflake x & y
for(int i = 0; i < snow.size(); i++){
snow.get(i).delta();
}
Canvas c = null;
try {
c = holder.lockCanvas();
if (c != null) {
// call to draw new snow position
drawSnow(c);
}
} finally {
if (c != null) holder.unlockCanvasAndPost(c);
}
// Reschedule the next redraw
mHandler.removeCallbacks(mDrawSnow);
if (mVisible) {
mHandler.postDelayed(mDrawSnow, 1000/100);
}
}
/*
* Draw the snowflakes
*/
void drawSnow(Canvas c) {
c.save();
// Draw bg
//********** add code to pull current bg and draw that instead of black. Maybe set this in config?
if(drawWall == null){
c.drawColor(Color.BLACK);
}else{
drawWall.copyBounds(wallBounds);
drawWall.draw(c);
}
/*
* draw up the snow
*/
for(int i = 0; i < snow.size(); i++){
c.drawBitmap(snow.get(i).getImage(), snow.get(i).getX(), snow.get(i).getY(), null);
}
c.restore();
}
}
回答
同樣的問題加布 - 有什麼問題嗎?
一些一般想法: *您應該避免在構造函數中做大量工作。你的構造函數做了大量的工作,而不是在init/setup方法中。更容易獨立於實例創建進行基準測試/配置文件。
你在很多地方使用Math.random - 我假設你是單線程的,但Math.random是同步的。根據javadocs:「如果許多線程需要以很快的速度生成僞隨機數,它可能會減少爭用每個線程有自己的僞隨機數發生器」
您正在使用Math.random讓你雙倍,然後相乘,然後添加,然後投射。這看起來很浪費。任何方式獲得更少的操作?
您似乎有一些劃分 - 請參見行「mHandler.postDelayed(mDrawSnow,1000/100);」。當然,這可能是編譯或JIT離開,但你應該避免在性能關鍵代碼中劃分(它比乘法慢得多)。所以任何一個常量的div都可以被1/C乘以靜態值來代替。
您有大量的重複訪問器方法調用(在某些情況下,幾乎所有的重複)。見SNIPPIT:
for(int i = 0; i < snow.size(); i++){ if(snow.get(i).getX() > holder.getSurfaceFrame().width()){ snow.get(i).setX(-65); } if(snow.get(i).getY() > holder.getSurfaceFrame().height()){ snow.get(i).setY(-69); } }
,可以儲存「holder.getSurfaceFrame()寬()在臨時/局部變量(每繪圖循環也許曾經假設你的面是可調整大小的用戶。 ),你也可能在一個局部變量店snow.get(I)。更重要的是(風格),您可以使用增強的for循環如雪是一個ArrayList,所以使用
for (Snow mySnow : snow) {
// Do something with mySnow
}
希望這有助於。祝你好運!
@加貝和諾亞,它確實工作,CPU使用率似乎很低(沒有做太多的分析,仍然學習,但根據我的機器人的電池使用率在2和3%之間),有時似乎很慢,但大多是我相信它會放慢主屏幕上的用戶界面。例如,向左或向右滑動似乎已經減慢。沒有什麼特別明顯的,但有時似乎有點遲緩。我實施諾亞斯的建議和更新。 – jwp 2010-11-29 07:52:28
- 1. 優化此代碼的任何建議?
- 2. 任何簡化此代碼的方法?
- 3. 無法獲得此鼠標檢測代碼可靠工作...任何想法?
- 4. RegisterTypeLibForUser調用似乎不工作 - 任何想法?
- 5. 任何想法如何優化我的小JQuery代碼的菜單?
- 6. 關於如何解析此數據集的任何優雅想法?
- 7. 似乎無法刪除任何註釋
- 8. 怎麼了?我似乎無法關閉此代碼
- 9. 關於Elasticsearch Aggregation的任何想法?
- 10. 我似乎無法讓我的代碼工作
- 11. 關於多重相關矩陣可視化的任何想法?
- 12. 有關如何簡化此代碼的任何建議?
- 13. 有關如何解決此錯誤的任何想法?
- 14. UnsatisifiedLinkError - 有關如何解決此問題的任何想法?
- 15. 我似乎無法連接IB和XCode之間的任何IBOutlets
- 16. 如何優化此代碼?
- 17. 如何優化此代碼?
- 18. 如何優化此代碼?
- 19. 如何優化此代碼
- 20. 如何優化此代碼?
- 21. 如何優化此代碼?
- 22. 如何優化此代碼?
- 23. 任何想法,爲什麼這段代碼不工作? body> *
- 24. 我似乎無法得到任何東西使用httpWebResponse
- 25. MS Access:關於如何創建類似Excel的表單的任何想法?
- 26. 應用不再工作 - 任何想法
- 27. 此模板代碼不會編譯。有任何想法嗎?
- 28. 遠程代理似乎無法工作?
- 29. SQL服務器遊標無法正常工作...任何想法?
- 30. 關於如何更改textarea選擇顏色的任何想法?
什麼問題?它太慢了嗎?它使用了太多的CPU嗎?它閃爍嗎?它甚至工作嗎? – Gabe 2010-11-29 06:40:11