Xamarin Android中MvxFragment未调用OnActivityResult问题求助
遇到这种情况很常见,我帮你梳理几个关键的排查点和解决方案:
1. 确保宿主Activity正确转发结果到Fragment
MvvmCross的MvxFragment依赖宿主Activity把OnActivityResult的结果传递过来,但有时候默认的转发逻辑可能没生效。你可以在绑定MainViewModel的MainActivity中手动重写OnActivityResult,主动把结果转发给当前显示的Fragment:
public override void OnActivityResult(int requestCode, int resultCode, Intent data) { base.OnActivityResult(requestCode, resultCode, data); // 获取当前显示在content_frame中的Fragment var currentFragment = SupportFragmentManager.FindFragmentById(Resource.Id.content_frame); currentFragment?.OnActivityResult(requestCode, resultCode, data); }
这样就能确保Facebook登录返回的结果能传递到你的FacebookLoginViewFragment中,触发它的OnActivityResult方法。
2. 检查MvxFragmentPresentation的配置
你的MvxFragmentPresentation属性设置了addToBackStack=false,虽然这通常不会直接影响OnActivityResult,但可以确认一下Fragment的导航方式是否正确——如果是通过MvvmCross的IMvxNavigationService跳转到这个Fragment的,确保导航流程没有异常。
3. 修复主线程阻塞的异步调用问题
顺便提一下,你在OnCreateView中直接调用(ViewModel).FinishLogin(...).GetAwaiter().GetResult()会阻塞主线程,可能导致UI卡顿甚至死锁。建议改成异步方式:
// 将OnCreateView改为async方法 public override async View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { var view = base.OnCreateView(inflater, container, savedInstanceState); ParentActivity.SupportActionBar.Title = "Login"; var accessToken = AccessToken.CurrentAccessToken; if (accessToken != null) { await ViewModel.FinishLogin(accessToken.Token, long.Parse(accessToken.UserId)); } else { _loginButton = view.FindViewById<LoginButton>(Resource.Id.loginButton1); _loginButton.SetReadPermissions(new string[] { "user_friends", "email", "pages_show_list" }); _callbackManager = CallbackManagerFactory.Create(); _loginButton.RegisterCallback(_callbackManager, this); } return view; }
4. 尝试手动控制Facebook登录的结果回调
如果上面的方法都不行,可以绕过LoginButton的自动登录逻辑,手动启动Facebook登录Activity,用MvvmCross的IMvxStartActivityForResult来精准控制结果回调:
首先在ViewModel中注入服务:
private readonly IMvxStartActivityForResult _startActivityForResult; public FacebookLoginViewModel(IMvxStartActivityForResult startActivityForResult) { _startActivityForResult = startActivityForResult; }
然后在Fragment中手动触发登录并处理结果:
private async void StartFacebookLogin() { var loginManager = LoginManager.Instance; loginManager.SetReadPermissions(new string[] { "user_friends", "email", "pages_show_list" }); var result = await _startActivityForResult.StartActivityForResultAsync(loginManager.CreateLoginIntent(Activity)); if (result.ResultCode == Result.Ok && result.Data != null) { _callbackManager.OnActivityResult(result.RequestCode, (int)result.ResultCode, result.Data); } }
这样可以确保结果能正确回调到Fragment中,再传递给Facebook的CallbackManager。
内容的提问来源于stack exchange,提问作者nick_green

