2013-08-30 62 views
1

通常情況下,在活動中,我使用SQLiteOpenHelper這樣如何在服務使用SQLiteOpenHelper

DatabaseHandler mDbHelper = new DatabaseHandler(getBaseContext()); 

現在,我要在服務中使用SQLite。但是,當我在Service類的方法中使用上述代碼時,會導致NullPointerException錯誤。

這是我的服務類

public class MyService extends Service{  
     public void LoadDB(){ 
      DatabaseHandler mDbHelper = new DatabaseHandler(getBaseContext()); 
      ArrayList <MyPosition> positionlist = mDbHelper.getAllPositions(); **//error here** 
     } 
     private final IBinder mBinder = new LocalBinder(); 
     public class LocalBinder extends Binder { 
      MyService getService() { 
       // Return this instance of LocalService so clients can call public methods 
       return MyService.this; 
      } 
     } 

     @Override 
     public IBinder onBind(Intent intent) { 
      return mBinder; 
     } 
    } 

This is the code that I call Service in MainActivity class 

     public class MainActivity extends Activity { 
      MyService mService; 
      boolean mBound = false; 
      @Override 
      protected void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 
      setContentView(R.layout.activity_main); 
      activity = this;  

      mService = new MyService(); 
      doBindService(); 
      if (mBound){ 
       mService.LoadDB(); 
      } 
     } 

     private ServiceConnection mConnection = new ServiceConnection() { 
      @Override 
      public void onServiceConnected(ComponentName className, IBinder service) { 
        LocalBinder binder = (LocalBinder) service; 
        mService = binder.getService(); 
        mBound = true; 
      } 

      @Override 
      public void onServiceDisconnected(ComponentName arg0) { 
       mBound = false; 
      } 
     }; 

      void doBindService() { 
       bindService(new Intent(MainActivity.this, MyService.class), mConnection, Context.BIND_AUTO_CREATE); 
       mBound = true; 
      } 

      void doUnbindService() { 
       if (mBound) { 
        // Detach our existing connection. 
        unbindService(mConnection); 
        mBound = false; 
       } 
      } 
     } 
} 

我的數據庫處理器類

package com.example.example10; 

import java.io.ByteArrayOutputStream; 
import java.util.ArrayList; 

import android.content.ContentValues; 
import android.content.Context; 
import android.database.Cursor; 
import android.database.sqlite.SQLiteDatabase; 
import android.database.sqlite.SQLiteOpenHelper; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 

public class DatabaseHandler extends SQLiteOpenHelper{ 
    // All Static variables 
    // Database Version 
    private static final int DATABASE_VERSION = 1; 

    // Database Name 
    private static final String DATABASE_NAME = "ListPosition"; 

    // Position table name 
    private static final String TABLE_POSITIONS = "positions"; 

    // Position Table Columns names 
    public static final String KEY_ROWID = "_id"; 
    private static final String KEY_ADDRESS = "address"; 
    private static final String KEY_LONG = "longPos"; 
    private static final String KEY_LAT = "latPos"; 
    private static final String KEY_LASTVISITED = "lastVisited"; 
    private static final String KEY_IMAGE = "image"; 

    public DatabaseHandler(Context context) { 
     super(context, DATABASE_NAME, null, DATABASE_VERSION); 
    } 

    // Creating Tables 
    @Override 
    public void onCreate(SQLiteDatabase db) { 
     String CREATE_POSITIONS_TABLE = "CREATE TABLE " + TABLE_POSITIONS + "(" + KEY_ROWID 
       + " INTEGER PRIMARY KEY AUTOINCREMENT, " + KEY_ADDRESS + " TEXT," 
       + KEY_LONG + " REAL, " + KEY_LAT + " REAL, " + KEY_LASTVISITED + " TEXT, " 
       + KEY_IMAGE + " BLOB" +")"; 
     db.execSQL(CREATE_POSITIONS_TABLE); 
    } 

    // Upgrading database 
    @Override 
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
     // Drop older table if existed 
     db.execSQL("DROP TABLE IF EXISTS " + TABLE_POSITIONS); 

