3

クリックするとアプリケーションがクラッシュするのはなぜbuttonですか?また、どのように修正すればよいですか?

ボタンがクリックrowされたときにを挿入する必要があります。SQLite databaseこれには2つの値が含まれていますが、これは十分に簡単なはずです。1つは、dateを使用してフォーマットされたsimpledateformatterです。もう1つは、からの場所ArrayListです。コードに赤い線はありませんが、行のボタンを押すとアプリがクラッシュしますinsert。以下は、Java相互作用する3つのファイルのコードです。問題は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);
    }
}

DBファイル

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ファイルに投稿されています

いつものようにどんな助けもありがたいです!

4

3 に答える 3

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

于 2013-03-18T20:30:55.120 に答える
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開始する必要があります。これはデータベースとは関係ありませんが、対処する必要があるコードにはまだ多くの問題があります。そうしないと、ユーザーがアプリの使用を開始したときにエラーやリークが発生します。

于 2013-03-18T20:44:06.887 に答える
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 static Device に制限がないため、ここでリストを使用します。

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;
   }

モデルクラスとIDフィールド(プライベートロングID)にゲッター/セッターを追加する必要があると思います

于 2013-03-18T20:34:02.407 に答える