HOME > android > basic

안드로이드 - Assets에서 파일을 읽는 방법

JSFollow28 Jul 2019

안드로이드 앱은 내부에 스트링, 이미지 등의 많은 리소스들을 갖고 있습니다. 이런 리소스 파일들은 프로젝트에서 /res/ 경로에 위치합니다. 순수하게 .txt 등의 구조적인 경로의 파일들을 읽을 때에는 이런 방식으로 읽을 수 없습니다.(/res/raw/에 파일을 저장할 수 있지만 리소스 ID로 접근 가능하고, 파일 path로 직접 접근할 수 없습니다)

앱의 Apk 파일에 어떤 파일을 저장하고 앱에서 그 파일을 읽고 싶다면, Assets을 이용해야 합니다. 앱은 Assets에 파일들을 저장할 수 있으며 AssetManager를 통해서 이 파일들을 읽을 수 있습니다.

앞으로 프로젝트 내에서 Asset 폴더 및 파일을 어떻게 생성하는지 알아보고, AssetManager를 통해 파일에 접근하는 방법에 대해서 알아보겠습니다.

이 글에서 소개되는 코드는 모두 코틀린으로 작성되었습니다.

Assets 폴더 및 파일 생성

안드로이드 스튜디오 프로젝트에서 Asset 파일들은 /main/assets/ 경로 아래에 있습니다. 기본적으로 assets 폴더는 프로젝트에 생성되지 않기 때문에 직접 만들어줘야 합니다.

아래 그림처럼 [File] -> [New] -> [Folder] -> [Assets Folder]로 Assets 폴더를 생성할 수 있습니다. create assets folder in android studio

폴더를 만들기 전에 Assets path를 변경하겠냐고 물어봅니다. 특별한 이유가 없다면 Finish 버튼을 눌러 기본 위치에 폴더를 생성합니다. 그럼 폴더는 /main/assets/에 생성됩니다. create assets folder in android studio

이제 이 폴더에 파일을 생성하면 됩니다. 저는 posts.json이라는 파일을 만들었습니다.

└── main
    ├── AndroidManifest.xml
    └── assets
        └── posts.json

posts.json에 다음과 같이 내용을 입력하였습니다.

{
  "posts": [
    {
      "title": "how to get stroage size",
      "url": "https://codechacha.com/ko/get-free-and-total-size-of-volumes-in-android/",
      "draft": false
    },
    {
      "title": "Android Q, Scoped Storage",
      "url": "https://codechacha.com/ko/android-q-scoped-storage/",
      "draft": false
    },
    {
      "title": "How to parse JSON in android",
      "url": "https://codechacha.com/ko/how-to-parse-json-in-android/",
      "draft": true
    }
  ]
}

Apk에 Assets 파일의 위치

AssetManager로 Asset을 불러오기 전에 Apk파일에 Asset 파일이 어디에 위치해 있는지 한번 확인해보고 넘어가겠습니다.

Apk를 분석해보면 Apk 가장 상위 경로에서 /assets/폴더가 있고 그 아래에 /assets/posts.json 파일이 존재합니다. Assets in apk

AssetManager는 이 경로에서 파일들을 가져옵니다.

AssetManager로 Assets 파일 읽기

다음은 AssetManager로 json 파일을 읽는 코드입니다.

val assetManager = resources.assets
val inputStream= assetManager.open("posts.json")
val jsonString = inputStream.bufferedReader().use { it.readText() }

AssetManager는 App의 resources.assets로 가져올 수 있습니다. 그리고 AssetManager.open(file name)은 인자로 전달된 이름에 해당하는 파일을 가져와 InputStream으로 리턴해줍니다.

AssetManager의 root 경로는 "/assets/"이기 때문에, 인자로 전달되는 "posts.json"의 경로는 "/assets/posts.json"가 됩니다.

다음은 위의 코드로 가져온 json 파일의 스트링을 읽어 JSONObject로 파싱 하는 코드입니다.

val assetManager = resources.assets
val inputStream= assetManager.open("posts.json")
val jsonString = inputStream.bufferedReader().use { it.readText() }

val jObject = JSONObject(jsonString)
val jArray = jObject.getJSONArray("posts")

for (i in 0 until jArray.length()) {
    val obj = jArray.getJSONObject(i)
    val title = obj.getString("title")
    val url = obj.getString("url")
    val draft = obj.getBoolean("draft")
    Log.d(TAG, "title($i): $title")
    Log.d(TAG, "url($i): $url")
    Log.d(TAG, "draft($i): $draft")
}

실행 결과는 다음과 같습니다.

MainActivity: title(0): how to get stroage size
MainActivity: url(0): https://codechacha.com/ko/get-free-and-total-size-of-volumes-in-android/
MainActivity: draft(0): false
MainActivity: title(1): Android Q, Scoped Storage
MainActivity: url(1): https://codechacha.com/ko/android-q-scoped-storage/
MainActivity: draft(1): false
MainActivity: title(2): How to parse JSON in android
MainActivity: url(2): https://codechacha.com/ko/how-to-parse-json-in-android/
MainActivity: draft(2): true

Asset 파일의 경로

위에서 설명했듯이 AssetManager의 기본 root path는 /assets/입니다.

예를 들어, 프로젝트에서 아래처럼 파일을 생성하였습니다.

└── main
    ├── AndroidManifest.xml
    └── assets
        ├── posts.json
        └── xml
             └── settings.xml

위의 두개의 파일은 다음 처럼 가져올 수 있습니다. settings.xml은 xml폴더에 있기 때문에 "xml/settings.xml"를 인자로 전달해야 합니다.

val assetManager = resources.assets
val inputStream= assetManager.open("posts.json")
val inputStream= assetManager.open("xml/settings.xml")

정리

Assets은 이미지, String이 아닌 파일 등을 apk에 저장하고 앱에서 읽을 때 사용할 수 있습니다. Assets을 사용하려면 Assets 폴더를 만들고 파일을 저장해야 합니다. 그리고 AssetManager를 통해 파일을 읽어와야 합니다.

참고