请帮忙。
编辑以提出更简单直接的问题
我有三个 Activity (A、B 和 C),每个 Activity 都托管一个 fragment 。 从 fragment C 导航到 fragment B 时,工具栏上的向上箭头导航不起作用。但是,使用内置 Android 后退箭头导航可以正常工作。
将下面生命周期方法的日志记录与两种不同的后退导航进行比较,为什么它会被工具栏后退导航破坏、分离和重新创建(由于参数包为空而崩溃并重新启动应用程序),而在内置的 Android 后退导航上却直接从停止到开始?
工具栏向上箭头上的 Activity 和 fragment 生命周期的顺序
11-30 19:41:15.491 2070-2086/? I/PgedBinderListener: kstate callback type:16 value1=1433 value2=CALLED
11-30 19:41:15.537 13374-13374/com.navsaria.keeran.clinicbook I/ChildDetailsFragment: onCreate Called
11-30 19:41:15.541 13374-13374/com.navsaria.keeran.clinicbook I/ChildDetailsFragment: onCreateView Called
11-30 19:41:15.607 13374-13374/com.navsaria.keeran.clinicbook I/ChildDetailsFragment: onDestroyView Called
11-30 19:41:15.607 13374-13374/com.navsaria.keeran.clinicbook I/ChildDetailsFragment: onStart Called
11-30 19:41:15.607 13374-13374/com.navsaria.keeran.clinicbook I/child_details_activity: onStart() called
11-30 19:41:15.607 13374-13374/com.navsaria.keeran.clinicbook I/child_details_activity: onResume() called
11-30 19:41:15.607 13374-13374/com.navsaria.keeran.clinicbook I/ChildDetailsFragment: onResume Called
11-30 19:41:17.321 13374-13374/com.navsaria.keeran.clinicbook I/child_details_activity: onPause() called
11-30 19:41:17.878 13374-13374/com.navsaria.keeran.clinicbook I/ChildDetailsFragment: onStopCalled
11-30 19:41:17.878 13374-13374/com.navsaria.keeran.clinicbook I/child_details_activity: onStop() called
11-30 19:41:18.838 13374-13374/com.navsaria.keeran.clinicbook I/ChildDetailsFragment: onDestroyView Called
11-30 19:41:18.839 13374-13374/com.navsaria.keeran.clinicbook I/ChildDetailsFragment: onDestroy Called
11-30 19:41:18.839 13374-13374/com.navsaria.keeran.clinicbook I/ChildDetailsFragment: onDetached Called
11-30 19:41:18.839 13374-13374/com.navsaria.keeran.clinicbook I/child_details_activity: onDestroy() called
11-30 19:41:18.874 13374-13374/com.navsaria.keeran.clinicbook I/ChildDetailsFragment: onCreate Called
带有 Android 内置后退箭头的 Activity 和 Fragment 生命周期的顺序
12-02 22:31:10.355 16037-16037/com.navsaria.keeran.clinicbook I/ChildDetailsFragment: onCreate Called
12-02 22:31:10.357 16037-16037/com.navsaria.keeran.clinicbook I/ChildDetailsFragment: onCreateView Called
12-02 22:31:10.420 16037-16037/com.navsaria.keeran.clinicbook I/ChildDetailsFragment: onDestroyView Called
12-02 22:31:10.420 16037-16037/com.navsaria.keeran.clinicbook I/ChildDetailsFragment: onStart Called
12-02 22:31:10.420 16037-16037/com.navsaria.keeran.clinicbook I/child_details_activity: onStart() called
12-02 22:31:10.421 16037-16037/com.navsaria.keeran.clinicbook I/child_details_activity: onResume() called
12-02 22:31:10.421 16037-16037/com.navsaria.keeran.clinicbook I/ChildDetailsFragment: onResume Called
12-02 22:31:13.499 16037-16037/com.navsaria.keeran.clinicbook I/child_details_activity: onPause() called
12-02 22:31:14.122 16037-16037/com.navsaria.keeran.clinicbook I/ChildDetailsFragment: onStopCalled
12-02 22:31:14.122 16037-16037/com.navsaria.keeran.clinicbook I/child_details_activity: onStop() called
12-02 22:31:27.380 16037-16037/com.navsaria.keeran.clinicbook I/ChildDetailsFragment: onStart Called
12-02 22:31:27.380 16037-16037/com.navsaria.keeran.clinicbook I/child_details_activity: onStart() called
12-02 22:31:27.380 16037-16037/com.navsaria.keeran.clinicbook I/child_details_activity: onResume() called
12-02 22:31:27.380 16037-16037/com.navsaria.keeran.clinicbook I/ChildDetailsFragment: onResume Called
举办 Activity 的抽象类
public abstract class SingleFragmentActivity extends AppCompatActivity {
protected abstract Fragment createFragment();
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fragment);
FragmentManager fm = getSupportFragmentManager();
Fragment fragment = fm.findFragmentById(R.id.fragment_container);
if (fragment == null) {
fragment = createFragment();
fm.beginTransaction()
.add(R.id.fragment_container, fragment)
.commit();
}
}
}
Activity B
public class ChildDetailsActivity extends SingleFragmentActivity {
public static final String EXTRA_CHILD_ID =
"com.navsaria.keeran.clinicbook.child_id";
public static final String TAG = "child_details_activity";
public static Intent newIntent(Context packagedContext, UUID childId) {
Intent intent = new Intent(packagedContext, ChildDetailsActivity.class);
intent.putExtra(EXTRA_CHILD_ID, childId);
return intent;
}
@Override
protected Fragment createFragment() {
UUID childId = (UUID) getIntent().getSerializableExtra(EXTRA_CHILD_ID);
return ChildDetailsFragment.newInstance(childId);
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) {
super.onCreate(savedInstanceState, persistentState);
Log.i(TAG, "onCreate() called");
}
@Override
protected void onStart() {
super.onStart();
Log.i(TAG, "onStart() called");
}
@Override
protected void onResume() {
super.onResume();
Log.i(TAG, "onResume() called");
}
@Override
protected void onPause() {
super.onPause();
Log.i(TAG, "onPause() called");
}
@Override
protected void onStop() {
super.onStop();
String uuid = getIntent().getSerializableExtra(EXTRA_CHILD_ID).toString();
Log.i(TAG, "onStop() called" + uuid);
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.i(TAG, "onDestroy() called");
}
}
fragment B
public class ChildDetailsFragment extends Fragment{
private RecyclerView mRecyclerView;
private Child mChild;
private static final String ARGS_ID = "child_id";
private static final String SAVED_INSTANCE_STATE_UUID = "clinicbook.childdetailsfragment.mchildid";
public static ChildDetailsFragment newInstance(UUID childId) {
ChildDetailsFragment childDetailsFragment = new ChildDetailsFragment();
Bundle args = new Bundle();
args.putSerializable(ARGS_ID, childId);
childDetailsFragment.setArguments(args);
return childDetailsFragment;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i("ChildDetailsFragment", "onCreate Called");
ChildList childList = ChildList.getChildList(getActivity());
UUID childId = (UUID) getArguments().getSerializable(ARGS_ID);
mChild = childList.getChild(childId);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_child_details, container, false);
((AppCompatActivity)getActivity()).getSupportActionBar().setTitle(mChild.getFirstName() + " " + mChild.getLastName());
mRecyclerView = (RecyclerView) v.findViewById(R.id.child_recycler_view);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
mRecyclerView.setAdapter(new CategoryAdapter());
return v;
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i("ChildDetailsFragment", "onDestroy Called");
}
@Override
public void onStop() {
super.onStop();
Log.i("ChildDetailsFragment", "fragment onStopCalled");
}
///////////////////////////////////////////////////////////////
//RecyclerView ViewHolder
private class CategoryHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public CategoryHolder(LayoutInflater inflater, ViewGroup parent) {
super(inflater.inflate(R.layout.category_list_item, parent, false));
((LinearLayout) itemView).setOnClickListener(this);
}
public void bind(String category) {
TextView categoryTitle = itemView.findViewById(R.id.category_title);
categoryTitle.setText(category);
}
@Override
public void onClick(View view) {
Intent intent = new Intent(getActivity(), PersonalDataActivity.class);
startActivity(intent);
}
}
//RecyclerView ViewHolder
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
//RecyclerView Adapter
private class CategoryAdapter extends RecyclerView.Adapter<CategoryHolder> {
private final String[] mCategoryList = {
"Personal Data",
"Growth Measurements",
"Growth Stages",
"Immunisations",
"Medications",
"Allergies"
};
@Override
public CategoryHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(getActivity());
return new CategoryHolder(inflater, parent);
}
@Override
public void onBindViewHolder(CategoryHolder holder, int position) {
String category = mCategoryList[position];
holder.bind(category);
}
@Override
public int getItemCount() {
return mCategoryList.length;
}
}
//RecyclerView Adapter
///////////////////////////////////////////////////////////////
}// End of Class ChildDetailsFragment
Activity C
public class PersonalDataActivity extends SingleFragmentActivity {
@Override
protected Fragment createFragment() {
return new PersonalDataFragment();
}
}
fragment C 公共(public)类 PersonalDataFragment 扩展 Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_personal_data, container, false);
return v;
}
}
AndroidManifest.xml
<activity android:name=".ChildrenActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".ChildDetailsActivity"
android:parentActivityName=".ChildrenActivity">
</activity>
<activity android:name=".PersonalDataActivity"
android:parentActivityName=".ChildDetailsActivity">
</activity>
堆栈跟踪 fatal error 如下:
12-02 22:42:18.330 16037-16037/com.navsaria.keeran.clinicbook E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.navsaria.keeran.clinicbook, PID: 16037
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.navsaria.keeran.clinicbook/com.navsaria.keeran.clinicbook.ChildDetailsActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.util.UUID.toString()' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2479)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2539)
at android.app.ActivityThread.access$900(ActivityThread.java:168)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1378)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:150)
at android.app.ActivityThread.main(ActivityThread.java:5659)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:822)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:712)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.util.UUID.toString()' on a null object reference
at com.navsaria.keeran.clinicbook.ChildList.getChild(ChildList.java:67)
at com.navsaria.keeran.clinicbook.ChildDetailsFragment.onCreate(ChildDetailsFragment.java:50)
at android.support.v4.app.Fragment.performCreate(Fragment.java:2339)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1377)
at android.support.v4.app.FragmentTransition.addToFirstInLastOut(FragmentTransition.java:1109)
at android.support.v4.app.FragmentTransition.calculateFragments(FragmentTransition.java:996)
at android.support.v4.app.FragmentTransition.startTransitions(FragmentTransition.java:99)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2364)
at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2322)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2229)
at android.support.v4.app.FragmentManagerImpl.dispatchStateChange(FragmentManager.java:3221)
at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:3171)
at android.support.v4.app.FragmentController.dispatchActivityCreated(FragmentController.java:192)
at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:560)
at android.support.v7.app.AppCompatActivity.onStart(AppCompatActivity.java:177)
at com.navsaria.keeran.clinicbook.ChildDetailsActivity.onStart(ChildDetailsActivity.java:56)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1241)
at android.app.Activity.performStart(Activity.java:6392)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2442)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2539)
at android.app.ActivityThread.access$900(ActivityThread.java:168)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1378)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:150)
at android.app.ActivityThread.main(ActivityThread.java:5659)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:822)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:712)
测试设备为华为P9 lite
最佳答案
找到解决方案:
将 AndroidManifest 中 ChildDetailsActivity 的 launchMode 更改为“singleTop”,以便返回堆栈中的 Activity 接收 Intent,而不是创建新 Activity。
<activity android:name=".ChildDetailsActivity"
android:parentActivityName=".ChildrenActivity"
android:launchMode="singleTop">
</activity>
关于java - 使用工具栏向上箭头导航会重新启动应用程序,但 Android 内置箭头按钮可以工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47572907/