Android 碎片';方向更改后未调用s onActivityResult
请注意,此问题不是以下问题的重复:Android 碎片';方向更改后未调用s onActivityResult,android,android-fragments,orientation-changes,Android,Android Fragments,Orientation Changes,请注意,此问题不是以下问题的重复: 另外,之前也有人问过另一个问题,但这并没有提到方向的改变(而且还没有解决) 如果不切换方向,则会调用片段中的onActivityResult方法。但是,如果我遵循这些步骤,它不会被调用: 在FragmentActivity中加载片段 从片段:startActivityForResult(新意图(MediaStore.ACTION\u IMAGE\u CAPTURE)、Constants.REQ\u code\u IMAGE\u CAPTURE) 等待相
片段中的onActivityResult
方法。但是,如果我遵循这些步骤,它不会被调用:
在FragmentActivity中加载片段
从片段:startActivityForResult(新意图(MediaStore.ACTION\u IMAGE\u CAPTURE)、Constants.REQ\u code\u IMAGE\u CAPTURE)代码>
等待相机加载
切换方向
拍摄照片并单击复选标记
onActivityResult
仍然在父FragmentActivity中被调用。然而,由于这一警告,我得到:
W/FragmentActivity(4418): Activity result no fragment exists for index: 0x22d73
…我的猜测是,父对象由于方向更改而被销毁,并且在重新创建后,无法找到最初称为startActivityForResult
的Fragment
这是一个框架错误吗?这是如何解决的
编辑:由于流行需求,添加了更多代码
FragmentActivity.java:
...
fragment = new ExampleFragment();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace (R.id.mainContentView, fragment);
if (clearBackStack) {
// clear the back stack
while (getSupportFragmentManager().popBackStackImmediate ());
// add the current transaction to the back stack
transaction.addToBackStack (null);
}
else {
transaction.addToBackStack(null);
}
transaction.commit();
...
@Override
public void onActivityResult(int reqCode, int resultCode, Intent data) {
super.onActivityResult(reqCode, resultCode, data);
}
Intent takePicture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(takePicture, Constants.REQ_CODE_IMAGE_CAPTURE);
...
@Override
public void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) {
super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
switch (requestCode) {
case Constants.REQ_CODE_IMAGE_CAPTURE:
// handle added image
}
}
ExampleFragment.java:
...
fragment = new ExampleFragment();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace (R.id.mainContentView, fragment);
if (clearBackStack) {
// clear the back stack
while (getSupportFragmentManager().popBackStackImmediate ());
// add the current transaction to the back stack
transaction.addToBackStack (null);
}
else {
transaction.addToBackStack(null);
}
transaction.commit();
...
@Override
public void onActivityResult(int reqCode, int resultCode, Intent data) {
super.onActivityResult(reqCode, resultCode, data);
}
Intent takePicture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(takePicture, Constants.REQ_CODE_IMAGE_CAPTURE);
...
@Override
public void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) {
super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
switch (requestCode) {
case Constants.REQ_CODE_IMAGE_CAPTURE:
// handle added image
}
}
我有一个解决办法
它目前正在我的项目中工作。
遵循步骤
-->在ActivityResultListener上创建接口名称(或根据需要命名)
ActivityResultListener上的公共接口{
public boolean onActivityResultTest(int request_code, int response_code,
Intent data);
}
-->在你的零碎活动中引用interace,如
public OnActivityResultListener activityResultListener;
-->现在在FragmentActivity中重写OnActivityResult。如下图所示
@Override
public void onActivityResult(int arg0, int arg1, Intent arg2) {
AppLog.Log(TAG, "onActivityResult");
try {
if (activityResultListener != null) {
activityResultListener.onActivityResultTest(arg0,arg1,arg2);
}
} catch (Exception e) {
e.printStackTrace();
}
super.onActivityResult(arg0, arg1, arg2);
}
-->现在在片段中实现接口并重写所需的方法
@Override
public boolean onActivityResultTest(int requestCode, int resultCode,
Intent data) {
AppLog.Log(TAG, "onActivityResultTest");
if (requestCode == CAMERA_REQUEST && resultCode == Activity.RESULT_OK) {
isHavePhoto = true;
bitmap = (Bitmap) data.getExtras().get("data");
userEditPhoto.setImageBitmap(bitmap);
}
}
-->最后一步是在Fragment类的OnAttach方法中,为活动结果在活动中注册您的片段。像
@Override
public void onAttach(Activity activity) {
this.activity = (YOUR_FRAGMENT_ACTIVITY) activity;
this.activity.activityResultListener = this;
super.onAttach(activity);
}
-->现在进行测试,不要忘记将其移除
@Override
public void onDestroyView() {
activity.activityResultListener = null;
super.onDestroyView();
}
->这是一个非常漫长的过程,但它在任何方向都能100%工作。通过将所有onActivityResult
逻辑从片段
移动到活动
解决了这一问题
请注意,但是,传递到片段
的reqCode
与传递到父活动
的reqCode
不同(我认为系统设置了活动
)。这意味着我还必须将原始的startActivityForResult
调用从片段
移动到活动
,然后在需要时创建一个方法从片段
调用它
如果有人找到一种更优雅的方式,我很乐意听到。支持库中有一个问题。查看此帖子:@shomeser,您的帖子是在搜索某个内容时出现的,但我没有嵌套的片段,因此我认为这与此无关。您的片段索引太大:0x22d73,看起来发生了一些奇怪的事情。这个问题是否可以稳定地重现?你能展示你的代码吗?@shomeser,我的代码没有什么特别之处,但请看编辑。如果您按照提供的步骤进行操作,则问题始终是可重现的。您是否尝试在beginTransaction()之前移动对PopBackbackImmediate()的调用?在支持库的Android 4.4、Nexus 5、版本19.0.1上不起作用。在调用活动的onActivityResult
后,该片段被附加,因此在调用该片段时,侦听器为空。抱歉,它正在使用4.4,我在Nexus 4和5中测试过,它也在使用。你需要告诉我,我认为你对Nanatach方法有问题。再次检查all步骤。嗯,那可能是。但是,在我目前的情况下,它不适合我。工作正常,只需从活动(activity?.startActivityForResult
)调用startActivityForResult
)请参见方法FragmentActivity.startActivityFromFragment(),它修改原始请求代码以存储片段的索引:这就是为什么得到不同的值。很遗憾,但目前我无法重现此问题。该修复对我有效。这个问题只发生在一些设备上(Galaxy S5很好,但我在Sony XPeria上有错误)。在我的情况下,onActivityResult已经出现在我的Activity类上了。但我仍然注意到同样的行为。