Android fragment lifecycle issue (NullPointerException on onActivityResult)

I have a problem and cannot find an explanation. I have a FragmentActivity that displays fragments using the TabManager, as shown below:

public class WorkOrderFormTabFragmentActivity extends FragmentActivity { TabHost mTabHost; TabManager mTabManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.work_order_form_tab_new); mTabHost = (TabHost)findViewById(android.R.id.tabhost); mTabHost.setup(); mTabManager = new TabManager(this, mTabHost, R.id.realtabcontent); mTabManager.addTab(mTabHost.newTabSpec("form").setIndicator("Form"), WorkOrderFormFragment.class, null); mTabManager.addTab(mTabHost.newTabSpec("pictures").setIndicator("Pictures"), PictureListFragment.class, null); if (savedInstanceState != null) { mTabHost.setCurrentTabByTag(savedInstanceState.getString("tab")); } } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putString("tab", mTabHost.getCurrentTabTag()); } public static class TabManager implements TabHost.OnTabChangeListener { private final FragmentActivity mActivity; private final TabHost mTabHost; private final int mContainerId; private final HashMap<String, TabInfo> mTabs = new HashMap<String, TabInfo>(); TabInfo mLastTab; static final class TabInfo { private final String tag; private final Class<?> clss; private final Bundle args; private Fragment fragment; TabInfo(String _tag, Class<?> _class, Bundle _args) { tag = _tag; clss = _class; args = _args; } } static class DummyTabFactory implements TabHost.TabContentFactory { private final Context mContext; public DummyTabFactory(Context context) { mContext = context; } @Override public View createTabContent(String tag) { View v = new View(mContext); v.setMinimumWidth(0); v.setMinimumHeight(0); return v; } } public TabManager(FragmentActivity activity, TabHost tabHost, int containerId) { mActivity = activity; mTabHost = tabHost; mContainerId = containerId; mTabHost.setOnTabChangedListener(this); } public void addTab(TabHost.TabSpec tabSpec, Class<?> clss, Bundle args) { tabSpec.setContent(new DummyTabFactory(mActivity)); String tag = tabSpec.getTag(); TabInfo info = new TabInfo(tag, clss, args); info.fragment = mActivity.getSupportFragmentManager().findFragmentByTag(tag); if (info.fragment != null && !info.fragment.isDetached()) { FragmentTransaction ft = mActivity.getSupportFragmentManager().beginTransaction(); ft.detach(info.fragment); ft.commit(); } mTabs.put(tag, info); mTabHost.addTab(tabSpec); } @Override public void onTabChanged(String tabId) { TabInfo newTab = mTabs.get(tabId); if (mLastTab != newTab) { FragmentTransaction ft = mActivity.getSupportFragmentManager().beginTransaction(); if (mLastTab != null) { if (mLastTab.fragment != null) { //ft.detach(mLastTab.fragment); ft.hide(mLastTab.fragment); } } if (newTab != null) { if (newTab.fragment == null) { newTab.fragment = Fragment.instantiate(mActivity, newTab.clss.getName(), newTab.args); ft.add(mContainerId, newTab.fragment, newTab.tag); } else { //ft.attach(newTab.fragment); ft.show(newTab.fragment); } } mLastTab = newTab; ft.commit(); mActivity.getSupportFragmentManager().executePendingTransactions(); } } } 

On the second tab of this user FragmentActivity, the user can manage the list of photos and use the camera to add additional images.

Fragment Code:

