I am using MVP. My activity contains one Fragment. I am initializing and then setting presenter to fragment inside Main-Activity's on Create method as follow.
public class MainActivity extends AppCompatActivity {
private StashPresenter stashPresenter;
private MainFragment mainFragment;
FragmentManager fm;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
App.getInstance().getAppComponent().inject(this);
setContentView(R.layout.activity_main);
fm = getSupportFragmentManager();
fm.beginTransaction()
.add(R.id.fragment_container, MainFragment.newInstance(),"mainFragment")
.commitNow();
mainFragment = (MainFragment) fm.findFragmentById(R.id.fragment_container);
stashPresenter = new StashPresenter(mainFragment);
mainFragment.setPresenter(stashPresenter);
}
Inside my mainFrgament class I am settinf Presenter in setPresenterFunction as follow.
public class MainFragment extends Fragment implements
StashContract.PublishToView {
public StashContract.ToPresenter forwardInteraction;
public void setPresenter(StashContract.ToPresenter forwardInteraction)
{
this.forwardInteraction = forwardInteraction;
}
Sometimes while performing searching operation as shown in my following code inside OnCreateView of mainFragment, I gets an error saying my forward "Attempt to invoke interface method on a null object reference"
Sometime I get this error, sometimes I do not. I do not understand why this is happening
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_main, container, false);
unbinder = ButterKnife.bind(this, view);
searchView.setOnEditorActionListener((v, actionId, event) -> {
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
progressBar.setVisibility(View.VISIBLE);
forwardInteraction.searchButtonClick(actionId, searchView.getText().toString());
return true;
}
return false;
});
String[] artistNames = getResources().getStringArray(R.array.artistNamesSuggestion);
ArrayAdapter<String> adapterArtist = new ArrayAdapter<>(getActivity().getApplicationContext(), R.layout.fragment_main, R.id.search_phrase, artistNames);
searchView.setAdapter(adapterArtist);
searchView.setThreshold(1);
recyclerView.setLayoutManager(new GridLayoutManager(getContext(), 3));
recyclerView.setAdapter(adapter);
recyclerView.addItemDecoration(new SpaceItemDecoration(space, space, space, space));
return view;
}
Solution
In the "onCreateView" method of the fragment, only initialize the views.
Move rest of the code in the "onResume" method.
Reason for error
Check this image
As you can see, "onCreateView" of your fragment is called when you are in the "onCreate" method in you activity.
In the current state of your code, there maybe times you when you will try to use the presenter before it is initialized.
Therefore, set your presented in the "onCreate" method of your activity and use it either it on the "onStart" or "onResume" of your fragment.
You can check this project to understand the MVP architecture more.