     // Create tables again 
     onCreate(db); 
    } 

    /** 
    * All CRUD(Create, Read, Update, Delete) Operations 
    */ 

    // Adding new position 
    void addPosition(MyPosition position) { 
     SQLiteDatabase db = this.getWritableDatabase(); 

     ContentValues values = new ContentValues(); 
     values.put(KEY_ADDRESS, position.GetAddress()); 
     values.put(KEY_LONG, position.GetLongPos()); 
     values.put(KEY_LAT, position.GetLatPos()); 
     values.put(KEY_LASTVISITED, position.GetLastVisited()); 
     ByteArrayOutputStream stream = new ByteArrayOutputStream(); 
     position.GetImage().compress(Bitmap.CompressFormat.PNG, 100, stream); 
     byte[] imageInByte = stream.toByteArray(); 
     values.put(KEY_IMAGE, imageInByte); 

     // Inserting Row 
     db.insert(TABLE_POSITIONS, null, values); 
     db.close(); // Closing database connection 
    } 

    // Getting All Positions 
    public ArrayList <MyPosition> getAllPositions() { 
     ArrayList <MyPosition> position_list = new ArrayList <MyPosition>(); 
     // Select All Query 
     String selectQuery = "SELECT * FROM " + TABLE_POSITIONS; 

     SQLiteDatabase db = this.getWritableDatabase(); 
     Cursor cursor = db.rawQuery(selectQuery, null); 

     // looping through all rows and adding to list 
     if (cursor.moveToFirst()) { 
      do { 
       MyPosition position = new MyPosition(); 
       position.SetAddress(cursor.getString(1)); 
       position.SetLongPos(cursor.getFloat(2)); 
       position.SetLatPos(cursor.getFloat(3)); 
       position.SetLastVisited(cursor.getString(4)); 
       byte[] imagebyte = cursor.getBlob(5); 
       Bitmap image = BitmapFactory.decodeByteArray(imagebyte, 0, imagebyte.length); 
       position.SetImage(image); 

       // Adding position to list 
       position_list.add(position); 
      } while (cursor.moveToNext()); 
     } 

     // return position list 
     return position_list; 
    } 

    // Updating single position 
    public int updatePosition(MyPosition position, int index) { 
     SQLiteDatabase db = this.getWritableDatabase(); 

     ContentValues values = new ContentValues(); 
     values.put(KEY_ADDRESS, position.GetAddress()); 
     values.put(KEY_LONG, position.GetLongPos()); 
     values.put(KEY_LAT, position.GetLatPos()); 
     values.put(KEY_LASTVISITED, position.GetLastVisited()); 
     ByteArrayOutputStream stream = new ByteArrayOutputStream(); 
     position.GetImage().compress(Bitmap.CompressFormat.PNG, 100, stream); 
     byte[] imageInByte = stream.toByteArray(); 
     values.put(KEY_IMAGE, imageInByte); 

     // updating row 
     return db.update(TABLE_POSITIONS, values, KEY_ROWID + "=" + (index + 1), null); 
    } 

    // Deleting single position 
    public void deletePosition(MyPosition position, int index) { 
     SQLiteDatabase db = this.getWritableDatabase(); 
     db.delete(TABLE_POSITIONS, KEY_ROWID + "=" + (index + 1), null); 
     db.close(); 
    } 


    // Getting position Count 
    public int getPositionCount() { 
     String countQuery = "SELECT * FROM " + TABLE_POSITIONS; 
     SQLiteDatabase db = this.getReadableDatabase(); 
     Cursor cursor = db.rawQuery(countQuery, null); 
     int count = cursor.getCount(); 
     cursor.close(); 

     // return count 
     return count; 
    } 

    // Getting single position 
    MyPosition getPosition(int index) { 
     SQLiteDatabase db = this.getReadableDatabase(); 
     Cursor cursor = db.query(TABLE_POSITIONS, new String[] { KEY_ADDRESS, KEY_LONG, KEY_LAT, KEY_LASTVISITED, KEY_IMAGE}, 
       KEY_ROWID + "=?", new String[] { String.valueOf(index) }, null, null, null, null); 
     if (cursor != null) 
      cursor.moveToFirst(); 

     Bitmap image = BitmapFactory.decodeByteArray(cursor.getBlob(5), 0, cursor.getBlob(5).length); 
     MyPosition position = new MyPosition(cursor.getString(1), cursor.getDouble(2), cursor.getDouble(3), 
           cursor.getString(4), image); 
     // return contact 
     return position; 
    } 

} 

你對我有什麼建議?謝謝大家。

回答

4

您不應該在上下文中(在您的活動或本服務中)使用getBaseContext()

Service延伸(Context這樣你就可以修復你這樣的代碼:

​​

Here is a good place to start learning about Context

編輯:

你不應該使用Service()構造函數。你應該閱讀Service javadoc

要創建意圖的活動啓動一個服務,然後調用startService()傳遞入。

Intent i = new Intent(this, YourService.class); 
startService(i); 
+0

我試過這個,但它仍然導致NullPointerException E/AndroidRuntime(21752):java.lang.RuntimeException:無法啓動活動ComponentInfo {com.example.example10/com.example.example10.MainActivity}:java。 lang.NullPointerException – lolyoshi

+0

您不應該使用Service()構造函數,請參閱我的編輯。 – FoamyGuy

+0

仍NullPointerException:( – lolyoshi

0

你不能從你的活動叫serive.loadDB ...除非它是一個static的調用,即使那麼它是錯誤的。 android中的服務以驅動程序級別運行,應用程序無法直接與它們交互。與他們互動的唯一方法是通過AIDL(實際上有另一種方式,但我忘記它是什麼)。

如果您需要自己的活動來告訴您的服務,當您加載數據庫使用AIDL

問候,

+0

所以你的意思是我必須使用AIDL來加載服務中的數據?另外,當我創建AIDL文件時,它有這個錯誤 接口IAdditionService void LoadDB(); void DeletePosition(MyPosition position,int index); **未知類型MyPosition } 我該如何解決? – lolyoshi

+0

不,AIDL的目的是將消息發送到服務。您將向您的服務發送一條消息,以在您希望加載數據時加載數據。但是,如果你想在服務啓動或創建時加載數據,那就不一樣了,那麼只需在你的服務'onCreate()'或'onStart()'方法中做,並確保從'onStart()'調用'onStartCommand()'如果你使用'onStart()'。請記住使用'startService(new Intent(this,MyService.class));'從該活動啓動您的服務。請記住,服務在主線程中運行。 – Ali

+0

好吧我想我想通了你想做什麼,你想定義和使用本地服務。有一個例子[這裏](http://www.vogella.com/articles/AndroidServices/article.html#exercise_bindlocalservice)你有沒有試過使用這段代碼? – Ali

0

閱讀這個問題的答案後,我認爲這是不可能的事,但我設法打電話從我SQliteOpenHelper類(DatabaseHelper)方法,而應用程序崩潰時,我加入的onCreate( ) 方法。

public class YourService extends Service { 

    private DatabaseHelper dbHeper; 
    private User user; 
    private String userName; 

    @Override 
    public void onCreate() { 
     dbHeper = new DatabaseHelper(getApplicationContext()); 
     user = dbHeper.getUser(1); 
     userName = user.getUserName(); 
     System.out.println("User Name: " + userToken); 
    } 

} 

我希望這有助於!