Android的onActivityResult不被调用的解决方案
16lz
2021-01-26
方案一:
现象: startActivityForResult() 后直接调用 onActivityResult()。
开发人员都知道,可以通过使用 startActivityForResult() 和 onActivityResult() 方法来传递或接收参数。
然而在一次使用中,还没等到被调用的 Activity 返回,onActivityResult() 就被执行了。
找了半于,才得知,这与 Activity 的加载模式(launchMode)有关,该属性可以在 AndroidManifest.xml 中设置。
原先将其设为 launchmode="SingleTask",经测试,所有需要传递或接收的 Activity 不允许设置该属性,或只能设为标准模式,否则系统将在 startActivityForResult() 后直接调用 onActivityResult()。
方案二:
ActivityA的代码:(放在onCreate方法中)
Intent intent = new Intent(ActivityA.this, ActivityB.class); Bundle bundle = new Bundle(); bundle.putString("abc", "aaaaaaaaaaa"); intent.putExtra("bundle", bundle); startActivityForResult(intent, RESULT_OK);
如果startActivityForResult此处写得是 RESULT_OK(值为负数) ,则在finish到ActivityB之后,ActivityA中的 onActivityResult 方法不会执行。 方案三:
在Fragment中onActivityResult不被调用的解决方案(绝对管用)
常见的,我们会在FragmentActivity中嵌套一层Fragment使用,甚至Fragment下层层嵌套使用。这个时候,在第二级或者更深级别的Fragment将无法收到onActivityResult回调,查看FragementActivity的源码发现:
public void startActivityFromFragment(Fragment fragment, Intent intent, int requestCode){if (requestCode == -1){super.startActivityForResult(intent, -1);return;}if ((requestCode&0xffff0000) != 0){throw new IllegalArgumentException("Can only use lower 16 bits for requestCode");}super.startActivityForResult(intent, ((fragment.mIndex+1)<<16) + (requestCode&0xffff));}@Override protected void onActivityResult(int requestCode, int resultCode, Intent data){ mFragments.noteStateNotSaved();int index = requestCode>>16;if (index != 0){ index--;if (mFragments.mActive == null || index < 0 || index >= mFragments.mActive.size()){Log.w(TAG,"Activity result fragment index out of range: 0x"+ Integer.toHexString(requestCode));return;} Fragment frag = mFragments.mActive.get(index);if (frag == null){Log.w(TAG, "Activity result no fragment exists for index: 0x"+ Integer.toHexString(requestCode));}else{frag.onActivityResult(requestCode&0xffff, resultCode, data);}return;}super.onActivityResult(requestCode, resultCode, data);}
原来,程序猿偷懒,没有处理嵌套Fragment的情况,也就是说回调只到第一级Fragment,就没有继续分发。我们可以实现一个自己的FragmentActiviy,来实现继续分发,如下:
public class BaseFragmentActiviy extends FragmentActivity{private static final String TAG = "BaseActivity";@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data){FragmentManager fm = getSupportFragmentManager();int index = requestCode >> 16;if (index != 0){index--;if (fm.getFragments() == null || index < 0 || index >= fm.getFragments().size()){Log.w(TAG,"Activity result fragment index out of range: 0x" + Integer.toHexString(requestCode));return;}Fragment frag = fm.getFragments().get(index);if (frag == null){Log.w(TAG, "Activity result no fragment exists for index: 0x" + Integer.toHexString(requestCode));}else{handleResult(frag, requestCode, resultCode, data);}return;}}/** * 递归调用,对所有子Fragement生效 * * @param frag * @param requestCode * @param resultCode * @param data */private void handleResult(Fragment frag, int requestCode, int resultCode, Intent data){frag.onActivityResult(requestCode & 0xffff, resultCode, data);List frags = frag.getChildFragmentManager().getFragments();if (frags != null){for (Fragment f : frags){if (f != null)handleResult(f, requestCode, resultCode, data);}}}
然后我们继承这个BaseFragmentActivity即可,但是要注意,在Fragment中启动Activity时,一定要调用根Fragment的启动方法,如下:
/** * 得到根Fragment * * @return */private Fragment getRootFragment(){Fragment fragment = getParentFragment();while (fragment.getParentFragment() != null){fragment = fragment.getParentFragment();}return fragment;}/** * 启动Activity */private void onClickTextViewRemindAdvancetime(){Intent intent = new Intent();intent.setClass(getActivity(), YourActivity.class);intent.putExtra("TAG","TEST"); getRootFragment().startActivityForResult(intent, 1001);}
参考:http://blog.csdn.net/shuaihj/article/details/46663109
更多相关文章
- Android(安卓)SystemUI之启动流程(一)
- Qt for android 开机自启动、开机黑屏处理
- eclipse启动时报错org.eclipse.core.runtime.AssertionFailedExc
- android启动页白屏的问题
- Android中对SQLite的操作
- 关于android:launchMode
- Unity3D android findviewbyid返回 null
- android中事件传递机制(2)
- Android中的SurfaceFlinger和Choreographer