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();
}
希望有帮助!
添加回答
举报