1

Normally, this is how my fragment's onActivityResult being triggered.

public void onActivityResult(final int requestCode, final int resultCode, final Intent data)

(1) Starting an intent through startActivityForResult from fragment

Intent intent = new Intent(this.getActivity(), NewBuyPortfolioFragmentActivity.class);
startActivityForResult(intent, RequestCode.REQUEST_NEW_BUY_PORTFOLIO_FRAGMENT_ACTIVITY);

(2) Set result and finish from the launched activity

setResult(RESULT_OK, resultIntent);
finish();

(3) Fragment's onActivityResult will be triggered

However, under very rare case (I'm not able to reproduce), I will receive such crash report.

It seems that during activity resuming, my fragment onActivityResult will be triggered, with its requestCode matched to my application requestCode (RequestCode.REQUEST_NEW_BUY_PORTFOLIO_FRAGMENT_ACTIVITY).

Any idea why fragment's onActivityResult will be triggered during activity resuming?

java.lang.RuntimeException: Unable to resume activity {org.yccheok.jstock.gui/org.yccheok.jstock.gui.JStockFragmentActivity}: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=196615, result=-1, data=Intent { (has extras) }} to activity {org.yccheok.jstock.gui/org.yccheok.jstock.gui.JStockFragmentActivity}: java.lang.NullPointerException
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2124)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2139)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1672)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:2836)
at android.app.ActivityThread.access$1600(ActivityThread.java:117)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:939)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3687)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=196615, result=-1, data=Intent { (has extras) }} to activity {org.yccheok.jstock.gui/org.yccheok.jstock.gui.JStockFragmentActivity}: java.lang.NullPointerException
at android.app.ActivityThread.deliverResults(ActivityThread.java:2536)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2111)
... 13 more
Caused by: java.lang.NullPointerException
at org.yccheok.jstock.gui.portfolio.BuyPortfolioFragment.void addTransaction(org.yccheok.jstock.portfolio.Transaction)(SourceFile:733)
at org.yccheok.jstock.gui.portfolio.PortfolioFragment.void onActivityResult(int,int,android.content.Intent)(SourceFile:661)
at android.support.v4.app.FragmentActivity.void onActivityResult(int,int,android.content.Intent)(SourceFile:161)
at org.yccheok.jstock.gui.JStockFragmentActivity.void onActivityResult(int,int,android.content.Intent)(SourceFile:988)
at android.app.Activity.dispatchActivityResult(Activity.java:3908)
at android.app.ActivityThread.deliverResults(ActivityThread.java:2532)
... 14 more

Note, if NPE is being thrown in onActivityResult during the 3 steps normal flow I mention above, I will be getting the below stack trace, without Unable to resume activity message.

Crash report produced from normal onActivityResult flow.

FATAL EXCEPTION: main
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=196615, result=-1, data=Intent { (has extras) }} to activity {org.yccheok.jstock.gui/org.yccheok.jstock.gui.JStockFragmentActivity}: java.lang.NullPointerException
    at android.app.ActivityThread.deliverResults(ActivityThread.java:3141)
    at android.app.ActivityThread.handleSendResult(ActivityThread.java:3184)
    at android.app.ActivityThread.access$1100(ActivityThread.java:130)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1243)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:4745)
    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:786)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
    at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
    at org.yccheok.jstock.gui.portfolio.BuyPortfolioFragment.addTransaction(BuyPortfolioFragment.java:734)
    at org.yccheok.jstock.gui.portfolio.PortfolioFragment.onActivityResult(PortfolioFragment.java:661)
    at android.support.v4.app.FragmentActivity.onActivityResult(FragmentActivity.java:161)
    at org.yccheok.jstock.gui.JStockFragmentActivity.onActivityResult(JStockFragmentActivity.java:988)
    at android.app.Activity.dispatchActivityResult(Activity.java:5192)
    at android.app.ActivityThread.deliverResults(ActivityThread.java:3137)
    ... 11 more
Cheok Yan Cheng
  • 47,586
  • 132
  • 466
  • 875
  • If the activity that started the sub activity is killed while in the background do you make sure it's data is still ok when it's rebuilt as the user comes back from the sub activity? – user Aug 09 '13 at 06:43
  • Yes. We aware of such issues : http://stackoverflow.com/questions/17731070/how-to-differentiate-activity-recreation-is-caused-by-screen-rotation-or-low-me – Cheok Yan Cheng Aug 09 '13 at 06:55
  • What we did is, if such situation happen, we simply close the sub activity, by setResult(RESULT_CANCELED); So, NPE shouldn't happen in onActivityResult, as we ignore RESULT_CANCELED case. – Cheok Yan Cheng Aug 09 '13 at 07:00
  • The `addTransaction()` method throws that exception. Do you use in that method, data fields that **might** not be available yet if the `Activity` is completely recreated? For example if the methods uses a field that is initialized with `null` in the `onCreate()` followed by starting an `AsyncTask` to initialize it, it's safe to assume that you might throw a `NullPointerException` if the `AsyncTask` is not finished by the time the `onActivityResult()` gets called. – user Aug 09 '13 at 07:08
  • Ya. NPE caused by data is not ready yet. But, this shouldn't happen as onResume will make sure data is ready. I'm more interested in why resuming parent activity process can trigger fragment's onActivityResult. As at the top of stack trace, I can see `Unable to resume activity` – Cheok Yan Cheng Aug 09 '13 at 07:15
  • *As at the top of stack trace, I can see Unable to resume activity* - the activity encountered a problem and the resume lifecycle failed. *But, this shouldn't happen as onResume will make sure data is ready.* - the problem is that the `onActivityResult` will be called for the activity before the actual `onResume` call. *I'm more interested in why resuming parent activity process can trigger fragment's onActivityResult.* - and why would this be a strange behavior, aren't you expecting the fragment to receive that call? – user Aug 09 '13 at 07:40
  • can u post your code here,i m sure will be help you in better way. – cafebabe1991 Aug 13 '13 at 07:55

1 Answers1

1

It possible that fragment's onActivityResult will be triggered during activity resuming by doing this-

Actually i am not getting how u have managed your fragment but i am providing u two solutions... on the basis of above code.

1. In your case it is null pointer exception so u can check null before super.onActivityResult of your fragment activity.

2. Just put ur code "Intent intent = new Intent(this.getActivity(), NewBuyPortfolioFragmentActivity.class); startActivityForResult(intent, RequestCode.REQUEST_NEW_BUY_PORTFOLIO_FRAGMENT_ACTIVITY);" on click of fragment item or any where from where u want to switch on NewBuyPortfolioFragmentActivity and from there just "Intent resultIntent; resultIntent = new Intent(this, ImageFragment.class); setResult(RESULT_OK, resultIntent); finish();"