남잭슨의 개발 블로그

[Android Jetpack] AAC Navigation Component -2. SafeArgs & Deeplink & Action 본문

Android

[Android Jetpack] AAC Navigation Component -2. SafeArgs & Deeplink & Action

남잭슨 2019. 8. 14. 05:07

 

2019/03/31 - [Android] - [Android Jetpack] AAC Navigation Component - 1. Navigation 소개,구성 및 개요 , BackStack관리

 

[Android Jetpack] AAC Navigation Component - 1. Navigation 소개,구성 및 개요 , BackStack관리

Navigation Android Jetpack 의 AAC (Android Architecture Component) 컴포넌트중 Navigation에 대해 알아보자! 네비게이션은 앱내의 화면 이동 구현을 도와주는 AAC 라이브러리이다. AAC 라이브러리는 기존에 없..

namjackson.tistory.com

AAC의 Navigation에 대해 잘모르는분들은 먼저 첫번째 게시글을 읽고 오자! 

 

이번글에는 SafeArgs, Deeplink , Action에 대해 소개할예정이다. 

 

 SafeArgs

먼저 SafeArgs를 사용하기 위해 추가 설정이 필요하다 

해당 설정은 구글 공식문서를 참고하여 추가하자

https://developer.android.com/jetpack/androidx/releases/navigation

 

기존에 Fragment의 이동에 따른 데이터전달은 보통 Argument Bundle을 이용한다. 

Navigation에서도 마찬가지로 Bundle을 이용하여 사용할수 있다.

findNavController().navigate(R.id.action_to_gameFragment, bundleOf("itemId" to 15))

마찬가지로 받을때 아래처럼 사용할수 있다.

arguments?.getInt("itemId")!!

이렇게 사용해도 큰 문제는 없지만, "itemId"라는 Key값을 통일하여 사용해야한다.

물론 상수로 정의하여 사용해도 되지만,

Navigation에서는 type-safe한 SafeArgs기능을 제공한다. NavGraph(Xml)의 Arguments를 미리 정의하여, 자동으로 Boilerplate Code를 생성하여 사용할 수 있다.  "itemId"라는 Key값을 사용할 필요가 없다.

자동으로 보내는 쪽에선 Directions Class가 생성되고, 받는 쪽에서는 Args Class가 생성된다.

    <fragment android:id="@+id/detailFragment"
              android:name="com.namjackson.arch.sample.view.ui.detail.DetailFragment"
              android:label="detail_fragment"
              tools:layout="@layout/detail_fragment">

        <argument
                android:name="itemId"
                app:argType="integer"
                android:defaultValue="0"/>
    </fragment>

 

NavGraph에서 fragment내의 argument를 정의하면, 자동으로 Directions,Args가 생성된다. 

findNavController().navigate( HomeListFragmentDirections.actionToDetail(itemId), extras)

HomeListFragmentDirections 클래스가 생성되고, HomeListFragment의 Action들이 메소드로 생긴다. 

해당 Action의 파라미터로 argument가 생성된다.

생성된현재FragmentDiretions클래스.정의된Action( 정의된 Argument)

위처럼 사용하면된다.

 

Action 목적지의 Fragment에서는 아래와 같이 파라미터를 받을수있다. 

// 2가지방법 - 1. by navArgs()
val safeArgs: DetailFragmentArgs by navArgs()
val itemId = safeArgs.itemId

// 2가지방법 - 2. fromBundle
arguments?.let {
  val arguments = DetailFragmentArgs.fromBundle(it)
  val itemId = arguments.itemId
}

 

DeepLink

딥링크는 안드로이드에서 어플의 특정 목적지까지 포인팅하는 URI이다.

이런 URI는 사용자에게 어떤일을 위해 특정 목적지로 보낼때 유용하다. 

ex> 빠르게 송금, 빠르게 메세지 확인, 빠르게 상품 확인 등등.. 

기존의 플로우 과정없이 한번에 이동하는 로직을 짤때 필요하다. 

 

Navigation의 DeepLink은 딥링크로 특정목적지를 들어왔어도,

첫화면부터 특정 목적지 까지의 일반적인 백스택을 그대로 지원해준다.

Navigation에서 DeepLink는 간단하게 짤수있다.

 

Deeplink는 두가지 구현방법이 있다.

1. Explicit Deep Linking - 명시적 딥링크

