我每隔x秒就在android中更新视图时遇到问题。
要了解android是如何工作的,我正在写一个小游戏。 它有一个GameController,可以保存游戏循环。在循环内部,逻辑被执行,之后gui将被告知变化。
问题是在视图中无法看到更改。视图保持不变,直到游戏循环结束,然后只更新一次。
这是我的代码(重要部分):
GameController.java:
IGui gui;
public void play() {
while (playing) {
getAndProcessInput();
updateGui();
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
}
}
}
private void updateGui() {
gui.setPlayer(x, y);
// ...
}
GameActivity.java:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
GridView gridview = (GridView) findViewById(R.id.GridView1);
TextAdapter = new TextAdapter(this);
gridview.setAdapter(textAdapter);
GameController c = new GameController();
// here, the game loop shoud start.
// what i tried:
// new Thread(c).start(); <-- causes crash
// c.play(); <-- causes view to frease until game loop is done
this.runOnUiThread(c); <-- causes view to frease until game loop is done
}
TextAdapter.java:
public class TextAdapter extends BaseAdapter implements IGui {
private final Context context;
private final String[] texts;
public TextAdapter(Context context) {
this.context = context;
texts = new String[height * width];
for (int i = 0; i < texts.length; i++) {
texts[i] = " ";
}
}
public int getCount() {
return height * width;
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
TextView tv;
if (convertView == null) {
tv = new TextView(context);
tv.setLayoutParams(new GridView.LayoutParams(25, 25));
} else {
tv = (TextView) convertView;
}
tv.setText(texts[position]);
return tv; // <-- this happens only when game loop is done, not everytime something changed
}
@Override
public void setPlayer(int x, int y) {
texts[width * y + x] = "X";
// this.notifyDataSetChanged(); <-- this does not help (view still freases)
// gridview.invalidateViews(); does not help either
}
}
我搜索了很多并尝试了很多(我知道这里曾经问过类似的问题,但他们也没有帮助我),但不知何故它只是不起作用。 我无法让它在视图和逻辑运行在android中的不同theads上工作,如果它们在同一个线程上运行,则逻辑阻止视图。 任何帮助将不胜感激。
//编辑:
如果我尝试新的线程(c).start(); LogCat sais: java.lang.RuntimeException:无法在未调用Looper.prepare()的线程内创建处理程序
如果我添加Looper.prepare(); : java.lang.RuntimeException:无法启动活动ComponentInfo {GameActivity}:java.lang.RuntimeException:每个线程只能创建一个Looper
如果我试试这个.runOnUiThread(c);没有错误。
答案 0 :(得分:2)
首先,这似乎不是游戏的方式,你需要使用SurfaceView
或GLSurfaceView
来更好地做你想要的。
你也可以在Android上寻找Cocos2d,它是一个2D平台(从iPhone移植而来),让你的生活更轻松:
http://code.google.com/p/cocos2d-android/
我冥想警告你,我几个月前尝试过它,它还没有生产等级,它确实不时崩溃。
无论如何,如果您仍想继续前进,我会尝试回答您的问题: 我认为你对这些东西应该起作用的方式太过分了。首先尝试理解处理程序如何使用线程。
在你的帖子上做任何你想要的事情:
new Thread(new Runnable()
{
@Override
public void run()
{
try
{
calculateGameChangesHere();
handler.sendEmptyMessage(SUCCESS);
}
catch (Exception e)
{
handler.sendEmptyMessage(FAILURE);
}
}
}).start();
当您的数据准备就绪后,告诉处理程序将其放在视图中并显示它:
protected Handler handler = new Handler()
{
@Override
public void handleMessage(Message msg)
{
if (msg.what == SUCCESS)
{
setCalculatedDataToaView(); // the data you calculated from your thread can now be shown in one of your views.
}
else if (msg.what == FAILURE)
{
errorHandlerHere();//could be your toasts or any other error handling...
}
}
};
这适用于需要大量处理/网络的所有内容,不应阻止您的UI线程。
希望这有帮助。
答案 1 :(得分:0)
通过每隔几秒刷新listView
,不确定您要实现的目标。无论如何,如果您正在编写一些2D游戏,您必须使用SurfaceView
,这尤其适用于持续刷新。
答案 2 :(得分:0)
遇到同样的问题并使用非常简单的代码解决了它。
提示:的
更新网格的方法(在第一个地方或任何地方放置构建GridView的Activity)
public void UpdateGrid(){
//your logic
//your way to change grid values (there are tones of other ways)
CustomGridAdapter cga = new CustomGridAdapter(this, values);
gridView.setAdapter(cga);
gridView.invalidateViews();
}
构建完成工作的非UI线程
公共类DataReceiver实现Runnable {
private MainActivity mainActivity;
public DataReceiver(MainActivity ma) {
mainActivity = ma;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
mainActivity.runOnUiThread(new Runnable() {
public void run() {
//update the grid here
mainActivity.UpdateGrid();
}
});
//sleep here
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}