MVP(Android) 中的 Presenter 对象获取空对象引用错误
Presenter object in MVP(Android) getting null object reference error
我正在使用 MVP。我的 activity 包含一个列表视图。我正在 Activity 的 on Create 方法中初始化演示器,然后使用该演示器对象调用接口方法来获取数据并设置列表视图适配器。
我的问题是当在任何 onClick 侦听器中使用 Presenter 对象然后工作正常但是当我直接使用它时它在 Presenter 对象上给出 NullPointerException。
这是我的代码片段:
这是我的 Activity :-
public class EmployeeListActivity extends AppCompatActivity implements EmployeeContract.View {
private static final String TAG = EmployeeListActivity.class.getSimpleName();
private ListView listView;
private EmployeeContract.GetPresenter presenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_employee_list);
presenter = new EmployeePresenter(this); //--> Presenter inialization
}
@Override
public void initView() {
try {
listView = findViewById(R.id.listview);
presenter.getEmployees(listView); //--> interface method calling (Here I got exception.)
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
presenter.listViewClick(position); //--> Same thing working perfectly here
}
});
} catch (Exception e) {
e.printStackTrace();
String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
ErrorLog.saveLog(getBaseContext(), TAG, methodName, e.getMessage(), String.valueOf(e.getCause()));
}
}
@Override
protected void onResume() {
super.onResume();
presenter = new EmployeePresenter(this);
}
}
我们会提供帮助。提前谢谢你。
已更新
这是我的错误日志
01-29 16:11:54.709 28540-28540/com.example.myfirstexamplemvp W/System.err: java.lang.NullPointerException: Attempt to invoke interface method 'void com.example.myfirstexamplemvp.contract.EmployeeContract$GetPresenter.getEmployees(android.widget.ListView)' on a null object reference
01-29 16:11:54.709 28540-28540/com.example.myfirstexamplemvp W/System.err: at com.example.myfirstexamplemvp.view.EmployeeListActivity.initView(EmployeeListActivity.java:35)
01-29 16:11:54.709 28540-28540/com.example.myfirstexamplemvp W/System.err: at com.example.myfirstexamplemvp.presenter.EmployeePresenter.initPresenter(EmployeePresenter.java:40)
01-29 16:11:54.709 28540-28540/com.example.myfirstexamplemvp W/System.err: at com.example.myfirstexamplemvp.presenter.EmployeePresenter.<init>(EmployeePresenter.java:34)
01-29 16:11:54.709 28540-28540/com.example.myfirstexamplemvp W/System.err: at com.example.myfirstexamplemvp.view.EmployeeListActivity.onCreate(EmployeeListActivity.java:28)
01-29 16:11:54.709 28540-28540/com.example.myfirstexamplemvp W/System.err: at android.app.Activity.performCreate(Activity.java:6582)
01-29 16:11:54.709 28540-28540/com.example.myfirstexamplemvp W/System.err: at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1113)
01-29 16:11:54.709 28540-28540/com.example.myfirstexamplemvp W/System.err: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2532)
01-29 16:11:54.709 28540-28540/com.example.myfirstexamplemvp W/System.err: at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2667)
01-29 16:11:54.709 28540-28540/com.example.myfirstexamplemvp W/System.err: at android.app.ActivityThread.-wrap11(ActivityThread.java)
01-29 16:11:54.709 28540-28540/com.example.myfirstexamplemvp W/System.err: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1494)
01-29 16:11:54.709 28540-28540/com.example.myfirstexamplemvp W/System.err: at android.os.Handler.dispatchMessage(Handler.java:111)
01-29 16:11:54.709 28540-28540/com.example.myfirstexamplemvp W/System.err: at android.os.Looper.loop(Looper.java:207)
01-29 16:11:54.710 28540-28540/com.example.myfirstexamplemvp W/System.err: at android.app.ActivityThread.main(ActivityThread.java:5776)
01-29 16:11:54.710 28540-28540/com.example.myfirstexamplemvp W/System.err: at java.lang.reflect.Method.invoke(Native Method)
01-29 16:11:54.710 28540-28540/com.example.myfirstexamplemvp W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
01-29 16:11:54.710 28540-28540/com.example.myfirstexamplemvp W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:679)
这是我的主持人:-
public class EmployeePresenter implements EmployeeContract.AddPresenter, EmployeeContract.GetPresenter, EmployeeContract.EditPresenter {
private EmployeeContract.View view;
AddEmployeeModel model;
SqliteController controller;
public EmployeePresenter(EmployeeContract.View view) {
this.view = view;
initPresenter();
}
private void initPresenter() {
model = new AddEmployeeModel();
controller = new SqliteController((Context) view);
view.initView();
}
@Override
public void getEmployees(final ListView listView) {
List<AddEmployeeModel> list = controller.getEmployeeList();
ArrayList<String> empname = new ArrayList<String>();
if (list.size() > 0) {
for (int i = 0; i < list.size(); i++) {
empname.add(list.get(i).getFirstName() + " " + list.get(i).getLastName());
}
listView.setAdapter(new ArrayAdapter<String>((Context) view, android.R.layout.simple_expandable_list_item_1, empname));
}
}
}
试试这个:
public class EmployeeListActivity extends AppCompatActivity implements EmployeeContract.View {
private static final String TAG = EmployeeListActivity.class.getSimpleName();
private ListView listView;
private EmployeeContract.GetPresenter presenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_employee_list);
presenter = new EmployeePresenter(this);
}
@Override
public void initView(List<Employee> employees, Presenter.Callback callback) {
listView = findViewById(R.id.listview);
EmployeesAdapter adapter = new EmployeesAdapter(this, employees);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
callback.onClick(position);
}
})
}
@Override
protected void onResume() {
super.onResume();
//presenter = new EmployeePresenter(this);
}
进入Presenter
public EmployeePresenter(EmployeeView view) {
List<Employee> employees = ...; // get the list of employees
Callback callback = new Callback(){
void onClick(int position){
listViewClick(position);
}
}
view.initView(employees, callback);
}
public interface Callback{
void onClick(int position);
}
我认为您的代码违反了 MVP.your Presenter 不应包含任何 android code.that MVP 的强大功能以便于测试。
1- 在 init() 方法中初始化您的 listView,包括设置适配器。
public void initView() {
listView = findViewById(R.id.listview);
adapter = new EmployeesAdapter(this, employeesList);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
presenter.listItemWasClicked(position).
}
})
}
2- 创建一个名为 EmployeeData 的接口。
public interface EmployeeData {
void add(Employee employee);
Employee getEmployee(int position);
int getSize();
}
3- 在您的适配器中实现 EmployeeData.
{
//.....adapter methods
@Overrride
public Employee getEmployee(int position){
return myEmployeeList.get(position);
}
//.. other methods.
}
4- 在您的演示者中
private EmployeeData empData;
public EmployeePresenter (View view,EmployeeData empData){
this.empData=empData;
//... other init
}
@Override
public void listItemWasClicked(int position){
Employee emp=empData.getEmployee(position)
}
5- inside your activity in onCreate()
例如,初始化你的Presenter。
employeePresenter=new EmployeePresenter(this,listAdapter);
注意:只是不要忘记在创建presnter
之前调用initView()
我正在使用 MVP。我的 activity 包含一个列表视图。我正在 Activity 的 on Create 方法中初始化演示器,然后使用该演示器对象调用接口方法来获取数据并设置列表视图适配器。
我的问题是当在任何 onClick 侦听器中使用 Presenter 对象然后工作正常但是当我直接使用它时它在 Presenter 对象上给出 NullPointerException。
这是我的代码片段:
这是我的 Activity :-
public class EmployeeListActivity extends AppCompatActivity implements EmployeeContract.View {
private static final String TAG = EmployeeListActivity.class.getSimpleName();
private ListView listView;
private EmployeeContract.GetPresenter presenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_employee_list);
presenter = new EmployeePresenter(this); //--> Presenter inialization
}
@Override
public void initView() {
try {
listView = findViewById(R.id.listview);
presenter.getEmployees(listView); //--> interface method calling (Here I got exception.)
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
presenter.listViewClick(position); //--> Same thing working perfectly here
}
});
} catch (Exception e) {
e.printStackTrace();
String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
ErrorLog.saveLog(getBaseContext(), TAG, methodName, e.getMessage(), String.valueOf(e.getCause()));
}
}
@Override
protected void onResume() {
super.onResume();
presenter = new EmployeePresenter(this);
}
}
我们会提供帮助。提前谢谢你。
已更新
这是我的错误日志
01-29 16:11:54.709 28540-28540/com.example.myfirstexamplemvp W/System.err: java.lang.NullPointerException: Attempt to invoke interface method 'void com.example.myfirstexamplemvp.contract.EmployeeContract$GetPresenter.getEmployees(android.widget.ListView)' on a null object reference
01-29 16:11:54.709 28540-28540/com.example.myfirstexamplemvp W/System.err: at com.example.myfirstexamplemvp.view.EmployeeListActivity.initView(EmployeeListActivity.java:35)
01-29 16:11:54.709 28540-28540/com.example.myfirstexamplemvp W/System.err: at com.example.myfirstexamplemvp.presenter.EmployeePresenter.initPresenter(EmployeePresenter.java:40)
01-29 16:11:54.709 28540-28540/com.example.myfirstexamplemvp W/System.err: at com.example.myfirstexamplemvp.presenter.EmployeePresenter.<init>(EmployeePresenter.java:34)
01-29 16:11:54.709 28540-28540/com.example.myfirstexamplemvp W/System.err: at com.example.myfirstexamplemvp.view.EmployeeListActivity.onCreate(EmployeeListActivity.java:28)
01-29 16:11:54.709 28540-28540/com.example.myfirstexamplemvp W/System.err: at android.app.Activity.performCreate(Activity.java:6582)
01-29 16:11:54.709 28540-28540/com.example.myfirstexamplemvp W/System.err: at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1113)
01-29 16:11:54.709 28540-28540/com.example.myfirstexamplemvp W/System.err: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2532)
01-29 16:11:54.709 28540-28540/com.example.myfirstexamplemvp W/System.err: at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2667)
01-29 16:11:54.709 28540-28540/com.example.myfirstexamplemvp W/System.err: at android.app.ActivityThread.-wrap11(ActivityThread.java)
01-29 16:11:54.709 28540-28540/com.example.myfirstexamplemvp W/System.err: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1494)
01-29 16:11:54.709 28540-28540/com.example.myfirstexamplemvp W/System.err: at android.os.Handler.dispatchMessage(Handler.java:111)
01-29 16:11:54.709 28540-28540/com.example.myfirstexamplemvp W/System.err: at android.os.Looper.loop(Looper.java:207)
01-29 16:11:54.710 28540-28540/com.example.myfirstexamplemvp W/System.err: at android.app.ActivityThread.main(ActivityThread.java:5776)
01-29 16:11:54.710 28540-28540/com.example.myfirstexamplemvp W/System.err: at java.lang.reflect.Method.invoke(Native Method)
01-29 16:11:54.710 28540-28540/com.example.myfirstexamplemvp W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
01-29 16:11:54.710 28540-28540/com.example.myfirstexamplemvp W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:679)
这是我的主持人:-
public class EmployeePresenter implements EmployeeContract.AddPresenter, EmployeeContract.GetPresenter, EmployeeContract.EditPresenter {
private EmployeeContract.View view;
AddEmployeeModel model;
SqliteController controller;
public EmployeePresenter(EmployeeContract.View view) {
this.view = view;
initPresenter();
}
private void initPresenter() {
model = new AddEmployeeModel();
controller = new SqliteController((Context) view);
view.initView();
}
@Override
public void getEmployees(final ListView listView) {
List<AddEmployeeModel> list = controller.getEmployeeList();
ArrayList<String> empname = new ArrayList<String>();
if (list.size() > 0) {
for (int i = 0; i < list.size(); i++) {
empname.add(list.get(i).getFirstName() + " " + list.get(i).getLastName());
}
listView.setAdapter(new ArrayAdapter<String>((Context) view, android.R.layout.simple_expandable_list_item_1, empname));
}
}
}
试试这个:
public class EmployeeListActivity extends AppCompatActivity implements EmployeeContract.View {
private static final String TAG = EmployeeListActivity.class.getSimpleName();
private ListView listView;
private EmployeeContract.GetPresenter presenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_employee_list);
presenter = new EmployeePresenter(this);
}
@Override
public void initView(List<Employee> employees, Presenter.Callback callback) {
listView = findViewById(R.id.listview);
EmployeesAdapter adapter = new EmployeesAdapter(this, employees);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
callback.onClick(position);
}
})
}
@Override
protected void onResume() {
super.onResume();
//presenter = new EmployeePresenter(this);
}
进入Presenter
public EmployeePresenter(EmployeeView view) {
List<Employee> employees = ...; // get the list of employees
Callback callback = new Callback(){
void onClick(int position){
listViewClick(position);
}
}
view.initView(employees, callback);
}
public interface Callback{
void onClick(int position);
}
我认为您的代码违反了 MVP.your Presenter 不应包含任何 android code.that MVP 的强大功能以便于测试。
1- 在 init() 方法中初始化您的 listView,包括设置适配器。
public void initView() {
listView = findViewById(R.id.listview);
adapter = new EmployeesAdapter(this, employeesList);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
presenter.listItemWasClicked(position).
}
})
}
2- 创建一个名为 EmployeeData 的接口。
public interface EmployeeData {
void add(Employee employee);
Employee getEmployee(int position);
int getSize();
}
3- 在您的适配器中实现 EmployeeData.
{
//.....adapter methods
@Overrride
public Employee getEmployee(int position){
return myEmployeeList.get(position);
}
//.. other methods.
}
4- 在您的演示者中
private EmployeeData empData;
public EmployeePresenter (View view,EmployeeData empData){
this.empData=empData;
//... other init
}
@Override
public void listItemWasClicked(int position){
Employee emp=empData.getEmployee(position)
}
5- inside your activity in onCreate()
例如,初始化你的Presenter。
employeePresenter=new EmployeePresenter(this,listAdapter);
注意:只是不要忘记在创建presnter
之前调用initView()