NavDeeplinkBuilder를 사용하여 인스턴스를 생성하여 핸들링이 가능하다.

val args = Bundle()
args.putString("itemId", itemId)
val pendingIntent = NavDeepLinkBuilder(context)
  .setGraph(R.navigation.mobile_navigation)
  .setDestination(R.id.detailFragment)
  .setArguments(args)
  .createPendingIntent()

위처럼 NavGraph, Desination Fragment, Args 를 명시적으로 선언하여 사용할 수 있다.

 

위 방법도 좋지만 

 

2. Implicit Deep Linking - 암시적 딥링크 

개인적으로 NavGraph에서 Navigation의 대한 정보를 정의하고 사용해야 Navigation Component가 의미가 있는거 같기 때문에 

이방법을 추천한다.

또한 더 간단하다. 

NavGraph에 선언하여 사용하면된다. 

  <fragment android:id="@+id/detailFragment"
          android:name="com.namjackson.arch.sample.view.ui.detail.DetailFragment"
          android:label="detail_fragment"
          tools:layout="@layout/detail_fragment">

    ...action 생략...

    <argument
          android:name="itemId"
          app:argType="integer"
          android:defaultValue="0"/>

    <deepLink android:id="@+id/deepLink"
          app:uri="sample.detail/{itemId}" />
  </fragment>

Manifest의 추가 작업이 더필요하다

 <activity
       android:name=".view.ui.MainActivity"
       android:label="@string/app_name">
   <intent-filter>
     <action android:name="android.intent.action.MAIN"/>

    <category android:name="android.intent.category.LAUNCHER"/>
  </intent-filter>

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

Manifestnav-graph추가와 , NavGraph에서의 <deepLink> 태그로 정의 하면 쉽게 사용가능하다

Action

Action은 Destination(Fragment)끼리의 화면이동이다.

NavGraph에선 화살표로 표시된다. 

Action엔 일반 Action, Global Action 두가지 종류가 있다.

일반적인 Action은 특정한 Destination <Fragment> 태그 아래에 존재하여, 특정 Destination에서 사용가능하지만

Global Action은 <Fragment> 태그들과 같은 레벨에 존재한다.

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:app="http://schemas.android.com/apk/res-auto"
            xmlns:tools="http://schemas.android.com/tools"
            app:startDestination="@id/dashboard"
            android:id="@+id/mobile_navigation">

  
    <fragment android:id="@+id/progressFragment"
              android:name="com.namjackson.arch.sample.view.ui.detail.ProgressFragment"
              android:label="progress_fragment"
              tools:layout="@layout/progress_fragment">
        <action
                android:id="@+id/action_to_detail"
                app:destination="@id/detailFragment"/>
        <argument
                android:name="itemId"
                app:argType="integer"
                android:defaultValue="0"/>
    </fragment>

    <fragment android:id="@+id/errorFragment"
              android:name="com.namjackson.arch.sample.view.ui.ErrorFragment"
              android:label="ErrorFragment"
              tools:layout="@layout/error_fragment"/>

    <action
            android:id="@+id/action_to_error"
            app:destination="@id/errorFragment"/>

</navigation>

action_to_error의 Action은 어디서나 사용가능한 Global Action이다.

 

Global Action의 경우 xml에선 화살표가 위와 같이 표현된다.

findNavController().navigate(R.id.action_to_error)

navigation은 일반적으로 똑같이 사용이 가능하다. 

 

샘플 코드

해당 예제 코드는 아래 깃허브에 구현하였습니다.

(네비게이션 외에도 클린아키텍쳐 스터디를 위해 오픈소스를 진행하고 있습니다. 많은 Star 와 많은 PR,Issue 참여해주세요! )

https://github.com/namjackson/Clean-Architecture-App

불러오는 중입니다...

 

 

다음글 

AAC Navigation Component -1. Navigation 소개, 구성 및 개여, BackStack 관리 ( 이전 글 )

AAC Navigation Component -2. SafeArgs & Deeplink & Action ( 현재 글 )

AAC Navigation Component -3. NavigationUI & Animation/Transition ( 다음 글 )

AAC Navigation Component -4. Navigation Upgrade (ViewModel with NavGraph Scope & Modularizing(Nested NavGraph) & Multiple-Start-Destination ) & 나의 후기, 장단점( 다음 글 )

Comments