活动选择时运行时崩溃

我想首先说我几乎没有安卓体验,这是我在android中的第一个项目,我的老师不是很教,所以我为任何过度的无知道歉。

在我进一步说明之前解释一下:我的应用程序的目标本质上是能够将您花费多少小时花在某些活动上,记录时间,然后在图表中显示它们。 我目前正在开发的是创建文本字段,允许用户键入他们在每个活动中花费了多少小时,然后将它们添加到总花费的小时数中,我希望在不使用按钮的情况下完成此操作,这让我查找textWatcher教程。

package com.example.gideon.timemanagement; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.text.Editable; import android.widget.EditText; import android.text.TextWatcher; import android.widget.TextView; public abstract class Customize extends AppCompatActivity implements TextWatcher { EditText a; EditText b; TextView ht; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_customize); EditText a = (EditText) findViewById(R.id.exerciseHours); EditText b = (EditText) findViewById(R.id.sleepHours); TextView ht = (TextView) findViewById(R.id.healthTotal); } private TextWatcher Ht = new TextWatcher() { @Override public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { } @Override public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { } @Override public void afterTextChanged(Editable editable) { if (!a.getText().toString().equals("") && !b.getText().toString().equals("")) { ht.setText(String.valueOf(Integer.valueOf(a.getText().toString()) + Integer.valueOf(b.getText().toString()))); } } }; 

这是我目前为此特定活动所拥有的代码。 在我实现任何这个之前,我可以进入屏幕并在布局上输入数据,但是,一旦我开始尝试输入代码,我就只有问题。 这段代码最终允许我构建gradle,但现在每当我尝试进入活动时,它都会崩溃整个应用程序。

任何帮助表示赞赏,并且主题提示也会有所帮助!

编辑:进行更改(原始post中的更新代码匹配,因此也应该更改)仍然有崩溃,所以我找到了logcat并将在此段后立即发布:

 02-10 18:53:40.167 23713-23713/com.example.gideon.timemanagement I/zygote: Not late-enabling -Xcheck:jni (already on) 02-10 18:53:40.174 23713-23713/com.example.gideon.timemanagement W/zygote: Unexpected CPU variant for X86 using defaults: x86 02-10 18:53:40.393 23713-23713/com.example.gideon.timemanagement I/InstantRun: starting instant run server: is main process 02-10 18:53:40.532 23713-23731/com.example.gideon.timemanagement D/OpenGLRenderer: HWUI GL Pipeline 02-10 18:53:40.662 23713-23731/com.example.gideon.timemanagement I/zygote: android::hardware::configstore::V1_0::ISurfaceFlingerConfigs::hasWideColor ay retrieved: 0 02-10 18:53:40.662 23713-23731/com.example.gideon.timemanagement I/OpenGLRenderer: Initialized EGL, version 1.4 02-10 18:53:40.662 23713-23731/com.example.gideon.timemanagement D/OpenGLRenderer: Swap behavior 1 02-10 18:53:40.662 23713-23731/com.example.gideon.timemanagement W/OpenGLRenderer: Failed to choose config with EGL_SWAP_BEHAVIOR_PRESERVED, retrying without... 02-10 18:53:40.662 23713-23731/com.example.gideon.timemanagement D/OpenGLRenderer: Swap behavior 0 02-10 18:53:40.682 23713-23731/com.example.gideon.timemanagement D/EGL_emulation: eglCreateContext: 0xb1eabb60: maj 3 min 0 rcv 3 02-10 18:53:40.726 23713-23731/com.example.gideon.timemanagement D/EGL_emulation: eglMakeCurrent: 0xb1eabb60: ver 3 0 (tinfo 0xb1eef120) 02-10 18:53:40.728 23713-23731/com.example.gideon.timemanagement E/eglCodecCommon: glUtilsParamSize: unknow param 0x00008cdf 02-10 18:53:40.728 23713-23731/com.example.gideon.timemanagement E/eglCodecCommon: glUtilsParamSize: unknow param 0x00008cdf 02-10 18:53:40.728 23713-23731/com.example.gideon.timemanagement E/eglCodecCommon: glUtilsParamSize: unknow param 0x00008824 02-10 18:53:40.728 23713-23731/com.example.gideon.timemanagement E/eglCodecCommon: glUtilsParamSize: unknow param 0x00008824 02-10 18:53:40.759 23713-23731/com.example.gideon.timemanagement D/EGL_emulation: eglMakeCurrent: 0xb1eabb60: ver 3 0 (tinfo 0xb1eef120) 

首先,当发生崩溃时,logcat中存在exception堆栈跟踪,它在调试问题时非常有用。 你应该学会使用它。 请参阅: 不幸的是MyApp已停止。 我怎么解决这个问题?

其次,你的活动还没有做任何事情。 一个崩溃的原因是,您在活动生命周期中过早地调用findViewById() ,在活动有窗口之前,以及在设置要查找的视图的布局之前。 在setContentView()之后将findViewById()调用移动到onCreate() setContentView()

首先,确保您始终添加打印在logcat中的崩溃详细信息,这可以在屏幕的下半部分找到,如下图> 6中所示:LOGCAT

在此处输入图像描述

其次,当您想要为变量分配视图时,应确保构建视图层次结构。 赋值findViewById(R.id.someID)查找视图,但是在构建父视图之前调用它时,您将获得一个空指针执行。 确保在onCreate()方法的setContentView(R.layout.activity_customize)之后始终调用此方法。

我想到的第三点是尝试将变量命名为有意义。 a,b和c不会在十天左右的时间内提醒你他们在做什么。 将变量命名为描述性的。 问问自己他们做了什么以及为什么需要他们,你对这些问题的回答将帮助你找到合适的名字。 我选择了一些例子,因为它不是a,b,c! 所以,让你的代码如下;

在类中,在onCreate()之前:

 EditText exerciseHoursEditText; EditText sleepHoursEditText; EditText mmHoursEditText; EditText oaHoursEditText; TextView healthTotalTextView; 

并在onCreate()

 super.onCreate(savedInstanceState); setContentView(R.layout.activity_customize); exerciseHoursEditText = (EditText) findViewById(R.id.exerciseHours); sleepHoursEditText = (EditText) findViewById(R.id.sleepHours); mmHoursEditText = (EditText) findViewById(R.id.mmHours); oaHoursEditText = (EditText) findViewById(R.id.oaHours); healthTotalTextView = (TextView) findViewById(R.id.healthTotal); 

Android以这种方式工作,也许你应该阅读一些关于android活动生命周期的内容。 这很简单。 检查此链接

第四点值得一提的是,在使用可能导致NULL方法时必须小心。 您在a.getText().toString()中所做的事情可能会导致在NPE ,因此请始终检查如下:

  if(a.getText() != null) { a.getText().toString() .... } 

我希望你喜欢你在做什么;)