You need to enable JavaScript to run this app. Google Drive API开发中onActivityResult未回调致空实例
优惠活动
大模型
产品
解决方案
定价
更多

Google Drive API开发中onActivityResult未回调致空实例

核心根因

你遇到的现象不属于“回调不触发”的bug,本质是对Android startActivityForResult的异步执行逻辑认知错误:

  • startActivityForResult 是非阻塞方法,调用后系统会立刻暂停当前页面的执行流程,跳转至Google账号授权界面,代码不会等待用户完成登录操作再继续向下运行。
  • 你在onCreate中将uploadPdfFile()写在requestSignIn()的下一行,相当于登录流程刚发起、还未弹出账号选择界面时,上传逻辑就已经开始执行,此时driveServiceHelper根本没有完成初始化,取值自然为null。
  • onActivityResult 的触发时机并不在startActivityForResult的代码块内,只有当用户在授权页完成账号选择、授权/取消操作,系统关闭登录页、将控制权交回MainActivity时,才会触发该回调。
代码存在的具体问题
  • 执行逻辑顺序错误:将需要等待登录授权完成才能执行的上传操作,放在了登录流程的同步执行流中调用。
  • 缺少空值判断:uploadPdfFile() 方法中直接调用driveServiceHelper的实例方法,未判空时遇到null会直接抛出空指针异常导致程序崩溃。
  • 废弃API兼容风险:startActivityForResult 已在AndroidX中标记废弃,当targetSdk版本为30及以上时,存在回调无法正常触发的兼容问题。
  • 异常处理缺失:登录失败、用户取消授权的回调逻辑为空,出现问题时没有任何用户可见的提示。
可直接落地的修改步骤
  1. 调整onCreate的启动逻辑,删除页面启动时直接调用uploadPdfFile()的代码,增加登录状态前置检查:
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 保留原有Toolbar、悬浮按钮的初始化代码
    
        GoogleSignInAccount lastSignedInAccount = GoogleSignIn.getLastSignedInAccount(this);
        if (lastSignedInAccount != null) {
            // 已有有效登录记录,直接初始化服务后执行上传
            initDriveService(lastSignedInAccount);
            uploadPdfFile();
        } else {
            // 无有效登录时再发起授权流程
            requestSignIn();
        }
    }
    
  2. 将handleSignalInIntent中的DriveServiceHelper初始化逻辑抽成公共方法,方便登录成功后复用:
    private void initDriveService(GoogleSignInAccount googleSignInAccount) {
        GoogleAccountCredential credential = GoogleAccountCredential
                .usingOAuth2(MainActivity.this, Collections.singleton(DriveScopes.DRIVE_FILE));
        credential.setSelectedAccountName(googleSignInAccount.getAccount().name);
        Drive googleDriveService = new Drive.Builder(
                AndroidHttp.newCompatibleTransport(),
                new GsonFactory(),
                credential)
                .setApplicationName("My Drive Tutorial")
                .build();
        driveServiceHelper = new DriveServiceHelper(googleDriveService);
    }
    
  3. 修改onActivityResult的回调逻辑,等初始化完成后再触发上传:
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case 400:
                if (resultCode == RESULT_OK) {
                    GoogleSignIn.getSignedInAccountFromIntent(data)
                        .addOnSuccessListener(googleSignInAccount -> {
                            initDriveService(googleSignInAccount);
                            // 服务初始化完成后再执行上传操作
                            uploadPdfFile();
                        })
                        .addOnFailureListener(e -> Toast.makeText(this, "登录授权失败,请重试", Toast.LENGTH_SHORT).show());
                }
                break;
        }
    }
    
  4. 给uploadPdfFile()增加空值判断,避免崩溃:
    private void uploadPdfFile() {
        if (driveServiceHelper == null) {
            Toast.makeText(this, "请先完成Google账号登录授权", Toast.LENGTH_SHORT).show();
            return;
        }
        // 保留原有上传的进度弹窗、文件上传逻辑
    }
    
补充说明
  • 所有依赖异步流程结果的操作,都必须放到对应的异步回调中触发,不能和异步流程的调用放在同一同步执行流里顺序执行。
  • 适配新版本Android时,建议将废弃的startActivityForResult替换为官方推荐的Activity Result API,从根源上避免版本兼容导致的回调丢失问题。

内容的提问来源于stack exchange,提问作者Thomas Suditu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.30 03:45:06