【发布时间】:2020-01-27 15:08:06
【问题描述】:
这是我的第一个问题,但作为一名学习者,我经常阅读以找到问题的解决方案。
因此,我正在关注使用 Java 的 Android 教程。挑战是创建一个计时器来煮鸡蛋。
到目前为止,我能够管理一切:
- 创建了seekBar 来设置时间;
- 移动seekBar 编辑TextView 以显示计时器;
- 创建了一个按钮来启动和停止计时器(button change when pressed from start to stop and another way round)。
现在我意识到我有一个小错误。如果我打开应用程序,擦洗 SeekBar,然后按下按钮,一切正常。如果我在应用程序打开后立即按下按钮,则会崩溃。
这里是错误信息:
01-27 14:50:41.011 20206-20206/com.example.yuri.eggtimer E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.yuri.eggtimer, PID: 20206
java.lang.IllegalStateException: Could not execute method for android:onClick
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:293)
at android.view.View.performClick(View.java:6256)
at android.view.View$PerformClick.run(View.java:24701)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
at android.view.View.performClick(View.java:6256)
at android.view.View$PerformClick.run(View.java:24701)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.os.CountDownTimer android.os.CountDownTimer.start()' on a null object reference
at com.example.yuri.eggtimer.MainActivity$override.startTimer(MainActivity.java:26)
at com.example.yuri.eggtimer.MainActivity$override.access$dispatch(Unknown Source:95)
at com.example.yuri.eggtimer.MainActivity.startTimer(MainActivity.java:0)
at java.lang.reflect.Method.invoke(Native Method)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
at android.view.View.performClick(View.java:6256)
at android.view.View$PerformClick.run(View.java:24701)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
代码如下:
public class MainActivity extends AppCompatActivity {
//Button startStop = findViewById(R.id.startButton);
//Creating a countDownTimer variable
CountDownTimer count;
// Creating a boolean variable to check if the timer is running.
boolean isRunning = false;
//Button method for start and stop
public void startTimer(View view) {
Log.i("info","Button pressed");
if (!isRunning){
final Button startStop = findViewById(R.id.startButton);
count.start();
startStop.setText("Stop");
isRunning = true;
}else{
final Button startStop = findViewById(R.id.startButton);
count.cancel();
startStop.setText("Start");
isRunning = false;
}
}
public void updateClock(int progress){
int time=progress/1000;
int minutes = Math.round(time/60);
int seconds = time%60;
TextView clock = findViewById(R.id.clockTextView);
clock.setText(minutes+":"+seconds);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Setting variable for max time and starting time
int max = 300;
final int[] startingPosition = {30};
//Calling the seekbar and setting the max and starting point
SeekBar timer = findViewById(R.id.eggSeekBar);
timer.setMax(max*1000);
timer.setProgress(startingPosition[0] *1000);
//creating Long type for countDownTimer
final Long[] timerProgress = {new Long(timer.getProgress())};
//set the starting clock
updateClock(startingPosition[0]*1000);
timer.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
timerProgress[0] = Long.valueOf(progress);
updateClock(progress);
count = new CountDownTimer(timerProgress[0],1000){
public void onTick(long secondLeft){
Long seconds = secondLeft;
int sec = seconds.intValue();
updateClock(sec);
Log.i("Second left", String.valueOf(secondLeft/1000));
}
public void onFinish(){
Log.i("Info","We are done!");
}
};
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
}
我只用日志尝试了按钮,没有问题。我注意到问题出在我想开始倒计时(在我的例子中称为计数)。
如果在 starttimer 方法中,我只需输入 count.start(),如果我在应用程序启动时单击它就会崩溃。所以我知道问题应该在倒计时的某个地方,但我不明白如果我先擦seekBar它为什么会起作用。
谢谢,每个人都会花时间阅读和/或回答这个问题。
【问题讨论】:
-
为什么将按钮设为
final?final Button startStop = findViewById(R.id.startButton);? -
也贴上xml
-
@Vault23 在按钮位于 if-else 语句之外并且 android studio 要求我最终访问它之前。我现在把它拿走了。谢谢。
-
@Wini 我按照 Zholot 的建议对在 onCreate 方法中在 seekBar 之外初始化 CountDownTime 的问题进行了排序。
标签: java android nullpointerexception