`
freedomray
  • 浏览: 33178 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

LG KG90n屏幕闪动问题和联网时弹出系统提示窗口闪动问题

阅读更多
    LG KG90n是中国移动游戏基地手机系列中的一款,240x320分辨率的屏幕,不支持蓝牙,下载jar的时候只能使用OTA (Over The Air)下载且下载速度极慢,一般需要五六分钟。不过总体来说性能还可以。做j2me应用时,jar包可以达到600k以上,内存也还算充裕。但是有手机的jvm不是特别完善,开发时如果不注意会出现一些难缠的问题。
    以下就是我遇到过的2个问题,试验了多遍得出的结果。

1,屏幕闪动问题
    现象:进入游戏后,屏幕总是会闪动,但其实游戏还算流畅。

    问题出在屏幕刷新,该手机不允许一帧内对屏幕进行两次刷新。何谓两次刷新?对比一下代码比较好理解一点。
    问题代码:
public void paint(Graphics g){
    g.setColor(-1);
    g.fillRect(0, 0, SCR_W, SCR_H);
    
    Graphics gBuf = imgBuf.getGraphics(); //imgBuf is an Image of screen size as the screen buffer
    game.draw(gBuf);
    
    g.draw(imgBuf, 0, 0, 0);
}



    修改后无问题的代码:
public void paint(Graphics g){
    Graphics gg = g;
    
    if(imgBuf != null)//imgBuf is an Image of screen size as the screen buffer
        gg = imgBuf.getGraphics();

    gg.setColor(-1);
    gg.fillRect(0, 0, SCR_W, SCR_H);
    game.draw(gg);
    
    if(imgBuf != null)
        g.draw(imgBuf, 0, 0, 0);
}


对比代码可以发现,看问题代码,可以知道前面说的‘两次’是:一次是直接网手机屏幕上画东西,一次是在buffer上画东西,然后再画到屏幕上。而无问题代码的做法是:在画图之前,先看是否有buffer,如果有buffer则把所有东西都画到buffer上,然后再一次性画到手机屏幕上,如果没有buffer,则把所有内容直接画到手机屏幕上——这样就不会出现闪动的问题了。


2,在联网时弹出系统提示窗口问是否允许联网时,也闪动。
    现象:正常的情况是弹出一个系统窗口,但是该窗口没有完全遮住屏幕,可以看到j2me应用暂停了,变成了灰色。但是我遇到的问题时,画面不断在我的j2me应用和系统提示窗口之间来回切换闪动,且应用没哟变灰色,还是正常的色彩,提示窗口没有显示出来,只显示出屏幕底部的‘是’和‘否’两个提示按钮。

    原因:按键响应的机制有问题。如果直接在按键响应函数中去做逻辑响应——keyPressed()和keyReleased()函数,就会出现这样的问题,如果在这两个函数里只是保存着按键的值,而在线程的run()函数的while循环中去做逻辑处理的话,则能避免改问题(我做的是一个游戏,一般来说游戏都是起一个线程,在run()函数中是否一个while(true)的无限循环不断重画屏幕来实现游戏的运行)。还是对比一下代码:

有问题代码:
public void run(){
    while(true){
        repaint();
        serviceRepaints();
    }
}

public void keyPressed(int keycode){
    if(keycode == NUM_0){
        midlet.platformRequest(url); //此处会出现系统联网提示
    }
}


无问题代码:
public void run(){
    while(true){
        gamelogic();
        repaint();
        serviceRepaints();
        
        if(keyHold != INVALID_KEY)
            keyHold = INVALID_KEY;
    }
}

int keyHold;

void gamelogic(){
    if(keyHold == NUM_0)
        midlet.platformRequest(url);
}

public void keyPressed(int keycode){
    keyHold = keycode;
}



对比代码可以发现,后者保证了逻辑处理(gamelogic())在画图之前处理完,逻辑处理和画图不会相互干扰;而前者直接在keyPressed()中处理,则很可能会打断画图的过程——即在画图还未完成的时候,弹出了系统提示框,弹出之后,又要进行剩余的画图过程从而导致了闪屏——似乎也可以这样总结:系统的画图线程和应用的画图线程相互穿插了,导致了闪屏。避免穿插的办法就是在系统画图线程启动的根源处做处理——即按键处理的地方,将逻辑处理和画图过程完全分开。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics