2013-08-25 19 views
0

我對此很尷尬。我正在跟着書中的一個項目,如果我使用書籍示例文件,它可以工作。但是,我使用我的文件,只要我能看到是相同的,我得到一個空指針異常。這裏是下面的文件:在asynctask中使用遊標的Nullpointerexception

//AddressBook.java 
//Main activity for address book app. 
package com.deitel.addressbook; 

import android.app.ListActivity; 
import android.os.Bundle; 
import android.os.AsyncTask; 
import android.database.Cursor; 
import android.content.Intent; 
import android.view.Menu; 
import android.view.View; 
import android.view.MenuItem; 
import android.widget.AdapterView; 
import android.widget.AdapterView.OnItemClickListener; 
import android.widget.CursorAdapter; 
import android.widget.ListView; 
import android.widget.SimpleCursorAdapter; 
import android.util.Log; 


public class AddressBook extends ListActivity { 

    //string used when logging for debug 
    public static final String TAG ="AddressBookBot"; 

    public static final String ROW_ID = "row_id"; //Intent extra key 
    private ListView contactListView; //the ListActivity's ListView 
    private CursorAdapter contactAdapter; //adapter for ListView 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); //call super's onCreate 
     Log.d(TAG, "In onCreate() event"); 
     contactListView = getListView(); 
     contactListView.setOnItemClickListener(viewContactListener); 

     //map each contact's name to a TV in the ListView layout 
     String[] from = {"name"}; 
     int[] to = new int[] {R.id.contactTextView}; 
     CursorAdapter contactAdapter = new SimpleCursorAdapter(AddressBook.this, 
       R.layout.contact_list_item, null, from, to);  
     setListAdapter(contactAdapter); //set contactView's adapter 
    } 

    @Override 
    protected void onResume(){ 

     Log.d(TAG, "In onResume() event"); 
     super.onResume(); //call super's onResume method 

     //create a new GetContactsTask and execute it 
     new GetContactsTask().execute((Object[]) null); 
    } //end onResume 

    @Override 
    protected void onStop(){ 

     Log.d(TAG, "In onStop() event"); 
     Cursor cursor = contactAdapter.getCursor(); //get current Cursor 
     if (cursor != null) 
      cursor.deactivate(); //deactivate it 

     contactAdapter.changeCursor(null); //adapter now has no Cursor 
     super.onStop(); 
    } //end onStop 

    //performs database query outside GUI thread 
    private class GetContactsTask extends AsyncTask<Object, Object, Cursor>{   

     DatabaseConnector DBC = new DatabaseConnector(AddressBook.this); 

     //perform the database access 
     @Override 
     protected Cursor doInBackground(Object... params){ 
      DBC.open(); 

      //get a cursor containing call contacts 
      return DBC.getAllContacts(); 
     } //end method doInBackground 

     //use the Cursor returned from the doInBackground method 
     @Override 
     protected void onPostExecute(Cursor result){ 
      Log.d(TAG, "In onPostExecute() event"); 
      contactAdapter.changeCursor(result); //set the adapter's Cursor 
      DBC.close(); 
     } //end method onPostExecute 
    } //end class GetContactsTask 

    //create the Activity's menu from a menu resource XML file 
    public boolean onCreateOptionsMenu(Menu menu) { 

     super.onCreateOptionsMenu(menu); 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.addressbook_menu, menu); 
     return true; 
    } //end onCreateOptionsMenu 

    //handle the choice from options menu 
    @Override 
    public boolean onOptionsItemSelected(MenuItem item){ 

     //create a new Intent to launch the AddEditContact Activity 
     Intent addNewContact = new Intent(AddressBook.this, AddEditContact.class); 
     startActivity(addNewContact); //start the AddEditContact Activity 
     return super.onOptionsItemSelected(item); //call super's method 
    } //end onOptionsItemSelected 

    //event listener that responds to the users touching a contact's name in the ListView 
    OnItemClickListener viewContactListener = new OnItemClickListener(){ 

     @Override 
     public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3){ 

      //create an Intent to launch the ViewContact Activity 
      Intent viewContact = new Intent(AddressBook.this, ViewContact.class); 

      //pass the selected contact's row ID as an extra with the intent 
      viewContact.putExtra(ROW_ID, arg3); 
      startActivity(viewContact); //start the ViewContact Activity   
     } //end method onItemClick 
    }; //end viewContactListener 
} //end class AddressBook 

的問題似乎是這條線在我的「getContactsTask」內部類: contactAdapter.changeCursor(結果); 一旦我打這條線,我得到一個空指針異常。作爲參考,這裏是數據庫連接器類,我在getContactsTask引用:

//DatabaseConnector.java 
//Provides easy connection and creation of UserContacts database. 
package com.deitel.addressbook; 

import android.content.ContentValues; 
import android.content.Context; 
import android.database.Cursor; 
import android.database.SQLException; 
import android.database.sqlite.SQLiteDatabase; 
import android.database.sqlite.SQLiteOpenHelper; 
import android.database.sqlite.SQLiteDatabase.CursorFactory; 
import android.util.Log; 

