4 回答

TA貢獻(xiàn)1817條經(jīng)驗(yàn) 獲得超14個(gè)贊
我認(rèn)為您可以執(zhí)行以下操作,它不持有全局引用,context因此不會(huì)泄漏
public void loginGoogle(Context context){
if(isSigningIn)
return
context.startActivityForResult(getGoogleSignInIntent(), GOOGLE_SIGN_IN)
isSigningIn = true;
}

TA貢獻(xiàn)1982條經(jīng)驗(yàn) 獲得超2個(gè)贊
替換 startActivityForResult 的文檔和函數(shù)似乎不鼓勵(lì)這樣做:
注冊(cè)請(qǐng)求以啟動(dòng)由給定合同指定的結(jié)果活動(dòng)。這會(huì)在與此調(diào)用者關(guān)聯(lián)的注冊(cè)表中創(chuàng)建一個(gè)記錄,管理請(qǐng)求代碼,以及在后臺(tái)與 Intent 的轉(zhuǎn)換。這必須無條件調(diào)用,作為初始化路徑的一部分,通常作為 Activity 或 Fragment 的字段初始化程序。如果此片段的宿主是 ActivityResultRegistryOwner,則將使用宿主的 ActivityResultRegistry。否則,這將使用片段的活動(dòng)注冊(cè)表。
注意“This must be called unconditionally, as part of initialization path”。
另請(qǐng)注意此 IlliegalStateException 消息:
片段 [this] 在創(chuàng)建后嘗試注冊(cè) ForActivityResult。片段必須在創(chuàng)建之前調(diào)用“registerForActivityResult()”(即初始化、“onAttach() 或 onCreate())”。
所以我的建議是將契約和registerForActivityResult()
你的 Activity 或 FragmentonCreate
放在你的視圖模型/域類中的函數(shù)中,無論你將對(duì)結(jié)果做什么,這基本上就是你已經(jīng)在做的事情。

TA貢獻(xiàn)1804條經(jīng)驗(yàn) 獲得超3個(gè)贊
您可以使用 SingleLiveData 打開新屏幕。
您創(chuàng)建具有所有必要參數(shù)的類來啟動(dòng)活動(dòng)
在 ViewModel 中,您使用需要的參數(shù)創(chuàng)建此類
您在 ViewModel 中創(chuàng)建單個(gè)實(shí)時(shí)數(shù)據(jù)字段并從活動(dòng)/片段中觀察它
你用 SingleLiveData 發(fā)送這個(gè)類
創(chuàng)建類:
public Enum Screen {
? ?LOGIN
}
在視圖模型中:
...
private SingleLiveData<Screen> onOpenScreen = new SingleLiveData<Screen>()
public SingleLiveData<Screen> observeScreenOpen() {
? ? return onOpenScreen
}
public void loginGoogle(){
? ? onOpenScreen.value = Screen.LOGIN
}
...
在活動(dòng)/片段中
viewModel.observeScreenOpen(this, new Observer<Screen> {screen->
? ? if(screen == Screen.LOGIN) {
? ? ? ? //start your activity here
? ? }
})

TA貢獻(xiàn)1850條經(jīng)驗(yàn) 獲得超11個(gè)贊
我要做的是在被調(diào)用的 ViewModel 中注冊(cè)一個(gè)回調(diào),Activity 可以對(duì)其做出反應(yīng)。然后 ViewModel 可以擁有大部分業(yè)務(wù)邏輯,但不必引用 Activity 或 Context,Activity 可以處理啟動(dòng) Intent 的 Activity 特定內(nèi)容。
例子:
回調(diào)接口:
interface OnSignInStartedListener {
void onSignInStarted(GoogleSignInClient client);
}
視圖模型:
public class ViewModel {
private final OnSignInStartedListener mListener;
public ViewModel(OnSignInStartedListener listener) {
mListener = listener;
}
public void viewModelOnCreate() {
// This is what i want: Google object defined in View Model
// but I dont know how to call startActivityForResult from here?
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN).requestEmail().build();
mGoogleSignInClient = GoogleSignIn.getClient(getApplication(), gso);
}
public void loginGoogle() {
// Invoke callback here to notify Activity
mListener.onSignInStarted(mGoogleSignInClient);
}
}
活動(dòng):
protected void onCreate(Bundle savedInstanceState) {
...
mViewModel = new ViewModel(new OnSignInStartedListener() {
@Override
public void onSignInStarted(GoogleSignInClient client) {
startActivityForResult(client.getSignInIntent(), RC_SIGN_IN);
}
});
...
}
@Override
public void onClick(View v) {
// Invokes listener this activity created to start sign in flow
viewModel.loginGoogle();
}
希望有幫助!
添加回答
舉報(bào)