为什么单击button
时我的应用程序崩溃了,如何解决?
单击按钮时,我需要在row
SQLite
中插入database
。它包含两个值,应该很容易。一个是date
,使用simpledateformatter
格式化。另一个只是ArrayList
的位置。我的代码中没有红线,但是当我按下按钮insert
时,我的应用程序崩溃了。以下是3个Java
文件之间相互作用的代码。我有预感问题在于我的Model.java,但它可能不止于此。如果需要更多代码,请询问。
MainActivity.java
public class MainActivity extends Activity {
final String TAG = "*** DEBUG ***";
public static final String SMOKIN_DATA_FILE = "smokin.dat";
public static final int EDIT_ACTIVITY = 1;
public static Model model = null;
public static MySmokinDatabase mySmokinDatabase;
public static Cursor cursor;
public static SimpleCursorAdapter adapter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
restoreModel();
if (mySmokinDatabase == null)
mySmokinDatabase = new MySmokinDatabase(this);
refreshView();
}
@Override
protected void onResume() {
super.onResume();
if (model == null)
restoreModel();
refreshView();
}
protected void onPause() {
super.onPause();
saveModel();
}
private void refreshView() {
Spinner spinner = (Spinner) findViewById(R.id.location_spinner);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, model.getLocationsArray());
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
SimpleDateFormat sdf = new SimpleDateFormat("E, MMM dd");
TextView dateText = (TextView) findViewById(R.id.date);
TextView countText = (TextView) findViewById(R.id.count);
TextView daysText = (TextView) findViewById(R.id.days);
TextView totalText = (TextView) findViewById(R.id.total);
TextView aveText = (TextView) findViewById(R.id.ave);
GregorianCalendar now = new GregorianCalendar();
dateText.setText(sdf.format(now.getTime()));
//get today's count from data in the SQLite table - count entries with today's date
countText.setText("" + "");
//mySmokinDatabase.getTodaysCount());
// Table data
daysText.setText("" + String.format("%10d", model.getDays()));
totalText.setText("" + "get total count from data in SQLite table - count total rows");
if (model.getDays() > 0)
aveText.setText("calc average from SQLite and model info");
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK && requestCode == EDIT_ACTIVITY) {
saveModel();
}
}
public void smokedHandler(View view) {
Spinner spinner = (Spinner) findViewById(R.id.location_spinner);
String s = spinner.getSelectedItem().toString();
String d = model.getDates();
mySmokinDatabase.insertSmokinValues(new Model(s,d));
cursor = mySmokinDatabase.getAllSmokinCursor();
adapter.changeCursor(cursor);
refreshView();
}
public void restoreModel() {
// Restore from disk, or start with an empty model
try {
ObjectInputStream ois = new ObjectInputStream(
openFileInput(SMOKIN_DATA_FILE));
model = (Model) ois.readObject();
ois.close();
}
catch (Exception e){
Log.v("*** DEBUG ***", "Error writing to file: " + e);
model = new Model();
}
}
public void saveModel() {
Log.v("*** AJ ***", "In onPause");
try {
ObjectOutputStream oos = new ObjectOutputStream(
openFileOutput(SMOKIN_DATA_FILE, Context.MODE_PRIVATE));
oos.writeObject(model);
oos.close();
}
catch (Exception e){
Log.v("*** MatchIt ***", "Error writing to file: " + e);
}
}
数据库文件
public long insertSmokinValues(Model model) {
ContentValues newSmokinValues = new ContentValues();
newSmokinValues.put(KEY_DATE, model.getDates());
newSmokinValues.put(KEY_LOCATION, model.getLocations());
SQLiteDatabase db = smokinDBOpenHelper.getWritableDatabase();
return db.insert(SmokinDBOpenHelper.INCIDENTS_TABLE, null, newSmokinValues);
}
public Cursor getAllSmokinCursor() {
SQLiteDatabase db = smokinDBOpenHelper.getWritableDatabase();
return db.query(SmokinDBOpenHelper.INCIDENTS_TABLE, new String[]
{KEY_ID, KEY_LOCATION, KEY_DATE}, null, null, null, null, null);
}
模型文件
private ArrayList<String> locations = new ArrayList<String>();
public String [] defaultLocations = {"Home", "Work", "Commuting", "School", "Bar",
"Restaurant", "Social Gathering", "Other"};
public Model(GregorianCalendar date){
startDate = date;
for (String s : this.defaultLocations)
locations.add(s);
}
public Model(String s, String d) {
place = s;
dates = d;
}
public String getDates() {
GregorianCalendar gc = new GregorianCalendar();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
dates = sdf.format(gc.getTime());
return dates;
}
public String getLocations() {
for (String s : this.locations)
place = s;
return place;
}
按要求登录日志:
03-18 15:52:42.397: W/dalvikvm(676): threadid=1: thread exiting with uncaught
exception
(group=0x40a13300)
03-18 15:52:42.457: E/AndroidRuntime(676): FATAL EXCEPTION: main
03-18 15:52:42.457: E/AndroidRuntime(676): java.lang.IllegalStateException: Could not
execute method of the activity
03-18 15:52:42.457: E/AndroidRuntime(676): at
android.view.View$1.onClick(View.java:3591)
03-18 15:52:42.457: E/AndroidRuntime(676): at
android.view.View.performClick(View.java:4084)
03-18 15:52:42.457: E/AndroidRuntime(676): at
android.view.View$PerformClick.run(View.java:16966)
03-18 15:52:42.457: E/AndroidRuntime(676): at
android.os.Handler.handleCallback(Handler.java:615)
03-18 15:52:42.457: E/AndroidRuntime(676): at
android.os.Handler.dispatchMessage(Handler.java:92)
03-18 15:52:42.457: E/AndroidRuntime(676): at android.os.Looper.loop(Looper.java:137)
03-18 15:52:42.457: E/AndroidRuntime(676): at
android.app.ActivityThread.main(ActivityThread.java:4745)
03-18 15:52:42.457: E/AndroidRuntime(676): at
java.lang.reflect.Method.invokeNative(Native Method)
03-18 15:52:42.457: E/AndroidRuntime(676): at
java.lang.reflect.Method.invoke(Method.java:511)
03-18 15:52:42.457: E/AndroidRuntime(676): at
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
03-18 15:52:42.457: E/AndroidRuntime(676): at
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
03-18 15:52:42.457: E/AndroidRuntime(676): at dalvik.system.NativeStart.main(Native
Method)
03-18 15:52:42.457: E/AndroidRuntime(676): Caused by:
java.lang.reflect.InvocationTargetException
03-18 15:52:42.457: E/AndroidRuntime(676): at
java.lang.reflect.Method.invokeNative(Native Method)
03-18 15:52:42.457: E/AndroidRuntime(676): at
java.lang.reflect.Method.invoke(Method.java:511)
03-18 15:52:42.457: E/AndroidRuntime(676): at
android.view.View$1.onClick(View.java:3586)
03-18 15:52:42.457: E/AndroidRuntime(676): ... 11 more
03-18 15:52:42.457: E/AndroidRuntime(676): Caused by: java.lang.NullPointerException
03-18 15:52:42.457: E/AndroidRuntime(676): at
com.example.smokin4ThomasSullivan.MainActivity.smokedHandler(MainActivity.java:119)
03-18 15:52:42.457: E/AndroidRuntime(676): ... 14 more
第119行:adapter.changeCursor(cursor);涉及的方法发布在我的DB文件
中
一如既往地感谢任何帮助!
答案 0 :(得分:3)
日志说明了所有内容:您尝试在此行中使用adapter
null
:
adapter.changeCursor(cursor);
编辑:
按照我的想法,您在此处声明了adapter
字段:
public static SimpleCursorAdapter adapter;
但是你没有初始化它,正如你在Java中应该知道的那样,如果声明一个没有初始化的字段,那么它就被设置为null
。这就是你得到错误的原因。
我没有亲自使用SimpleCursorAdapter
类,但你可能想看一下它的构造函数,这在android文档中有描述:
http://developer.android.com/reference/android/widget/SimpleCursorAdapter.html
所以基本上在onCreate()
方法中,你应该这样做:
adapter = new SimpleCursorAdapter( this,
R.layout.some_layout,
cursor,
columns,
to,
0 );
在我之前发布链接的文档中描述了使用过的构造函数的参数。
您可能还想查看使用SimpleCursorAdapter
的代码:
http://www.mysamplecode.com/2012/07/android-listview-cursoradapter-sqlite.html
答案 1 :(得分:1)
修改强>
像其他人一样说。 adapter
负责NPE
然而,通过处理Sqlite cursor
来采用正确的方法也很重要。
执行以下操作非常重要
<强>替换强>
public Cursor getAllSmokinCursor() {
SQLiteDatabase db = smokinDBOpenHelper.getWritableDatabase();
return db.query(SmokinDBOpenHelper.INCIDENTS_TABLE, new String[]
{KEY_ID, KEY_LOCATION, KEY_DATE}, null, null, null, null, null);
}
public List<Model> getAllSmokinCursor() {
List<Model> models= new ArrayList<Model>();
SQLiteDatabase db = smokinDBOpenHelper.getWritableDatabase();
Cursor cursor= db.query(SmokinDBOpenHelper.INCIDENTS_TABLE, new String[]
{KEY_ID, KEY_LOCATION, KEY_DATE}, null, null, null, null, null);
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
Model device = fromCursorToObject(cursor);
models.add(device);
cursor.moveToNext();
}
// Make sure to close the cursor
cursor.close();
return models;
}
我在这里使用一个列表,因为你的requestpublic静态设备没有任何限制
fromCursorToObject(Cursor cursor) {
Model model = new Model();
int i = 0;
model.setId(cursor.getLong(i++));
model.setLocation(cursor.getString(i++));
model.setDate(cursor.getString(i++));
return model;
}
我假设您必须将getter / setter添加到Model类以及ID字段(private Long id)
答案 2 :(得分:1)
首先,您应该在这些函数中关闭数据库:
public long insertSmokinValues(Model model) {
ContentValues newSmokinValues = new ContentValues();
newSmokinValues.put(KEY_DATE, model.getDates());
newSmokinValues.put(KEY_LOCATION, model.getLocations());
SQLiteDatabase db = smokinDBOpenHelper.getWritableDatabase();
return db.insert(SmokinDBOpenHelper.INCIDENTS_TABLE, null, newSmokinValues);
}
public Cursor getAllSmokinCursor() {
SQLiteDatabase db = smokinDBOpenHelper.getWritableDatabase();
return db.query(SmokinDBOpenHelper.INCIDENTS_TABLE, new String[]
{KEY_ID, KEY_LOCATION, KEY_DATE}, null, null, null, null, null);
}
第二,如果你不想在gestSmokinCursor
中没有结果时更改适配器中的光标,只需检查moveToFirst
光标是否包含结果,如果没有抛出自定义异常说获得光标时可以处理的EmptyCursorException
。
此外,您需要考虑如何关闭游标,因为我不确定您的适配器是否在更改游标时关闭游标以及活动被销毁时,但这也是您的责任。
如果您的NullPointerException
在此行:
adapter.changeCursor(cursor);
然后您的适配器只是null
并且需要启动并且这与数据库无关,但是您的代码仍然存在很多问题需要解决,否则您将遇到错误并且当人们开始使用该应用程序时泄漏。