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:nullオブジェクト参照でインターフェイスメソッド 'void com.example.usama.demoapp.fragments.LoginFragment $ CallBacks.onLoggedIn()'を呼び出そうとしました
これで案内してください。
あなたは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メソッドのパラメーターとしてContextではなくActivityを渡すと、機能します。しかし、なぜそれがエラーを引き起こしているのか知りたいですか?
理由は簡単です。あなたのアクティビティはすでにそのインターフェースを実装しているので、それをLoginFragment
コンテキストとしてあなたに渡すと、条件if (context instanceof CallBacks)
が真になります。ただし、裸で合格context
しても、そのif
声明は成立しません。
セッターを定義する方法を教えてください。
とても簡単です!他の通常のメソッドと同様に、次のようなメソッドを宣言します。
public void setOnLoginListener(Callbacks listener){
this.callbacks = listener;
}
アップデート#2
ここで、setOnLoginListenerメソッドを定義する必要があります
内部LoginFragment
クラス。
どこに呼べばいいの?
LoginFragment
クラスを最初にインスタンス化するメインアクティビティ。
どのパラメータで?
そのJavaインターフェースを実装するアクティビティ。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加