public class DatabaseConnector { 

    public static final String TAG ="AddressBookBot"; 

    //database name 
    private static final String DATABASE_NAME = "UserContacts"; 
    private SQLiteDatabase database; //database object 
    private DatabaseOpenHelper DBOpenHelper; //database helper 

    //public constructor for DatabaseConnector 
    public DatabaseConnector(Context context){ 

     //create a new DatabaseOpenHelper 
     DBOpenHelper = new DatabaseOpenHelper(context, DATABASE_NAME, null, 1); 
    } //end constructor 

    //open the database connection 
    public void open() throws SQLException{ 

     //create or open a database for reading/writing 
     database = DBOpenHelper.getWritableDatabase(); 
    } //end method open 

    //close the database connection 
    public void close(){ 

     if(database != null) 
      database.close(); //close database connection 
    } //end method close 

    //inserts a new contact in the database 
    public void insertContact(String name, String email, String phone, String state, String city){ 

     ContentValues newContact = new ContentValues(); 
     newContact.put("name", name); 
     newContact.put("email", email); 
     newContact.put("phone", phone); 
     newContact.put("street", state); 
     newContact.put("city", city); 

     open(); //open the database 
     database.insert("contacts", null, newContact); 
     close(); //close the database 
    } //end insertContact 

    //inserts a new contact in the database 
    public void updateContact(long id, String name, String email, String phone, String state, String city){ 

     ContentValues editContact = new ContentValues(); 
     editContact.put("name", name); 
     editContact.put("email", email); 
     editContact.put("phone", phone); 
     editContact.put("street", state); 
     editContact.put("city", city); 

     open(); //open the database 
     database.update("contacts", editContact, "_id=" + id, null); 
     close(); //close the database 
    } //end updateContact 

    //return a Cursor with all contact information in the database 
    public Cursor getAllContacts(){ 
     Log.d(TAG, "in getAllContacts"); 
     return database.query("contacts", new String[] {"_id", "name"}, null, null, null, null, "name"); 

    } //end getAllContacts 

    //get a Cursor containing all information about the contact specified by the given id 
    public Cursor getOneContact(long id){ 

     return database.query("contacts", null, "_id='" + id, null, null, null, null); 
    } //end getOneContact 

    //delete the contact specified by the given String name 
    public void deleteContact(long id){ 

     open(); //open the database 
     database.delete("contacts", "_id=" + id, null); 
     close(); //close the database 
    } //end deleteContact 

    private class DatabaseOpenHelper extends SQLiteOpenHelper{ 

     //public constructor 
     public DatabaseOpenHelper(Context context, String name, CursorFactory factory, int version){ 
      super(context, name, factory, version); 
     } //end DatabaseOpenHelper contstructor 

     //creates the contacts table when the database is created 
     @Override 
     public void onCreate(SQLiteDatabase db){ 

      //query to create a new table named contacts 
      String createQuery = "CREATE TABLE contacts" + "(_id integer primary key autoincrement," + "name TEXT, email TEXT, phone TEXT," + "street TEXT, city TEXT);"; 

      db.execSQL(createQuery); //execute the query 
     } //end method onCreate 

     @Override 
     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){ 

     } //end onUpgrade 
    } //end class DatabaseOpenHelper 
} //end class DataBaseConnector 

任何幫助或清晰度將不勝感激!

回答

0

這裏是我做錯了什麼:

我在AddressBook.java文件中聲明一個

private CursorAdapter contactAdapter; 

。的再後來就不是把

contactAdapter = new SimpleCursorAdapter(AddressBook.this, 
       R.layout.contact_list_item, null, from, to); 

我再次聲明當場

CursorAdapter contactAdapter = new SimpleCursorAdapter(AddressBook.this, 
       R.layout.contact_list_item, null, from, to); 

這會導致空指針異常。清理第二個聲明錯誤後,該應用程序運行得很好。再次感謝所有幫助:)

1

您的光標對象正在refrencing爲空,我認爲。結果引用變量是指向哪個查詢?

+0

是的,遊標肯定是引用null,但我不明白爲什麼。這裏沒有什麼不合適的地方。至於結果參考,我很肯定'結果'是引用getAllContacts的返回值。 –

0

在getAllContacts()中進行查詢之前,您沒有打開數據庫。 函數應該是這樣的:

public Cursor getAllContacts() { 
    Log.d(TAG, "in getAllContacts"); 

    Cursor cursor = null; 

    open(); // open the database 
    cursor = database.query("contacts", new String[] {"_id", "name"}, 
         null, null, null, null, "name"); 
    close(); // close the database 

    return cursor; 
} 

類似的問題是那裏的功能getOneContact()了。

+0

doInBackground在調用時打開數據庫,並且(我假設)從返回結果DBC.getAllContacts();到onPostExecute然後讀取設置的光標。這是我對AsyncTask應該如何工作的理解,但我可能不正確。 –

相關問題