博客介绍
大家好,本人目前(2020年5月)是准大学生。我的博客将记录一些自己计算机方面的学习、捣鼓和心得。我会分享一些自己踩过的雷,解释一些自己花了好久才搞明白的知识。
本坑介绍
第一个坑就先开一个用Java开发安卓应用的系列吧,反正最近正在自己玩Android Studio。
本期正文
最近,我在研究和探索安卓应用的开发。模式基本上是想到一个好玩的点子,然后试着去写。不会就上网查。鉴于我有一定的C++和Python功底(之前没系统学过Java),还是应付得来。我发现大部分信息网上都能很轻易的查到,所以一下分享自己研究出来,并不能很容易查明白的经验。
安卓如何用事件环更新各种参数
事件环,顾名思义,会帮助程序处理各种事件。最我最初接触事件环则是PyGame:
import pygame
pygame.init()
game_running = True
#这里初始化一些程序参数
while game_running:
doThings()
这个循环会一直循环,并且随时更新程序的状态。比如,我这次写的游戏会有很多方块从屏幕上方往下走。这时候就需要事件环来更新位置:
def doThings():
box_position += -1
draw(box, box_position)
pygame.display.update()
这样,每次循环一次,方块就能往下一点。
可是,安卓并没有这种显而易见的事件环,而是用了诸多个Listener来检测特定的事件有没有发生:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//程序打开时运行
}
@Override
protected void onClick(){
super.onClick();
//按钮被按时运行
}
那么,我如果想以特定频率更新我的位置参数,该如何做?
高级的做法是使用多个线程来同时做到检测各种事件和更新参数。不过,我的水平还没到那里,也不是能够搞懂怎么去做。
我第一个想法是使用计时器创造一个可以被检测到的事件,因为我之前使用Qt的时候用过这个方法去更新一个日晷:
@Override
protected void onStart(){
super.onStart();
Timer timer = new Timer();
timer.schedule(new TimerTask(){
@Override
public void run(){
updatePosition();
}
}, delay, period);
}
不过,问题是周期设的太短就会出问题。我为了达到比较快速的更新,就把周期设成了10毫秒。结果,上一个位置还没有更新完就会开始更新下一个。出现的问题就是方块会无故复制出好多个同时显示,并且不定时程序会崩溃闪退。
再查一查发现,正确(或者说,能用,因为我的方法不一定是最好的,最应该使用的)的方法是使用Handler类:
@Override
protected void onStart() {
super.onStart();
final Handler handler = new Handler();
boolean running = true;
handler.postDelayed(new Runnable() {
public void run() {
updatePosition();
if(running) {
handler.postDelayed(this, period);
}else{
return;
}
}
}, delay);
}
这样一来,每次更新不会强求在一定时间过去之后必须要运行,而是让每次更新乖乖的排起队。这样,每次更新都能完全进行。这样,就做到了对参数和状态的周期性更新。
最后提一句,Android Studio和安卓模拟器与手机在时间周期上可能存在比较大的差异。相同的周期下,我在用安卓模拟器测试程序时,方块掉落的很慢,但是在手机上试了后方块掉落的非常快。最后我是连接了手机最后调整了循环的周期,才让程序能够合理运行。这可能是由于我的电脑是很多年前的i5处理器,而手机搭载麒麟980。电脑上的模拟器不能很快完成每次更新,所以显得方块掉落会慢。现在想想,不同的手机上由于处理器性能不同可能也会存在差异。
最后,感谢您阅读这篇文章。我的文笔不好,语文从未是强项,有叙述不清、错别字、用词不当等还请见谅,同时,作为计算机萌新,有技术方面的错误请指正。
附:本文提到的程序