 public class PictureListFragment extends Fragment { static final int TAKE_PICTURE_ACTIVITY = 1; static final int EDIT_PICTURE_ACTIVITY = 2; FormPictureListAdapter lvAdapter; @Override public View onCreateView(LayoutInflater inflater, ViewGroup viewgrp, Bundle savedInstanceState) { // Inflate the layout for this fragment View cont = inflater.inflate(R.layout.form_picture_list, viewgrp, false); LinearLayout container = (LinearLayout)cont.findViewById(R.id.formPictureListLayout); try{ final Context context = getActivity(); ListView ls2 = new ListView(context); // clear previous results in the LV ls2.setAdapter(null); // populate ArrayList<MFPicture> pictures = new ArrayList<MFPicture>(); //pictures.add(0, new MFPicture()); pictures.addAll(((MFApplication)getActivity().getApplication()).getCurrentForm().getPictures()); lvAdapter = new FormPictureListAdapter(context, pictures); ls2.setAdapter(lvAdapter); LinearLayout.LayoutParams Params = new LinearLayout.LayoutParams(FrameLayout.LayoutParams.FILL_PARENT, 0, 1f); ls2.setLayoutParams(Params); ls2.setOnItemClickListener(new OnItemClickListener() { public void onItemClick(AdapterView<?> parent, View view, int position, long id) { final MFPicture picture = ((MFPictureView)view).getPicture(); final int idx = position; DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { switch (which){ case DialogInterface.BUTTON_POSITIVE: //Edit picture EditPictureActivity.setPicture(picture); Intent configurationOpen = new Intent(getActivity(), EditPictureActivity.class); startActivityForResult(configurationOpen, EDIT_PICTURE_ACTIVITY); break; case DialogInterface.BUTTON_NEGATIVE: //Delete picture ((MFApplication)getActivity().getApplication()).getCurrentForm().getPictures().remove(idx); MFUtils.deleteFile(picture.getPath()); lvAdapter.updatePictureList(((MFApplication)getActivity().getApplication()).getCurrentForm().getPictures()); lvAdapter.notifyDataSetChanged(); break; } } }; AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); builder.setMessage(getResources().getString(R.string.wo_bem_regie_list_el_action)).setPositiveButton(getResources().getString(R.string.wo_bem_regie_list_el_edit), dialogClickListener) .setNegativeButton(getResources().getString(R.string.wo_bem_regie_list_el_delete), dialogClickListener).show(); } }); container.addView(ls2); LayoutInflater layoutInflater = (LayoutInflater)getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE); View view=layoutInflater.inflate(R.layout.add_btn_bottom,container); view.setBackgroundResource(R.drawable.list_selector_even); TextView text = (TextView)view.findViewById(R.id.title); text.setText(getResources().getString(R.string.wo_picturelist_add)); view.setOnClickListener(new OnClickListener() { @Override public void onClick(View v){ v.setBackgroundResource(R.drawable.list_selector_even); String pictureFile = ((MFApplication)getActivity().getApplication()).getNextPictureFile(); String picPath = MFUtils.MF_STORAGE_PATH+"/"+pictureFile; Log.e("FormPictureListActivity", "PicturePath : "+picPath); //setBackgroundResource(android.R.drawable.list_selector_background); try { Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(picPath))); startActivityForResult(intent, TAKE_PICTURE_ACTIVITY); } catch (ActivityNotFoundException e) { Log.e("FormPictureListActivity", "Call failed", e); } } }); } catch(Exception e){ e.printStackTrace(); Log.e("FormPictureListActivity", "Error:", e); } return cont; } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { //super.onActivityResult(requestCode, resultCode, data); String pictureFile = ((MFApplication)getActivity().getApplication()).getPictureFile(); Log.d("FormPictureListActivity", "ActivityResult:"+resultCode); Log.d("FormPictureListActivity", "ActivityResult-picFile:"+pictureFile); if (requestCode == TAKE_PICTURE_ACTIVITY){ if(resultCode == getActivity().RESULT_OK){ Log.d("FormPictureListActivity", "ActivityResult:OK"); MFPicture picture = new MFPicture(MFPicture.TYPE_PICTURE, MFUtils.MF_STORAGE_PATH+"/"+pictureFile); ((MFApplication)getActivity().getApplication()).getCurrentForm().getPictures().add(picture); lvAdapter.updatePictureList(((MFApplication)getActivity().getApplication()).getCurrentForm().getPictures()); lvAdapter.notifyDataSetChanged(); EditPictureActivity.setPicture(picture); Intent configurationOpen = new Intent(getActivity(), EditPictureActivity.class); startActivityForResult(configurationOpen, EDIT_PICTURE_ACTIVITY); } } else if (requestCode == EDIT_PICTURE_ACTIVITY){ EditPictureActivity.getPicture().setComment(EditPictureActivity.getPicture().getCommentUIValue()); lvAdapter.updatePictureList(((MFApplication)getActivity().getApplication()).getCurrentForm().getPictures()); lvAdapter.notifyDataSetChanged(); } } } 

Everything works well on my test devices (Nexus 5, Galaxy Nexus, Galaxy Mini 2), but from time to time I get errors from other devices that I don’t have access to (mostly devices running Android 4.0.4):

 java.lang.RuntimeException: Unable to resume activity {com.mf.mobile.android/com.mf.mobile.android.WorkOrderFormTabFragmentActivity}: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=131073, result=-1, data=null} to activity {com.mf.mobile.android/com.mf.mobile.android.WorkOrderFormTabFragmentActivity}: java.lang.NullPointerException at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2616) at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2644) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2130) at android.app.ActivityThread.access$600(ActivityThread.java:135) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1248) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:4645) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:809) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:576) at dalvik.system.NativeStart.main(Native Method) Caused by: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=131073, result=-1, data=null} to activity {com.mf.mobile.android/com.mf.mobile.android.WorkOrderFormTabFragmentActivity}: java.lang.NullPointerException at android.app.ActivityThread.deliverResults(ActivityThread.java:3156) at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2599) ... 12 more Caused by: java.lang.NullPointerException at com.timewise.mobile.android.fragments.PictureListFragment.onActivityResult(PictureListFragment.java:138) at android.support.v4.app.FragmentActivity.onActivityResult(FragmentActivity.java:166) at android.app.Activity.dispatchActivityResult(Activity.java:4662) at android.app.ActivityThread.deliverResults(ActivityThread.java:3152) ... 13 more 

NPE appears in this line of code: (. ((MframeApplication) getActivity () getApplication ()) getCurrentForm () getPictures () ..) LvAdapter.updatePictureList;

This means that the lvAdapter variable is null at this time. But this variable had to be set to onCreateView of Fragment ... Which makes me think that at some point the Fragment may have been recreated without calling onCreateView.

I can not find an explanation on this issue. Can you help me with this?

Thank you very much

+2
source share
1 answer

Well, I think this can happen if a user opens your application and then clicks the home button, or either clicks the launch button of running applications (the one to the right of the home button), or keeps the house on some phones and selects your application to return to it. Then, if you look at the life cycle, it will call onResume (this is what is in the stack trace above), without calling onCreateView again.

Fragment Life Cycle

Now you can imitate this to see how this happens by going to the developer options on your Nexus 5 and selecting "Do not perform actions." Then open the application, go to this snippet by clicking the home button, then the Launch Application button and select your application, and I think it will show you this exception.

+2
source

Source: https://habr.com/ru/post/984727/


All Articles