我正在尝试为Android Lollipop(5.0)构建一个应用程序。有一个登录片段,当我按登录按钮时,应用程序自动崩溃。我正在分享我的代码和错误消息,请指导我。
BaseActivity.java
public abstract class BaseActivity extends AppCompatActivity {
protected CoreApplication coreApplication;
@Override
protected void onCreate(Bundle savedState) {
super.onCreate(savedState);
coreApplication = (CoreApplication) getApplication();
}
}
BaseAuthenticatedActivity.java
public abstract class BaseAuthenticatedActivity extends BaseActivity {
@Override
protected final void onCreate(Bundle savedState) {
super.onCreate(savedState);
if (!coreApplication.getAuth().getUser().isLoggedIn()) {
startActivity(new Intent(this, LoginActivity.class));
finish();
return;
}
onCoreApplicationCreate(savedState);
}
protected abstract void onCoreApplicationCreate(Bundle savedState);
}
LoginActivity.java
public class LoginActivity extends BaseActivity implements View.OnClickListener, LoginFragment.CallBacks {
private static final int REQUEST_NARROW_LOGIN = 1;
private View loginButton;
@Override
protected void onCreate(Bundle savedState) {
super.onCreate(savedState);
setContentView(R.layout.activity_login);
loginButton = findViewById(R.id.LoginJustChat);
if (loginButton != null) {
loginButton.setOnClickListener(this);
}
}
@Override
public void onClick(View view) {
if (view == loginButton)
startActivityForResult(new Intent(this, LoginNarrowActivity.class), REQUEST_NARROW_LOGIN);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode != RESULT_OK)
return;
if (requestCode == REQUEST_NARROW_LOGIN) {
finishLogin();
}
}
private void finishLogin() {
startActivity(new Intent(this, MainActivity.class));
finish();
}
@Override
public void onLoggedIn() {
finishLogin();
}
}
LoginNarrowActivity.java
public class LoginNarrowActivity extends BaseActivity implements LoginFragment.CallBacks {
@Override
protected void onCreate(Bundle savedState){
super.onCreate(savedState);
setContentView(R.layout.activity_login_narrow);
}
@Override
public void onLoggedIn() {
setResult(RESULT_OK);
finish();
}
}
MainActivity.java
public class MainActivity extends BaseAuthenticatedActivity {
@Override
protected void onCoreApplicationCreate(Bundle savedState) {
}
}
BaseFragment.java
public abstract class BaseFragment extends Fragment {
protected CoreApplication application;
@Override
public void onCreate(Bundle savedInstance) {
super.onCreate(savedInstance);
application = (CoreApplication) getActivity().getApplication();
}
}
LoginFragment.java
public class LoginFragment extends BaseFragment implements View.OnClickListener {
private Button loginButton;
private CallBacks callBacks;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup root, Bundle savedState) {
View view = inflater.inflate(R.layout.fragment_login, root, false);
loginButton = (Button) view.findViewById(R.id.fragment_login_loginButton);
loginButton.setOnClickListener(this);
return view;
}
@Override
public void onClick(View view) {
if (view == loginButton) {
application.getAuth().getUser().setIsLoggedIn(true);
callBacks.onLoggedIn();
}
}
// because onAttach(Activity activity) is deprecated
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof CallBacks) {
callBacks = (CallBacks) context;
} else {
throw new ClassCastException(context.toString()
+ " must implement MyListFragment.OnItemSelectedListener");
}
}
@Override
public void onDetach() {
super.onDetach();
callBacks = null;
}
public interface CallBacks {
void onLoggedIn();
}
}
错误:
java.lang.NullPointerException:尝试调用接口方法
'无效
com.example.usama.demoapp.fragments.LoginFragment $ CallBacks.onLoggedIn()'
在空对象引用上
请用这个指导我。
最佳答案
欢迎使用Android!
您得到一个NullPointerException
。这是非常普遍的[而且很可爱;因为它很容易调试] Java中的异常。检查您的LoginFragment
。以下方法将引发此异常。
@Override
public void onClick(View view) {
if (view == loginButton) {
application.getAuth().getUser().setIsLoggedIn(true);
callBacks.onLoggedIn();
}
}
为了诊断此错误,有几点注意事项:
在声明类成员并对其进行初始化时(在本例中为
callBacks
),Java会自动将其初始化为null
。在
null
引用上调用任何方法都将导致NPE
。好吧,让我们缩小到您的具体情况。您声明了一个名为
callBacks
的类成员,但从未对其进行初始化,而且,我看不到为其分配任何内容的方法。因此,该类成员始终保持为null
,因此对其进行的任何后续方法调用都将导致我们进入NPE
。作为解决方案,您应该在您的
LoginFragment
类中添加一个setter方法,在其中设置该callBacks
。在另一面提供此对象,您首先在其中创建此片段的实例。更新#1
当我在onAttach方法中将Activity而不是Context作为参数传递时,它将起作用。但我想知道为什么会导致错误?
原因很简单。由于您的活动已经实现了该接口,因此将其作为上下文传递给您的
LoginFragment
会导致条件if (context instanceof CallBacks)
变为true。但是,传递裸context
不会导致建立该if
语句。你能告诉我如何定义二传手吗?
非常简单!就像其他常规方法一样,声明这样的方法:
public void setOnLoginListener(Callbacks listener){
this.callbacks = listener;
}
更新#2
我需要定义setOnLoginListener方法的地方
在
LoginFragment
类中。我应该在哪里称呼它
在您首先实例化
LoginFragment
类的主要活动中。有什么参数?
您的活动,该活动实现了该Java接口。