오늘도 더 나은 코드를 작성하였습니까?

Deep link for Destination 본문

Android Jetpack Architecture/Navigation

Deep link for Destination

hik14 2021. 11. 29. 16:46

 

Android에서 deep link는 앱 내의 특정 destination 으로 직접 연결하는 링크입니다

 

navi component 를 사용하면 explicit(명시적) 및 implicit(암시적) 이라는 두 가지 유형의 딥 링크를 만들 수 있습니다.

 

 explicit(명시적) deep link 만들기.

explicit deep link 는 PendingIntent를 사용하여 사용자를 앱 내의 특정 위치로 안내하는 딥 링크의 single instance입니다

notification 또는 앱 widget 의 일부로 explicit deep link 표시할 수 있습니다

 

사용자가 explicit deep link를 통해 앱을 열면 작업 백 스택이 지워지고 deep link destination으로 대체됩니다.

nested graph를 이용할 때, 각 nested level의 start destination, 즉 계층 구조의 각 <navigation> 요소의 start destination도 스택에 추가됩니다.

즉, 사용자가 딥 링크 destinatiuon 에서 back button 을 누르면 진입점에서 앱에 들어간 것처럼 탐색 스택을 탐색합니다.

NavDeepLinkBuilder 클래스를 이용하여 PendingIntent를 구성.

제공된 context가 activity가 아닌 경우 constructor는 가능한 경우 시작할 basic Activity로PackageManager.getLaunchIntentForPackage()(앱 런치로 지정된 activity)를 사용합니다.

 

val pendingIntent = NavDeepLinkBuilder(context)
    .setGraph(R.navigation.nav_graph)
    .setDestination(R.id.android)
    .setArguments(args)
    .createPendingIntent()

 

기본적으로 NavDeepLinkBuilder는 앱의 매니페스트에 선언된 basic launch Activity에 대한 명시적 딥 링크를 시작합니다.

NavHost가 다른 Activity에 있는 경우 딥 링크 빌더를 생성할 때 구성 요소 이름을 지정해야 합니다.

val pendingIntent = NavDeepLinkBuilder(context)
    .setGraph(R.navigation.nav_graph)
    .setDestination(R.id.android)
    .setArguments(args)
    .setComponentName(DestinationActivity::class.java)
    .createPendingIntent()

기존 NavController가 있는 경우 NavController.createDeepLink()를 사용하여 딥 링크를 생성할 수도 있다.

 

implicit(암시적) deep link 만들기.

implicit deep link 는 앱의 특정 대상을 나타냅니다. 딥 링크가 호출되면(예: 사용자가 링크를 클릭할 때) Android는 해당 대상으로 앱을 열 수 있습니다.

 

딥 링크는 URI, INTENT ACTION 및 MIME TYPE로 일치될 수 있습니다.

딥 링크에 대해 여러 일치 유형을 지정할 수 있지만, URI 인수 일치가 먼저 우선 순위가 지정되고 그 다음이 INTENT ACTION, 그 다음이 MIME TYPE입니다.

 

<fragment android:id="@+id/a"
          android:name="com.example.myapplication.FragmentA"
          tools:layout="@layout/a">
        <deeplink app:uri="www.example.com"
                app:action="android.intent.action.MY_ACTION"
                app:mimeType="type/subtype"/>
</fragment>

 

 

1. 탐색 편집기의 디자인 탭에서 딥 링크의 대상을 선택합니다.

2. 속성 패널의 딥 링크 섹션에서 +를 클릭합니다.

3. 표시되는 딥 링크 추가 대화 상자에서 딥 링크에 대한 정보를 입력합니다.

 

 - scheme가 없는 URI는 http 또는 https로 간주됩니다. 예를 들어 www.google.com은 http://www.google.com 및 https://www.google.com과 모두 일치 

- { placeholder_name } 형식의 path parameter placeholder 는 하나 이상의 문자와 일치합니다.

예를 들어 http://www.example.com/users/{id}는 http://www.example.com/users/4와 일치합니다. 

 

Navigation 구성 요소는 placeholder_name 을 딥 링크된 destination에 정의된 argument 와 일치시켜 자리 표시자 값을 적절한 유형으로 구문 분석하려고 시도합니다.

 

