4 回答

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

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

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

TA貢獻1850條經驗 獲得超11個贊
我要做的是在被調用的 ViewModel 中注冊一個回調,Activity 可以對其做出反應。然后 ViewModel 可以擁有大部分業務邏輯,但不必引用 Activity 或 Context,Activity 可以處理啟動 Intent 的 Activity 特定內容。
例子:
回調接口:
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);
}
}
活動:
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();
}
希望有幫助!
添加回答
舉報