我目前正在开发我的第一款完整的Android应用。我正在开发一个数学脑训练游戏,所以我需要一个倒数计时器。因此,我正在使用Android的CountDownTimer来构建它。
以下是我用来控制游戏玩法的GameActivity.java类的Java代码。
package lk.iit.mobiletechnology.mathematicsbraintrainer;
import java.util.concurrent.TimeUnit;
import lk.iit.mobiletechnology.mathematicsbraintrainer.entity.Challenge;
import lk.iit.mobiletechnology.mathematicsbraintrainer.entity.Game;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@SuppressLint("NewApi")
public class GameActivity extends ActionBarActivity {
private Game game;
private Challenge currentChallenge;
private int questionCount;
private TextView timeView;
private TextView question;
private EditText inputField;
private static final String TAG = "Brain Trainer" ;
private static final int MAXIMUM_QUESTIONS = 10;
public static final String KEY_DIFFICULTY = "lk.iit.mobiletechnology.mathematicsbraintrainer.difficulty";
public static final int DIFFICULTY_NOVICE = 0;
public static final int DIFFICULTY_EASY = 1;
public static final int DIFFICULTY_MEDIUM = 2;
public static final int DIFFICULTY_GURU = 3;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game);
int difficultyLevel = this.getIntent().getIntExtra(KEY_DIFFICULTY, GameActivity.DIFFICULTY_NOVICE);
this.game = new Game(GameActivity.MAXIMUM_QUESTIONS, difficultyLevel);
this.questionCount = 0;
this.question = (TextView)(this.findViewById(R.id.question_text));
currentChallenge = this.game.getChallenges().get(questionCount);
question.setText(currentChallenge.toString());
this.timeView = (TextView)(this.findViewById(R.id.time_text));
timeView.setText("00:10");
final CountDownMachine timer = new CountDownMachine(10000, 1000);
timer.start();
this.setButtonClickListener();
}
private void setButtonClickListener() {
Button testButton = (Button)(findViewById(R.id.test_button));
inputField = (EditText)(findViewById(R.id.question_input));
testButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
double inputValue = Double.parseDouble(inputField.getText().toString());
ImageView imageView = (ImageView)(findViewById(R.id.answer_feedback));
Drawable drawable;
if(questionCount < 10) {
if(currentChallenge.correctAnswer(inputValue)) {
drawable = getResources().getDrawable(R.drawable.fixed_correct_image);
imageView.setImageDrawable(drawable);
}
else {
drawable = getResources().getDrawable(R.drawable.fixed_wrong_image);
imageView.setImageDrawable(drawable);
}
questionCount++;
if(questionCount == 5) {
//Intent intent = new Intent(, UserEntryActivity.class);
finish();
}
currentChallenge = game.getChallenges().get(questionCount);
question.setText(currentChallenge.toString());
inputField.setText(" ?");
}
}
});
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@SuppressLint("NewApi")
public class CountDownMachine extends CountDownTimer {
public CountDownMachine(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@SuppressLint("NewApi")
@Override
public void onTick(long millisUntilFinished) {
long timeRemaining = millisUntilFinished;
String text = String.format("%02d:%02d", (TimeUnit.MILLISECONDS.toMinutes(timeRemaining) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(timeRemaining))), (TimeUnit.MILLISECONDS.toSeconds(timeRemaining) - (TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(timeRemaining)))));
timeView.setText(text);
}
@Override
public void onFinish() {
ImageView imageView = (ImageView)(findViewById(R.id.answer_feedback));
Drawable drawable;
if(!(inputField.getText().toString().equals(""))) {
double inputValue = Double.parseDouble(inputField.getText().toString());
if(questionCount < 10) {
if(currentChallenge.correctAnswer(inputValue)) {
drawable = getResources().getDrawable(R.drawable.fixed_correct_image);
imageView.setImageDrawable(drawable);
}
else {
drawable = getResources().getDrawable(R.drawable.fixed_wrong_image);
imageView.setImageDrawable(drawable);
}
}
}
else {
drawable = getResources().getDrawable(R.drawable.fixed_wrong_image);
imageView.setImageDrawable(drawable);
}
questionCount++;
if(questionCount == 5) {
finish();
}
currentChallenge = game.getChallenges().get(questionCount);
question.setText(currentChallenge.toString());
inputField.setText(" ?");
timeView.setText("00:10");
}
}
}
定义布局的关联activity_game.xml如下:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:background="@color/background"
tools:context="lk.iit.mobiletechnology.mathematicsbraintrainer.GameActivity" >
<TextView
android:id="@+id/time_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:textSize="15sp"
android:textStyle="bold"
android:textColor="#000"
/>
<TextView
android:id="@+id/question_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:textSize="15sp"
android:textStyle="bold"
android:textColor="#000"
android:layout_below="@+id/time_text"
/>
<EditText
android:id="@+id/question_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="numberDecimal|numberSigned"
android:text=" ?"
android:layout_below="@+id/question_text"
android:background="#fff"
/>
<ImageView
android:id="@+id/answer_feedback"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="@dimen/image_text_gap"
android:layout_below="@+id/question_input"
android:layout_centerHorizontal="true"
/>
<Button
android:id="@+id/test_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Test"
android:layout_below="@+id/answer_feedback"
android:layout_centerHorizontal="true"
/>
</RelativeLayout>
请注意,此java类仍未涵盖整个要求,但它可以在每个游戏过程中触发10个问题。 我已经介绍了计时器,但自从调用timer.start()方法以来,我不断得到以下异常:
Android IllegalAccessError java.util.concurrent.TimeUnit.toMinutes
由于我是这个发展领域的新手,很难找到适当的解决方案,如果有人能帮我解释为什么我得到这个以及存在什么样的解决方案,我将不胜感激。
这是我得到的异常的logcat内容:
03-06 01:52:59.328: D/AndroidRuntime(278): Shutting down VM
03-06 01:52:59.328: W/dalvikvm(278): threadid=1: thread exiting with uncaught exception (group=0x4001d800)
03-06 01:52:59.348: E/AndroidRuntime(278): FATAL EXCEPTION: main
03-06 01:52:59.348: E/AndroidRuntime(278): java.lang.IllegalAccessError: tried to access method java.util.concurrent.TimeUnit.toMinutes:(J)V from class lk.iit.mobiletechnology.mathematicsbraintrainer.GameActivity$CountDownMachine
03-06 01:52:59.348: E/AndroidRuntime(278): at lk.iit.mobiletechnology.mathematicsbraintrainer.GameActivity$CountDownMachine.onTick(GameActivity.java:108)
03-06 01:52:59.348: E/AndroidRuntime(278): at android.os.CountDownTimer$1.handleMessage(CountDownTimer.java:124)
03-06 01:52:59.348: E/AndroidRuntime(278): at android.os.Handler.dispatchMessage(Handler.java:99)
03-06 01:52:59.348: E/AndroidRuntime(278): at android.os.Looper.loop(Looper.java:123)
03-06 01:52:59.348: E/AndroidRuntime(278): at android.app.ActivityThread.main(ActivityThread.java:4627)
03-06 01:52:59.348: E/AndroidRuntime(278): at java.lang.reflect.Method.invokeNative(Native Method)
03-06 01:52:59.348: E/AndroidRuntime(278): at java.lang.reflect.Method.invoke(Method.java:521)
03-06 01:52:59.348: E/AndroidRuntime(278): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
03-06 01:52:59.348: E/AndroidRuntime(278): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
03-06 01:52:59.348: E/AndroidRuntime(278): at dalvik.system.NativeStart.main(Native Method)
答案 0 :(得分:1)
不要使用TimeUnit将millis转换为秒,分钟等等,只需自己动手。
int seconds = (millis / 1000) % 60;
int minutes = millis / (1000 * 60);
显然,当运行时没有TimeUnit时会出现此错误,请参见此处:
Android IllegalAccessError java.util.concurrent.TimeUnit.toHours