Android原生应用Google一键登录触发空指针异常求助
Google一键登录(One Tap)空指针异常修复方案
问题描述
集成Google一键登录功能时,点击登录按钮执行activityResultLauncher.launch(intentSenderRequest)代码,触发如下空指针异常:
java.lang.NullPointerException: Attempt to invoke virtual method 'android.app.ActivityThread$ApplicationThread android.app.ActivityThread.getApplicationThread()' on a null object reference
问题根源
- ActivityResultLauncher注册时机错误:在
login方法内临时注册Launcher,而非在Activity生命周期早期(如onCreate)完成注册,导致异步回调时Launcher与Activity生命周期绑定失效。 - 局部变量生命周期问题:Launcher作为
login方法的局部变量,异步回调触发时可能已被GC回收,引发上下文空指针。 - 上下文强转风险:将传入的
context强转为Activity,存在上下文类型不匹配的隐患。
修复代码示例
public class Googlelogin extends AppCompatActivity implements SocialLoginswwwwwwwwwwwwwwwwwwwwwwwwww, GoogleApiClient.OnConnectionFailedListener { private SignInClient oneTapClient; private BeginSignInRequest signInRequest; private ActivityResultLauncher<IntentSenderRequest> activityResultLauncher; private static final String TAG = "GoogleLogin"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 必须在Activity生命周期早期注册ActivityResultLauncher activityResultLauncher = registerForActivityResult( new ActivityResultContracts.StartIntentSenderForResult(), result -> { try { SignInCredential credential = oneTapClient.getSignInCredentialFromIntent(result.getData()); String idToken = credential.getGoogleIdToken(); if (idToken != null) { String email = credential.getId(); String username = credential.getDisplayName(); Toast.makeText(Googlelogin.this, "Email : " + email + " Name : " + username, Toast.LENGTH_SHORT).show(); } } catch (ApiException e) { e.printStackTrace(); } }); } @RequiresApi(api = Build.VERSION_CODES.DONUT) @Override public void login(Context context) { // 使用当前Activity自身上下文,避免强转风险 oneTapClient = Identity.getSignInClient(this); signInRequest = BeginSignInRequest.builder() .setPasswordRequestOptions(BeginSignInRequest.PasswordRequestOptions.builder() .setSupported(true) .build()) .setGoogleIdTokenRequestOptions(BeginSignInRequest.GoogleIdTokenRequestOptions.builder() .setSupported(true) .setServerClientId("885176601647-qnk12j18ln08dhhhal4lgprmlrreor1q.apps.googleusercontent.com") .setFilterByAuthorizedAccounts(true) .build()) .setAutoSelectEnabled(true) .build(); oneTapClient.beginSignIn(signInRequest) .addOnSuccessListener(this, result -> { IntentSenderRequest intentSenderRequest = new IntentSenderRequest.Builder(result.getPendingIntent().getIntentSender()).build(); activityResultLauncher.launch(intentSenderRequest); }) .addOnFailureListener(this, e -> { Log.d(TAG, e.getLocalizedMessage()); Toast.makeText(this, e.getLocalizedMessage(), Toast.LENGTH_SHORT).show(); }); } }
关键修复点
- 提前注册Launcher:在
onCreate方法中完成ActivityResultLauncher的注册,确保其与Activity生命周期绑定,避免回调时上下文失效。 - 改用类成员变量:将Launcher、
oneTapClient、signInRequest设为类成员变量,保证异步回调时变量仍处于有效生命周期内。 - 直接使用Activity上下文:当前类继承自
AppCompatActivity,直接用this替代传入的context,消除强转带来的风险。
内容的提问来源于stack exchange,提问作者sejn
相关产品推荐
相关产品推荐

