我有3个片段和一个活动。这些片段定义了一个用于将结果传递给活动的接口。
此接口在onAttach()中初始化,并在onDetach()中设置为null。但是,当活动被销毁并在轮换时重新创建时,接口将设置为null,并且在调用它们时,会导致NullPointerException。
这是片段和活动的代码。
MainActivity.java
package com.gianfranco.rsa.view;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import com.gianfranco.rsa.R;
import com.gianfranco.rsa.view.fragment.InputKeySizeFragment;
import com.gianfranco.rsa.view.fragment.InputPlainTextFragment;
import com.gianfranco.rsa.view.fragment.RSADetailsFragment;
public class MainActivity extends AppCompatActivity implements InputKeySizeFragment.OnKeySizeListener,
InputPlainTextFragment.OnMessageListener, RSADetailsFragment.OnClickHomeListener {
private InputKeySizeFragment inputKeySizeFragment;
private InputPlainTextFragment inputPlainTextFragment;
private RSADetailsFragment rsaDetailsFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
inputKeySizeFragment = new InputKeySizeFragment();
inputPlainTextFragment = new InputPlainTextFragment();
rsaDetailsFragment = new RSADetailsFragment();
getSupportFragmentManager().beginTransaction()
.add(R.id.main_container, inputKeySizeFragment)
.addToBackStack(null)
.commit();
}
}
@Override
public void onKeySizeSelected(int keySize) {
getSupportFragmentManager().beginTransaction()
.add(R.id.main_container, inputPlainTextFragment)
.addToBackStack(null)
.commit();
}
@Override
public void onMessageEntered(String message) {
getSupportFragmentManager().beginTransaction()
.add(R.id.main_container, rsaDetailsFragment)
.addToBackStack(null)
.commit();
}
@Override
public void onClickHome() {
getSupportFragmentManager().popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
getSupportFragmentManager().beginTransaction()
.add(R.id.main_container, inputKeySizeFragment)
.addToBackStack(null)
.commit();
}
}
InputKeySizeFragment.java
package com.gianfranco.rsa.view.fragment;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Spinner;
import com.gianfranco.rsa.R;
public class InputKeySizeFragment extends Fragment {
private Spinner keySizeSpinner;
private Button buttonNext;
private ArrayAdapter<Integer> adapter;
private OnKeySizeListener listener;
@FunctionalInterface
public interface OnKeySizeListener {
void onKeySizeSelected(int keySize);
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnKeySizeListener) {
listener = (OnKeySizeListener) context;
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_input_key_size, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
keySizeSpinner = view.findViewById(R.id.spinner_key_size);
buttonNext = view.findViewById(R.id.btn_next);
Integer[] bits = new Integer[]{64, 128, 256, 512, 1024, 2048};
adapter = new ArrayAdapter<>(getActivity(), R.layout.support_simple_spinner_dropdown_item, bits);
adapter.setDropDownViewResource(R.layout.support_simple_spinner_dropdown_item);
keySizeSpinner.setAdapter(adapter);
buttonNext.setOnClickListener(v -> {
int keySize = (Integer) keySizeSpinner.getSelectedItem();
listener.onKeySizeSelected(keySize);
});
}
@Override
public void onDestroyView() {
keySizeSpinner = null;
buttonNext = null;
adapter = null;
super.onDestroyView();
}
@Override
public void onDetach() {
listener = null;
super.onDetach();
}
}
InputPlainTextFragment.java
package com.gianfranco.rsa.view.fragment;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.Snackbar;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import com.gianfranco.rsa.R;
public class InputPlainTextFragment extends Fragment {
private EditText editTextMessage;
private Snackbar snackbar;
private Button buttonNext;
private OnMessageListener listener;
@FunctionalInterface
public interface OnMessageListener {
void onMessageEntered(String message);
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnMessageListener) {
listener = (OnMessageListener) context;
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_input_plain_text, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
editTextMessage = view.findViewById(R.id.et_message);
buttonNext = view.findViewById(R.id.btn_details);
buttonNext.setOnClickListener(v -> listener.onMessageEntered(editTextMessage.getText().toString()));
}
@Override
public void onDestroyView() {
editTextMessage = null;
buttonNext = null;
super.onDestroyView();
}
@Override
public void onDetach() {
listener = null;
super.onDetach();
}
}
RSADetailsFragment.java
package com.gianfranco.rsa.view.fragment;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import com.gianfranco.rsa.R;
public class RSADetailsFragment extends Fragment {
private TextView pValue;
private TextView qValue;
private TextView nValue;
private TextView zValue;
private TextView dValue;
private TextView eValue;
private TextView encryptedValue;
private TextView decryptedValue;
private Button buttonHome;
private OnClickHomeListener listener;
@FunctionalInterface
public interface OnClickHomeListener {
void onClickHome();
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnClickHomeListener) {
listener = (OnClickHomeListener) context;
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_rsa_details, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
pValue = view.findViewById(R.id.tv_pValue);
qValue = view.findViewById(R.id.tv_qValue);
nValue = view.findViewById(R.id.tv_nValue);
zValue = view.findViewById(R.id.tv_zValue);
dValue = view.findViewById(R.id.tv_dValue);
eValue = view.findViewById(R.id.tv_eValue);
encryptedValue = view.findViewById(R.id.tv_encrypted_value);
decryptedValue = view.findViewById(R.id.tv_decrypted_value);
buttonHome = view.findViewById(R.id.btn_home);
buttonHome.setOnClickListener(v -> listener.onClickHome());
}
@Override
public void onDestroyView() {
pValue = null;
qValue = null;
nValue = null;
zValue = null;
dValue = null;
eValue = null;
encryptedValue = null;
decryptedValue = null;
buttonHome = null;
super.onDestroyView();
}
@Override
public void onDetach() {
listener = null;
super.onDetach();
}
}
这是错误消息
03-10 00:03:16.243 31676-31676/com.gianfranco.rsa E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.gianfranco.rsa, PID: 31676
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Class java.lang.Object.getClass()' on a null object reference
at android.support.v4.app.BackStackRecord.doAddOp(BackStackRecord.java:392)
at android.support.v4.app.BackStackRecord.add(BackStackRecord.java:381)
at com.gianfranco.rsa.view.MainActivity.onKeySizeSelected(MainActivity.java:39)
at com.gianfranco.rsa.view.fragment.InputKeySizeFragment.lambda$onViewCreated$0$InputKeySizeFragment(InputKeySizeFragment.java:58)
at com.gianfranco.rsa.view.fragment.InputKeySizeFragment$$Lambda$0.onClick(Unknown Source)
at android.view.View.performClick(View.java:4819)
at android.view.View$PerformClick.run(View.java:20152)
at android.os.Handler.handleCallback(Handler.java:815)
at android.os.Handler.dispatchMessage(Handler.java:104)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5562)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:968)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:763)
我有什么遗漏或做错了吗?请让我知道。
答案 0 :(得分:0)
Add this line in your activity manifest
机器人:configChanges = “keyboardHidden |取向|屏幕尺寸”
<activity android:name=".MainActivity"
android:configChanges="keyboardHidden|orientation|screenSize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>