1

通常,在活动中,我像这样使用 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;
                }
            }
        }
}

我的 DatabaseHandler 类

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

3 回答 3

4

您不应该将其getBaseContext()用于您的上下文(在您的活动或此服务中)。

Service extends ( is a )Context所以你可以像这样修复你的代码:

public class MyService extends Service{     
  public void LoadDB(){
    DatabaseHandler mDbHelper = new DatabaseHandler(this);  
  }...

这是开始学习 Context 的好地方

编辑:

您不应该使用Service()构造函数。您应该阅读服务 javadoc

要从 Activity 启动服务,您需要创建一个意图,然后调用 startService() 将其传入。

Intent i = new Intent(this, YourService.class);
startService(i);
于 2013-08-30T02:24:22.130 回答
0

你不能serive.loadDB从你的活动中打电话......除非它是一个static电话,否则它是错误的。android 中的服务在驱动程序级别运行,应用程序无法直接与它们交互。与它们交互的唯一方法是通过AIDL(实际上还有另一种方法,但我忘记了它是什么)。

如果您在加载数据库时需要您的活动来告诉您的服务,请使用AIDL

问候,

于 2013-08-30T03:11:50.710 回答
0

在阅读了这个问题的答案后,我认为这是不可能的,但是当我添加 onCreate() 方法时,我设法从我的 SQliteOpenHelper 类(DatabaseHelper)调用方法,而不会导致应用程序崩溃。

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

}

我希望这有帮助!

于 2016-07-14T09:14:47.650 回答