3

I am experiencing an issue when trying to pass the context from the MainActivity class to another. Here is the ContextPasser Class.

public class ContextPasser extends Application{
public Context context;
public ContextPasser(){
    context = getApplicationContext();
}}

But if I use the context variable in the other class, like this:

Line line = new Line(new ContextPasser().context);

I am getting a null pointer exception. I want to get a solution which does not involve passing in a context variable because I have looked at all of the other stackoverflows and they do not seem to help me with that. One of the solutions that I found was:

Context context;
MyHelperClass(Context context){
this.context=context;
}

This does not help me because I am calling the Line class which is,

Line line = new Line(new ContextPasser().context);

in another class called the GameRunner like so:

public class GameRunner extends Activity {
Line line = new Line(new ContextPasser().context);
public void draw(Canvas canvas){
    line.draw(canvas);
    getWindow().getDecorView().setBackgroundColor(Color.BLACK);
}

public void update(){
    line.update();
}

}

So, I want to create a method that will pass the Context without accepting parameters of the Context class themselves.

Please let me know any suggestions or answers. I would really appreciate it. Thanks a lot for your time and consideration!

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Akash Veerappan
  • 76
  • 1
  • 1
  • 6

2 Answers2

8

If your other class is a non-activity class this is how you pass the Context:

public class MyNonActivityClass{

// variable to hold context
private Context context;

//save the context received via constructor in a local variable

public MyNonActivityClass(Context context){
    this.context=context;
}

}

And this is how you pass the context :

MyNonActivityClass mClass = new MyNonActivityClass(this);
OBX
  • 6,044
  • 7
  • 33
  • 77
5

OBX's answer shows one way to do it. But you should understand why your approach does not work.

Instances of Android components such as Application and Activity are not fully realized as Contexts until they've been initialized by the framework. This happens sometime before onCreate(...) is called. If you create a new instance yourself, it won't be initialized and will neither have nor be usable as a Context. For the same reason, calling getApplicationContext() in a field assignment or constructor will return null or throw an exception.

MyActivity extends Activity {
  private Context appContext = getApplicationContext(); // wrong

  public MyActivity {
    appContext = getApplicationContext(); // wrong
  }

  public void onCreate(final Bundle savedInstanceState) {
    appContext = getApplicationContext(); // correct
  }
}
Community
  • 1
  • 1
Kevin Krumwiede
  • 9,868
  • 4
  • 34
  • 82
  • But I think getApplicationContext() returns data provided by Android OS right? It's not like we are instantiating/initializing an Application instance by ourselves. – Harsha Apr 27 '18 at 10:47
  • @Harsha Yes, but that data isn't there until the framework has initialized the activity instance. Check out the source for [`ContextWrapper`](http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/5.0.1_r1/android/content/ContextWrapper.java), which `Activity` indirectly extends. A lot of methods won't work until `mBase` is set. – Kevin Krumwiede Apr 28 '18 at 01:14
  • Alright, I get it now.. So if this activity here is not the first activity, is it then valid to initialize it in the constructor? – Harsha Apr 28 '18 at 07:00
  • @Harsha No. Calling `getApplicationContext()` in an activity's constructor or field initializer will always result in an NPE. – Kevin Krumwiede Apr 29 '18 at 23:16