簡體   English   中英

如何在 Jetpack Compose 中使用 acquireToken?

[英]How to use acquireToken with Jetpack Compose?

我如何在 Jetpack Compose 中使用acquireToken - 這需要傳入一個Fragment ,而我沒有Fragment

val parameters = AcquireTokenParameters.Builder()
    .withScopes(scopes.toList())
    .withCallback(authenticationCallback)
    .withFragment(<what can I pass in here?>) // <--------- relevant line
    .build()

_msalPublicClient.acquireToken(parameters)

我使用的是 Android 的最新 MSAL,版本 4.1.0

您可能需要使用 acquireToken 方法,將 Fragment 作為 withFragment 參數傳入。 獲取令牌時,MSAL 在片段的上下文中顯示授權 UI。

您的應用中可能沒有 Fragment,但您可以使用 AndroidX Fragment 庫提供的 FragmentActivity 作為授權 UI 的宿主。

創建一個 FragmentActivity 並將其傳遞給 AcquireTokenParameters 構建器的 withFragment 參數,如下所示 -

class MyFragmentActivity : FragmentActivity()

val parameters = AcquireTokenParameters.Builder()
.withScopes(scopes.toList())
.withCallback(authenticationCallback)
.withFragment(MyFragmentActivity())
.build()

_msalPublicClient.acquireToken(parameters)

免責聲明:此答案可能有效/無效,具體取決於您應用程序的架構。

首先,很奇怪為什么微軟需要 Fragment 並且不確定它背后的用例是什么。 似乎這里提出了問題。必須等待相關更新。

讓我們假設現在 Fragment 是強制性的。 實際上我們可以在 compose app 中使用 Fragment。 因為使用 xml 的遺留應用程序必須支持從片段架構逐步遷移到組合 ui。順便說一下,Android 提供了將可組合組件集成到遺留活動/片段架構的靈活性。

2 例。

  1. 如果你有單一的活動應用程序架構,所有其他都是組合 UI。 您可能需要做更多的工作來調整 compose 應用程序中的片段。

  2. 如果您使用 msal 的登錄/注冊屏幕是單獨的活動,並且對於核心功能您有其他活動,則您可以僅將片段集成到使用 msal 的活動。

讓我們開始實施吧。

  1. 首先,你需要片段依賴。

     implementation 'androidx.fragment:fragment:1.5.5'
  2. 假設你有活動。

     class MainActivity: FragmentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) } }

此處您的活動應擴展 FragmentActivity 或任何擴展 FragmentActivity 的活動類。 ComponentActivity 可能不起作用。 您需要將 xml 文件用於活動並使用 setcontent 視圖。 如果不存在,您可能需要創建布局資源文件夾和布局文件。

  1. 您的活動 xml。

     <androidx.fragment.app.FragmentContainerView android:id="@+id/fragment" android:layout_width="match_parent" android:name="com.example.myapplication.MyFragment" android:layout_height="match_parent"/>

這里有 FragmentContainerView 並引用我們將要創建的片段 class。 無需充氣。

  1. 我的片段 class。

     class MyFragment: Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { return ComposeView(requireContext()).apply { setContent { MyApplicationTheme { // A surface container using the 'background' color from the theme Surface( modifier = Modifier.fillMaxSize(), color = MaterialTheme.colors.background ) { CompositionLocalProvider(MyFragmentProvider provides this@MyFragment) { SigninScreen("My App Name") } } } } } } }

這里 Fragment 不需要 xml 文件。 Fragment 現在將成為您所有撰寫內容的根。 在這里,我們使用 CompositionLocalProvider 來保存片段實例,稍后它可以在多個可組合項中使用。 您還可以使用 LocalCurrent.context 和類型轉換來分段。 但是你可能每次都需要這樣做。 更好的方法是使用 CompositionLocalProvider。

  1. 您可以在片段 class 之外添加staticCompositionLocalOf

     val MyFragmentProvider = staticCompositionLocalOf<MyFragment> { error("No Fragment Instance Provided") }

因此,您可以在同一活動和片段布局樹中的任何可組合項中訪問片段實例。

  1. 這是可組合的 function 用戶界面。 我在這里獲取片段實例並傳遞給 MSAL。
    @Composable
    fun SigninScreen(name: String) {
        //Here I am getting instance of the fragment.
        val myFragment =  MyFragmentProvider.current
        Text(text = "Signin $name!")
        Button(onClick = {
            val parameters = AcquireTokenParameters.Builder()
                .withScopes(scopes.toList())
                .withCallback(authenticationCallback)
                .withFragment(myFragment) 
            .build()
            _msalPublicClient.acquireToken(parameters)
    
        }) {
            Text(text = "Signin")
        }
    }

最重要的是您的可組合項的直接父項應該是片段而不是活動。 它的實例將通過CompositionLocalProvider提供給所有子可組合項。 並且這種遷移完全基於項目的現有架構和規模。

暫無
暫無

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

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