MainActivity中有一个fragment,fragment需要上传头像,所以肯定要跳到onActivityResult()方法
关于onActivityResult()写到哪会调到的问题,相信大家都知道,这个案例1中fragment中startActivityForResult调onActivityResult()是不行的
案例2 :当我们从一个Activity启动了一个Fragment,然后在这个Fragment中又去实例化了一些子Fragment,在子Fragment中去有返回的启动了另外一个Activity,即通过startActivityForResult方式去启动,这时候造成的现象会是,子Fragment接收不到OnActivityResult,如果在子Fragment中是以getActivity.startActivityForResult方式启动,那么只有Activity会接收到OnActivityResult,如果是以getParentFragment.startActivityForResult方式启动,那么只有父Fragment能接收(此时Activity也能接收),但无论如何子Fragment接收不到OnActivityResult。
这是一个非常奇怪的现象,按理说,应该是让子Fragment接收到OnActivityResult才对,究竟是什么造成的呢?
在网上搜了一大丢,发现都很讲的不详细,于是自己把解决的过程分享下:
没错最近我在项目中就是遇到了,第2中情况:MainActivity 里面实例化一个 fragment,在有这个fragment去实话子fragment 在有子fragment去调用系统的相册,相机,发现子fragment显示不了图片,于是我选择了走一条复杂的路
看源码:
public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
if (mParent == null) {
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, mEmbeddedID, requestCode, ar.getResultCode(),
ar.getResultData());
}
if (requestCode >= 0) {
// If this start is requesting a result, we can avoid making
// the activity visible until the result is received. Setting
// this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
// activity hidden during this time, to avoid flickering.
// This can only be done when a result is requested because
// that guarantees we will get information back when the
// activity is finished, no matter what happens to it.
mStartedActivity = true;
}
final View decor = mWindow != null ? mWindow.peekDecorView() : null;
if (decor != null) {
decor.cancelPendingInputEvents();
}
// TODO Consider clearing/flushing other event sources and events for child windows.
} else {
if (options != null) {
mParent.startActivityFromChild(this, intent, requestCode, options);
} else {
// Note we want to go through this method for compatibility with
// existing applications that may have overridden it.
mParent.startActivityFromChild(this, intent, requestCode);
}
}
}
看看这个方法:mParent.startActivityFromChild(this, intent, requestCode)
public void startActivityFromChild(Activity child, Intent intent,
int requestCode, Bundle options) {
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, child,
intent, requestCode, options);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, child.mEmbeddedID, requestCode,
ar.getResultCode(), ar.getResultData());
}
}
ar为null,你的请求就被丢弃了,无法回调到你当前实现的 。。 Result(。。。){ }
为什么会这样呢?
我们回到启动的时候,getActivity(). startActivityForResult()
if(mParent == null){
.....
}
else {
if (options != null) {
mParent.startActivityFromChild(this, intent, requestCode, options);
} else {
// Note we want to go through this method for compatibility with
// existing applications that may have overridden it.
mParent.startActivityFromChild(this, intent, requestCode);
}
}
最后我发现源码是花了时间看,可是问题还是纯在:
因为当启动Intent调用系统的action的时候,肯定会回调到 ,此fragment所依赖的
于是,想到了用接口的回调: Activity:<pre name="code" class="java"> private onActivityResultListener resultlistener;
public interface onActivityResultListener{
void onResultlistener(int requestCode, int resultCode, Intent data);
}
public void setOnActivityResultListener(onActivityResultListener resultlistener){
this.resultlistener = resultlistener;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
resultlistener.onResultlistener(requestCode, resultCode, data);
super.onActivityResult(requestCode, resultCode, data);
}
fragment:
<pre name="code" class="java">@Override
public void onResume() {
// TODO Auto-generated method stub
super.onResume();
((MainActivity)getActivity()).setOnActivityResultListener(new onActivityResultListener() {
@Override
public void onResultlistener(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
if (resultCode == FragmentActivity.RESULT_OK) {
uri = data.getData();
ContentResolver cr = getActivity().getContentResolver();
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(cr, uri);
if (bitmap != null) {
Bitmap smallBitmap = ImageTools.zoomBitmap(bitmap, bitmap.getWidth() / SCALE,
bitmap.getHeight() / SCALE);
bitmap.recycle();
if (flag == 1) {
bytePhoto1 = Bitmap2Bytes(smallBitmap);
dan_photo1.setImageBitmap(smallBitmap);
String path = uri.getPath();
Toast.makeText(getActivity(), "路径="+path, 2000).show();
} else if(flag == 2) {
dan_photo2.setImageBitmap(smallBitmap);
String photo_two = uri.toString();
bytePhoto2 =Bitmap2Bytes(smallBitmap);
} else if(flag == 3) {
bytePhoto3 = Bitmap2Bytes(smallBitmap);
dan_photo3.setImageBitmap(smallBitmap);
String photo_three = uri.toString();
} else {
return;
}
//photo.append(uri.toString());
}
} catch (Exception e) {
ToastUtil.show(getActivity(), getResources().getString(R.string.read_photo_failed));
}
}
}
});
}
调用系统相册:
<pre name="code" class="java"> private void commonMethod() {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(intent, 1);
}