동일한 이름의 argument가 정의되지 않은 경우 argument 값에 기본 문자열 유형이 사용됩니다.  .* 와일드카드를 사용하여 0개 이상의 문자를 일치시킬 수 있습니다.

 

쿼리 매개변수 placeholder는 경로 매개변수 대체 또는 경로 매개변수와 함께 사용할 수 있습니다.

예를 들어 http://www.example.com/users/{id}?myarg={myarg}는 http://www.example.com/users/4?myarg=28과 일치.

 

본값 또는 nullable 값으로 정의된 변수에 대한 쿼리 매개변수 자리 표시자는 일치할 필요가 없습니다.

예를 들어 http://www.example.com/users/{id}?arg1={arg1} & arg2={arg2}는

http://www.example.com/users/4?arg2=28 또는 http와 일치합니다. //www.example.com/users/4?arg1=7    

 

path 매개변수의 경우적용 되지 않는다.

http://www.example.com/users?arg1=7&arg2=28 은 필수 경로 매개변수가 제공되지 않았기 때문에 위의 패턴과 불일치    

 

외부 쿼리 매개변수는 딥 링크 URI 일치에 영향을 주지 않습니다.

http://www.example.com/users/{id}는 URI 패턴에 extraneousParam이 정의되어 있지 않더라도 http://www.example.com/users/4?extraneousParam=7과 일치합니다.  

 

4. (선택 사항) Google에서 사용자가 URI의 소유자인지 확인하도록 하려면 자동 확인을 선택합니다. 자세한 내용은 Android 앱 링크 확인을 참조하세요.

 

5. 추가를 클릭합니다. 선택한 destination 위에 링크 아이콘이 나타나 destination에 딥 링크가 있음을 나타냅니다.

 

6. 코드 탭을 클릭하여 XML 보기로 전환합니다. 중첩된 <deepLink> 요소가 대상에 추가되었습니다.

 

<deepLink app:uri="https://www.google.com" />

 

암시적 딥 링크를 enable 하려면 앱의 manifest.xml 파일에도 추가해야 합니다. 다음 예와 같이 기존 탐색 그래프를 가리키는 Activity에 단일 <nav-graph> 요소를 추가합니다.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapplication">

    <application ... >

        <activity name=".MainActivity" ...>
            ...

            <nav-graph android:value="@navigation/nav_graph" />

            ...

        </activity>
    </application>
</manifest>

프로젝트를 빌드할 때 navi component 요소는 navi graph 의 모든 딥 링크와 일치하도록 <nav-graph> 요소를 생성된 <intent-filter> 요소로 대체합니다.

 

implicit 딥 링크를 트리거할 때 백 스택의 상태는 implicit intent가 Intent.FLAG_ACTIVITY_NEW_TASK 플래그로 시작되었는지 여부에 따라 다릅니다.

 

- 플래그가 설정되면 작업 백 스택이 지워지고 딥 링크 destination 으로 대체됩니다. 

nested graph를 이용할 때, 각 nested level의 start destination, 즉 계층 구조의 각 <navigation> 요소의 start destination도 스택에 추가됩니다. 즉, 사용자가 딥 링크 destinatiuon 에서 back button 을 누르면 진입점에서 앱에 들어간 것처럼 탐색 스택을 탐색합니다.

 

- 플래그가 설정되지 않은 경우 implicit  딥 링크가 트리거된 이전 앱의 작업 스택에 남아 있습니다.

이 경우 back button을 누르면 이전 앱으로 돌아가고 up button을 누르면 navi graph 내의 계층적 상위 대상에서 앱의 작업이 시작됩니다.

 

Handling deep links

Navigation을 사용할 때는 항상 standard의 기본 launchMode를 사용하는 것이 권장한다. 

standard 시작 모드를 사용할 때 Navigation은 인텐트 내의 명시적 또는 암시적 딥 링크를 처리하기 위해 handleDeepLink()를 호출하여 딥 링크를 자동으로 처리합니다. 그러나 singleTop과 같은 대체 launchMode를 사용할 때 Activity가 재사용되는 경우에는 자동으로 처리되지 않는다.  이 경우 다음 예와 같이 onNewIntent()에서 수동으로 handleDeepLink()를 호출해야 합니다.

 

override fun onNewIntent(intent: Intent?) {
    super.onNewIntent(intent)
    navController.handleDeepLink(intent)
}