-1

Can't figure out why my following code is broken

I've got MainActivity class:

public class MainActivity implements PresenterListener {
...
private Presenter presenter = new Presenter(this);
...
}

Presenter:

public class Presenter extends PresenterUtils {
    protected DateTimeFormatter dateFormat = DateTimeFormat.forPattern(getDateFormat());
}

PresenterUtils:

public class PresenterUtils extends Utils {

    public String getDateFormat() {
        return getResources().getString(R.string.date_format);
    }
}

Utils extends AppCompatActivity, so context has to be available for this class. But its not. I mean, IDE allows me to apply getResources() method, but I've got an exception right after launching:

java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{...} java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference

Exception points to getResources().getString(R.string.date_format)

But! If I apply application context

public class PresenterUtils extends Utils {

    public String getDateFormat() {
        return ContextProvider.getContext().getResources().getString(R.string.date_format);
    }
}

where ContextProvider is

public class ContextProvider extends Application {

    private static ContextProvider instance;

    public ContextProvider() {
        instance = this;
    }

    public static Context getContext() {
        return instance;
    }
}

everything is fine

Why is that?

Anton
  • 449
  • 2
  • 7
  • 20
  • What does your implementation of `getResources()` do in `PresenterUtils.getResources()`? – George Mulligan Mar 27 '16 at 19:33
  • @GeorgeMulligan what do you mean? It has to extract string from strings.xml as I specified in code: getResources().getString(R.string.date_format); – Anton Mar 27 '16 at 19:38
  • What does your `Utils` class definition look like then? I'm asking this because I don't know why the `getResources()` call is valid from there because you need a `Context` for that call. Does `Utils` extend something or did you implement that method yourself? – George Mulligan Mar 27 '16 at 19:43
  • @GeorgeMulligan I mentioned, that Utils extends AppCompatActivity. But I guess nuuneoi has already enlightened me – Anton Mar 27 '16 at 19:45
  • I see sorry I missed the part where you mentioned that. You were already passing in a context with `new Presenter(this)` so I thought you had a method to return `context.getResources()` in the `Utils` class named `getResources()`. – George Mulligan Mar 27 '16 at 19:51

1 Answers1

2

To be extended from AppCompatActivity doesn't mean it will have a Context. It needs to be created as an Activity as well or it will be just another object created.

In this case, it is obviously that your PresenterUtils (Presenter) class is manually initialized. So you need to pass a Context to this class and use it instead.

public class PresenterUtils extends Utils {

    private Context context;

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

    public String getDateFormat() {
        return context.getResources().getString(R.string.date_format);
    }
}
nuuneoi
  • 1,788
  • 1
  • 17
  • 14
  • Could you explain me please, why MainActivity extending AppCompatActivity already has a Context? I think I'm about to rediscover android for myself – Anton Mar 27 '16 at 19:35
  • 1
    MainActivity is created by the system as an Activity. In that case, an Activity Context will be created by the system and is passed into MainActivity. The key is "it needs to be created by the system as an Activity" or there will be no Context inside. – nuuneoi Mar 27 '16 at 19:41
  • It's so great to learn something new. Thank you! – Anton Mar 27 '16 at 19:42