У меня проблема с обновлением представления в Android каждые x секунд.
Чтобы узнать, как работает Android, я пишу небольшую игру.
Он имеет GameController, который содержит игровой цикл. Внутри цикла выполняется логика, после чего графический интерфейс будет проинформирован об изменениях.
Проблема в том, что изменения не видны на виде. Вид остается неизменным до тех пор, пока игровой цикл не завершится и не обновится, а только один раз.
Вот мой код (важные части):
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, и если они работают в одном потоке, логика блокирует представление.
Любая помощь будет принята с благодарностью.
// редактировать:
Если я попробую новую тему (c) .start (); LogCat говорит:
java.lang.RuntimeException: не удается создать обработчик внутри потока, который не вызвал Looper.prepare ()
А если я добавлю Looper.prepare (); :
java.lang.RuntimeException: невозможно запустить действие ComponentInfo {GameActivity}: java.lang.RuntimeException: только один лупер может быть создан для потока
Если я попробую this.runOnUiThread (c); ошибок нет.