在我的活动中,我有 4个按钮,当用户点击其中一个按钮时,它会检查当前按钮的值并检查所选值是否正确。
问题是按钮滞后毫秒然后工作正常。 我不希望它是滞后的,因为它的游戏应该在几毫秒内工作。
我听说过 AsyncTask ,但我不知道在这里使用它是否正确。 如果是,怎么做?
onCreate(Bundle savedInstanceState)
firstButton.setOnClickListener(this);
secondButton.setOnClickListener(this);
thirdButton.setOnClickListener(this);
fourthButton.setOnClickListener(this);
onClick(查看视图)
disableButtons();
switch (view.getId()) {
case R.id.firstButton:
try {
if (firstButton.getText() == songs.get(currentSong).getString("artist")) {
givePoints();
isCorrect(0);
} else {
isFalse(0);
}
sleepForNext();
} catch (JSONException e) {
e.printStackTrace();
callError();
}
break;
...
}
修改
private void givePoints() {
points += 100;
}
private void sleepForNext() {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
resetButtonColors();
player.reset();
player.stop();
nextSong();
enableButtons();
}
}, MainActivity.SLEEP_TIME);
}
这里也是。
private void isCorrect(int buttonIndex) {
switch (buttonIndex) {
case 0:
firstButton.setBackgroundColor(getResources().getColor(R.color.darkGreen));
break;
case 1:
secondButton.setBackgroundColor(getResources().getColor(R.color.darkGreen));
break;
case 2:
thirdButton.setBackgroundColor(getResources().getColor(R.color.darkGreen));
break;
case 3:
fourthButton.setBackgroundColor(getResources().getColor(R.color.darkGreen));
break;
}
}
private void isFalse(int buttonIndex) {
switch (buttonIndex) {
case 0:
firstButton.setBackgroundColor(getResources().getColor(R.color.darkRed));
break;
case 1:
secondButton.setBackgroundColor(getResources().getColor(R.color.darkRed));
break;
case 2:
thirdButton.setBackgroundColor(getResources().getColor(R.color.darkRed));
break;
case 3:
fourthButton.setBackgroundColor(getResources().getColor(R.color.darkRed));
break;
}
}
nextSong()
private void nextSong() {
currentSong++;
gameLayout.setVisibility(View.INVISIBLE);
startSong();
}
最后,我的startSong()方法从我的url获取一个json对象。
private void startSong() {
fakeArtists.clear();
progress.show();
try {
String gender = songs.get(currentSong).getString("gender");
String language = songs.get(currentSong).getString("lang");
String URL = MainActivity.API_URL + "/get/artists/" + language + "/" + gender + "/" + MainActivity.FAKE_ARTISTS + "/" + URLEncoder.encode(songs.get(currentSong).getString("artist"));
Request request = new Request.Builder()
.url(URL)
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
callError();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
try {
JSONObject artistObj = new JSONObject(response.body().string());
JSONArray artistArr = artistObj.getJSONArray("result");
for (int i = 0; i < artistArr.length(); i++) {
String currentArtist = artistArr.getJSONObject(i).getString("artist");
fakeArtists.add(currentArtist);
}
progress.dismiss();
shuffleButtons();
runOnUiThread(new Runnable() {
@Override
public void run() {
gameLayout.setVisibility(View.VISIBLE);
stateTextView.setText((currentSong + 1) + "/" + (loadedSongs + 1));
pointsTextView.setText(getString(R.string.correct_answers) + ": " + points);
}
});
try {
player.setDataSource(MainActivity.API_URL + "/uploads/compressed/" + songs.get(currentSong).getString("file"));
player.prepare();
player.start();
} catch (IOException | JSONException e) {
e.printStackTrace();
callError();
}
} catch (JSONException e) {
e.printStackTrace();
callError();
}
}
});
} catch (JSONException e) {
e.printStackTrace();
callError();
}
}
答案 0 :(得分:0)
试试这个......
我假设你的isCorrect()和isFalse()方法对你的UI做了一些事情,所以我在onPostExecute()中做了这些调用。
在您的活动中,在代码底部声明一个私有内部类:
private class ClickHandler extends AsyncTask<Pair<Integer, String>, Void, Boolean> {
@Override
protected void onPreExecute() {
super.onPreExecute();
disableButtons();
}
@Override
protected Boolean doInBackground(Pair<Integer, String>... params) {
Pair<Integer, String> buttonKeyValue = params[0];
boolean result = false;
switch (buttonKeyValue.first) {
case R.id.firstButton:
result = buttonKeyValue.second.equals(songs.get(currentSong).getString("artist"));
break;
case R.id.secondButton:
result = buttonKeyValue.second.equals(songs.get(currentSong).getString("song"));
break;
case R.id.thirdButton:
result = buttonKeyValue.second.equals(songs.get(currentSong).getString("album"));
break;
}
if (result)
givePoints();
return result;
}
@Override
protected void onPostExecute(Boolean correct) {
super.onPostExecute(correct);
if (correct) {
isCorrect(0);
} else {
isFalse(0);
}
enableButtons();
}
}
onPreExecute()在UI线程上运行,因此您可以在此安全地禁用按钮。
onPostExecute()也在UI线程上运行,因此您可以在此处再次启用按钮。
在您的活动中初始化ClickHandler的实例:
private ClickHandler mClickHandler = new ClickHandler();
单击按钮,将按钮id和文本作为Pair传递给AsyncTask的execute方法。这将Pair传递给AsyncTask,以便它在doInBackground()中计算比较:
@Override
public void onClick(View view) {
Button button = (Button) view;
mClickHandler.execute(new Pair<>(button.getId(), button.getText().toString()));
}
doInBackground的结果传递给onPostExecute,因此您可以使用后台计算的结果相应地处理您的UI。