Question

Unlike the title I'll try to be as clear, concise, and to the point as possible (hopefully this isn't TL;DR) I know the title is hard to understand, so hopefully my question won't be. I have a NPE that I can't track down in stack trace, or in debug mode (running eclipse). The stack trace points to a line, but no matter what I change I can't seem to get it to run without throwing the NPE (I'll point out the specific line later). So I have an Activity, an SQLiteOpenHelper, and a Service. In addition to those three classes I will include a snippet from a fourth class, my Splash class. The aforementioned service is started via my Splash class, using this code (I'll explain why I've included this later):

startService(new Intent(getApplicationContext(), MyService.class));

It's important that I point out before moving on that the variable "ID" in MyService.class is set by another activity which I won't include here. Just know that the variable does get set correctly, it changes correctly when changed by the user, and that I've put Log.I(TAG, TEXT) statements at various points in the code to be sure that it works and that the data remains consistent through out. I've also verified that my service is starting correctly, so that is a non-issue as well. Moving on. Here is the method from my SQLiteOpenHelper class that I reference later on (I've trimmed down the code as much as possible, so that I only include pertinent information.)

public class DBHandler extends SQLiteOpenHelper {

private static final String _ID = "_id";
private final String KEY_NAME = "name";
public String getData(String ID, int pos) {
    String clause = _ID + " = " + ID;
    Cursor cr = null;
    String result = "";

    cr = getReadableDatabase().query(DB_T, columns1, clause, null, null, null, null);

    if (cr != null) {
        cr.moveToFirst();
        result = cr.getString(pos);
    }
    close();
    return result;
}

}

I've verified that the database handler works correctly because I can call it from many other points in my code without issue. This particular method works every time also (in fact, the entire class works without fail...except when this NPE pops up) The data in the table gets initialized in a part of the DB class that I've left out, and I've verified that all of that works as well. So, moving forward please assume that my database class works flawlessly at all points in my application except the line that I will show you later. Next we have my service class, which looks like this (the offending line is in here, I'll point it out in a moment):

public class MyService extends Service {

DBHandler dbHelper = new DBHandler(this);
public static String ID = "1";
String name = "";

@Override
public void onCreate() {
    super.onCreate();
    init();
}

public void init() {
    name = dbHelper.getData(ID, 1);
}

}

In the method "public void init()" the NPE points at "name = dbHelper.getData(ID, 1);" Notice that I can use this EXACT line of code in other places in my application and it works without fail...yet here, it fails time and time again. Finally I have the activity that is calling my service to get this data. Below, where I call MyService.init(), that's where the gremlins come out. No matter what I do I can't get this to work. For some reason using name = dbHelper.getData(ID, 1); in this manner makes it blow a gasket.

public class ActivityInteract extends Activity implements OnClickListener {

MyService fooService = new MyService();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    MyService.init();
    interactInit();
}

private void interactInit() {
    setContentView(R.layout.g_interact);
    nameText.setText(fooService.name);
}

}

Basically, this is driving me INSANE. I've read through the android Docs until my eyes are bleeding. Scoured google. Nothing no where is clicking the light on in my head to say "oh, thats what I'm doing wrong" Also (I asked this question earlier, but it was closed because I asked it without supporting data) I'd like to know the difference (if any) between instancing my service by declaring it as a new variable (as I did in my activity above by declaring MyService fooService = new MyService()) vs. just starting the service like I did in my splash class using an Intent at the very beginning of this question.

Is their a difference? I'm instancing it because if I just call the service (i.e. using MyService.name instead of fooService.name in my Activity directly above) then I have to set the 'name' variable to static...which in turn means that I have to set 'dbHelper' to static...which SQLiteHelper doesn't agree with at all (can't make a static reference to non static methods in sqliteopenhelper).

I hope this is enough information. I can include a pastebin to the stack trace if need be, but I have to warn you, I've trimmed down the above code quite a bit to get it to fit, and changed the names on classes and variables so that it makes more sense in this limited context. In a nutt shell the stack trace point at the above activity, then points at the MyService.init() line, which then points (finally) at the name = DbHelper(ID, 1) line in the service. Thank you for any help!!!

EDIT: In a nutt-shell the problem is with passing a context and what kind of context you are passing. To anyone reading over this, and having the same or similar issue: Try changing the context that you are passing into the SQLiteOpenHelper.

Was it helpful?

Solution

EDIT

After further reading i may be wrong since the services are called with a context?. If this is the case then it is most likely your calling your service from different activities and, therefore, using different activity's context when you call init() from different activities. If this is the case try this,

public class MyService extends Service {
    DBHandler dbHelper;

    public void init() {
        dbHelper = new DBHandler(this);
        dbHelper.getData(ID, 1);
    }
}

Same as my other answer w/o passing a context


The context is null because this does not refer to an activity context

public class MyService extends Service {
    DBHandler dbHelper = new DBHandler(this);
}

try passing a context:

public class MyService extends Service {
    DBHandler dbHelper;

    public void init(Context context)
    {
        dbHelper = new DBHandler(context);
        dbHelper.getData(ID, 1);
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top