Facebook sdk 3.8.0。重新登录后的android.newMeRequest返回null的用户; java.net.SocketException:Socket已关闭

时间:2014-08-06 15:27:39

标签: java android facebook facebook-android-sdk

我正在开发一个Android应用程序,它已经使用Facebook sdk 5个月了。在我登录已成功登录的新设备之前,一切都工作正常。之后我成功登录,但当我尝试使用Request.newMeRequest获取用户信息时,我得到了null。所以我调试了问题,这就是我发现的:

  1. 使用访问令牌
  2. 成功创建了会话
  3. 当试图在facebook sdk的某处调用newMeRequest时,引发了异常。例外是“java.net.SocketException:Socket is closed”
  4. 我不明白套接字是如何关闭的。我在互联网上搜索了很多,以下是我试图删除错误的一些建议和事项:

    1. 我重新安装了应用并清除了所有缓存的数据
    2. 我重新安装了Facebook应用
    3. 我重新启动了设备
    4. 我从我的Facebook应用列表中删除了该应用程序(这会撤消该应用对我的数据的访问权限)
    5. 他们似乎都没有产生结果,所以我放弃了。我回到家时,我没有尝试过这个过程4个小时。在那里我重新安装了Facebook应用程序,之后我成功登录并再次检索用户的数据。 我没有修改任何代码。

      但问题并没有止步于此。在几次登录和注销后,问题再次出现,在过去的3个小时里,我已经能够使其正常工作。

      此时我真的不知道为什么会发生这种情况,也不知道如何解决这个问题。有没有人有任何想法可能导致这种行为?

      我正在使用Facebook sdk for Android v 3.8.0。我也在多个设备上测试应用程序(我不确定这是否相关),到目前为止这个问题只出现在带有Jelly Bean的Nexus 7上,在带有Kit Kat的Nexus 4上,到目前为止这个问题从未发生过。

      编辑:

      代码库非常大,所以我将从一些可能有用的部分开始,并根据请求添加更多内容:
      这会处理会话

      private Session.StatusCallback callback = new Session.StatusCallback() {
          @Override
          public void call(Session session, SessionState state,
                  Exception exception) {
              onSessionStateChange(session, state, exception);
          }
      };
      
      private void onSessionStateChange(Session session, SessionState state,
              Exception exception) {
          if(Utils.DEBUG) Log.d(TAG, "sessionStateChange fired");
      
          FragmentManager fm = getSupportFragmentManager();
          Fragment currentFragment = null;
      
          switch (session.getState()) {
              case CLOSED:
                  if(Utils.DEBUG) Log.d(this.getClass().getSimpleName(), "SESSION CLOSED");
                  handleLoginButtonOnClosedSession(fm, currentFragment);
      
                  break;
              case CLOSED_LOGIN_FAILED:
                  if(Utils.DEBUG) Log.d(this.getClass().getSimpleName(), "SESSION CLOSED LOGIN FAILED");
                  handleLoginButtonOnClosedSession(fm, currentFragment);
                  break;
              case CREATED:
                  if(Utils.DEBUG) Log.d(this.getClass().getSimpleName(), "SESSION CREATED");
                  break;
              case CREATED_TOKEN_LOADED:
                  if(Utils.DEBUG) Log.d(this.getClass().getSimpleName(), "SESSION CREATED TOKEN LOADED");
      
                  UserWrapper.getCurrentUser(mContext).maintainFacebookToken(mContext);
      
                  break;
              case OPENED:
                  if(Utils.DEBUG) Log.d(this.getClass().getSimpleName(), "SESSION OPENED");
      
                  break;
              case OPENED_TOKEN_UPDATED:
                  if(Utils.DEBUG) Log.d(this.getClass().getSimpleName(), "SESSION OPENED TOKEN UPDATED");
      
                  UserWrapper.getCurrentUser(mContext).maintainFacebookToken(mContext);
      
                  break;
              case OPENING:
                  if(Utils.DEBUG) Log.d(this.getClass().getSimpleName(), "SESSION OPENING");
                  fm = getSupportFragmentManager();
                  currentFragment = fm.findFragmentById(R.id.fragment_container);
      
                  if(currentFragment instanceof SplashFragment) {
                      SplashFragment splashFragment = (SplashFragment) currentFragment;
                      splashFragment.hideLoginButtonForLogin();
                  }
                  break;
          }
      
          // Only make changes if the activity is visible
          if (mIsResumed) {
              if (state.isOpened()) {
                  // we don't want to clear the back stack if the 
                  // home fragment is already showing
                  FragmentManager manager = getSupportFragmentManager();
                  Fragment previousFragment = manager.findFragmentById(R.id.fragment_container);
                  if(previousFragment == null || !(previousFragment instanceof HomeFragment)) {
                      clearFramgnets();
                  }
                  UserWrapper.getCurrentUser(mContext).maintainFacebookToken(mContext);
                  // If the session state is open:
                  // Show the authenticated fragment
                  showFragment(HOME, false);
              } else if (state.isClosed()) {
                  if(Utils.DEBUG) Log.d(TAG, "showing splash");
                  clearFramgnets();
                  // If the session state is closed:
                  // Show the login fragment
                  showFragment(SPLASH, false);
              }
          }
      }
      @Override
      public void onActivityResult(int requestCode, int resultCode, Intent data) {
          super.onActivityResult(requestCode, resultCode, data);
          uiHelper.onActivityResult(requestCode, resultCode, data);
          if(Utils.DEBUG) Log.d(TAG, "Main Activity - onActivityResult called: requestCode="
                  + requestCode + " resultCode:" + resultCode);
      }
      

      在这里,我尝试从Facebook获取用户

      public void logOnApp(final LoginManager loginManager,
              final AppUserLoadedCallback callback) {
          if (mUserId == null || mUserId.getIdFromProvider() == null || getAuthToken() == null) {
              // make request to the /me API
              Request.newMeRequest(Session.getActiveSession(),
                      new Request.GraphUserCallback() {
                          // callback after Graph API response with sUser object
                          public void onCompleted(GraphUser user,
                                  Response response) {
                              if (user != null) {
                                  mUserId = new Id(Provider.FACEBOOK, user
                                          .getId());
      
                                  loginManager.increaseSuccesfulRetrievalsCount();
      
                                  fetchUserAuthData(loginManager, callback);
                              } else {
                                  // The login has been unsuccessful, if we have reached
                                  // the maximum login retries -> logout, else attempt again.
                                  if (loginManager.maxRetriesCountReached()) {
                                      loginManager.mLogoutRunnable.run();
                                  } else {
                                      loginManager.increaseRetriesCount();
                                      logOnApp(loginManager, callback);
                                  }
                              }
                          }
                      }).executeAsync();
          } else {
              fetchUserAuthData(loginManager, callback);
          }
      }
      

      关于为什么会发生这种情况的任何新想法都会非常有用!

0 个答案:

没有答案