簡體   English   中英

Android MVVM - 如何在 ViewModel 中引用 Activity

[英]Android MVVM - How to reference Activity in ViewModel

MVVM架構,

這是我的觀點(活動):

private MyApp app;
private MainActivityVM viewModel;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
app = (MyApp) this.getApplication();
ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);

MainActivityVM.Factory factory = new MainActivityVM.Factory(app);

final MainActivityVM model = ViewModelProviders.of(this, factory)
.get(MainActivityVM.class);

viewModel = model;
binding.setVm(viewModel);
viewModel.onCreate();

和查看模型:

public class MainActivityVM extends AndroidViewModel implements ViewModel {

    public MainActivityVM(@NonNull Application application) {
        super(application);
    }

    @Override public void onCreate() {
         model = new MyService();
         model.getData(); /* <-- how do i pass the activity here? */
    }

    @Override public void onPause() { }

    @Override public void onResume() { }

    @Override public void onDestroy() { }

    public static class Factory extends ViewModelProvider.NewInstanceFactory {

        @NonNull
        private final Application mApplication;

        public Factory(@NonNull Application application) {
            mApplication = application;
        }

        @Override
        public <T extends android.arch.lifecycle.ViewModel> T create(Class<T> modelClass) {
            return (T) new MainActivityVM(mApplication);
        }
    }
}

和型號:

public class myService{

    public getData(){
        if(permissionacquired(){
            getdata()
        }else{
            requestPermission();
        }
    }

    private void requestPermission() {
        PermissionKey permKey = new PermissionKey(HealthConstants.StepCount.HEALTH_DATA_TYPE, PermissionType.READ);
        HealthPermissionManager pmsManager = new HealthPermissionManager(mStore);
        try {
            // Show user permission UI for allowing user to change options

            /* BELOW CODE REQUIRE Activity reference to PASS */

            pmsManager.requestPermissions(Collections.singleton(permKey), MainActivity.this).setResultListener(result -> {

            /* ABOVE CODE REQUIRE Activity reference to PASS */

            Log.d(APP_TAG, "Permission callback is received.");
            Map<PermissionKey, Boolean> resultMap = result.getResultMap();

                if (resultMap.containsValue(Boolean.FALSE)) {
                    updateStepCountView("");
                    showPermissionAlarmDialog();
                } else {
                    // Get the current step count and display it
                    mReporter.start(mStepCountObserver);
                }
            });
        } catch (Exception e) { Log.e(APP_TAG, "Permission setting fails.", e); }
    }

}

編輯:如果您在我的模型中看到我的請求權限,則 API 需要傳遞活動 - 我如何將活動引用傳遞給請求權限?

我有一個來自模型的獲取權限方法。 這個從我的服務提供商那里獲得許可的方法需要活動,例如requestPermission(Activity)

所以在我的 ModelView 中,我有一個模型對象,它是來自另一個來源的 dataService。

然后,我如何在我的 ViewModel 中引用 Activity 以便我可以調用: model.requestPermission(Activity); 在我的視圖模型中?

這里理解:

注意:ViewModel 絕不能引用視圖、生命周期或任何可能持有對活動上下文的引用的類。

只要您在 onCreate() 方法中需要權限,您就可以將帶有權限請求的邏輯移動到活動中,並將請求結果傳遞到視圖模型中。

就我而言,我還將Activity添加到ViewModel以獲取權限和字符串,但這不是一個好主意。 當我在一個Fragment 禁用位置權限時,應用程序崩潰,因為它重新啟動,然后使用片段堆棧恢復FragmentManager ,然后啟動MainActivity 因此ViewModel過早地(在構造函數中)獲得了位置狀態並引發了異常。 但是當我將獲取位置狀態移動到一個函數時,應用程序會正常重新啟動。

因此,使用 Dagger,您可以編寫如下內容:

AppModule:
    @JvmStatic
    @Provides
    fun provideActivity(app: MainApplication): AppCompatActivity = app.mainActivity

MainApplication持有mainActivity並在MainActivity設置onCreate

application.mainActivity = this

onDestroy

application.mainActivity = null

在任何ViewModel添加:

class SomeViewModel @Inject constructor(
    private val activity: Provider<AppCompatActivity>
)

然后使用它: activity.get().getString(R.string.some_string)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM