2013-08-25 3 views
0

Je suis stupéfait à ce sujet. Je suis avec un projet dans le livre et si j'utilise le fichier d'exemples de livres cela fonctionne. Cependant, est-ce que j'utilise mon fichier qui, autant que je peux voir est identique, je reçois une exception nullpointer. Voici le fichier ci-dessous:Nullpointerexception ue un curseur dans asynctask

//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 

le problème semble être cette ligne dans mon « getContactsTask » classe interne: contactAdapter.changeCursor (résultat); Une fois que j'ai frappé cette ligne, je reçois une exception nullpointer. Pour référence, voici la classe de connexion de base de données Je référencement dans 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 

Toute aide ou clarté à ce sujet seront grandement appréciés!

Répondre

0

Voici ce que je fait de mal:

Je déclare une

private CursorAdapter contactAdapter; 

dans le fichier AddressBook.java. Puis, plus tard au lieu de mettre

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

Je déclare à nouveau sur place

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

cela provoque une exception de pointeur nul. Après avoir nettoyé la 2ème erreur de déclaration, l'application fonctionne très bien. Merci encore à tous ceux qui ont aidé :)

1

Votre objet Cursor est réfrénant à null je pense. La variable de réfrence de résultat est ponting à quelle requête?

+0

Oui, le curseur fait référence à null, mais je ne comprends pas pourquoi. Rien ne semble hors de propos ici. En ce qui concerne la référence du résultat, je suis presque sûr que le 'résultat' fait référence au retour de getAllContacts. –

0

Vous n'avez pas ouvert la base de données avant d'effectuer une requête dans getAllContacts(). La fonction devrait ressembler à:

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

problème similaire est là dans la fonction getOneContact() aussi.

+0

doInBackground ouvre la base de données lorsqu'il est appelé et (je suppose) donne les résultats du retour DBC.getAllContacts(); à onPostExecute qui devrait alors lire le curseur qui est mis en place. C'est ma compréhension de la façon dont AsyncTask devrait fonctionner mais je peux être incorrect. –

Questions connexes