Android 앱 리소스에서 JSON 파일 사용


87

내 앱의 원시 리소스 폴더에 JSON 콘텐츠가있는 파일이 있다고 가정합니다. JSON을 구문 분석 할 수 있도록 어떻게 이것을 앱으로 읽어 들일 수 있습니까?

답변:


143

openRawResource를 참조하십시오 . 다음과 같이 작동합니다.

InputStream is = getResources().openRawResource(R.raw.json_file);
Writer writer = new StringWriter();
char[] buffer = new char[1024];
try {
    Reader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
    int n;
    while ((n = reader.read(buffer)) != -1) {
        writer.write(buffer, 0, n);
    }
} finally {
    is.close();
}

String jsonString = writer.toString();

1
Android의 String 리소스에 문자열을 넣고 getResources (). getString (R.String.name)을 사용하여 동적으로 사용하려면 어떻게해야합니까?
Ankur Gautam 2014 년

나를 위해 그것은 읽을 때 무시되고 또한 탈출 할 수없는 것처럼 보이는 인용문 때문에 작동하지 않습니다
Marian Klühspies dec.

1
ButterKnife 가 원시 리소스를 바인딩 하도록하는 방법이 있습니까? 문자열을 읽기 위해 10 줄 이상의 코드를 작성하는 것은 약간 과잉 인 것처럼 보입니다.
Jezor 2016 년

json은 리소스 내부에 어떻게 저장됩니까? 단순히 \res\json_file.json폴더 내부 또는 내부 \res\raw\json_file.json?
Cliff Burton

이 답변에는 중요한 정보가 없습니다. 어디로 전화 할 getResources()수 있습니까? 원시 리소스 파일은 어디로 가야합니까? 빌드 도구가 만들려면 어떤 규칙을 따라야 R.raw.json_file합니까?
NobodyMan

112

Kotlin은 이제 Android의 공식 언어이므로 누군가에게 유용 할 것 같습니다.

val text = resources.openRawResource(R.raw.your_text_file)
                                 .bufferedReader().use { it.readText() }

이것은 잠재적으로 오래 실행되는 작업이므로 주 스레드에서 호출되었는지 확인하십시오!
Andrew Orobator

@AndrewOrobator 누군가가 큰 json을 앱 리소스에 넣을지 의심 스럽지만 그래, 좋은 점
Dima Rostopira

24

@kabuko의 답변을 사용 하여 리소스에서 Gson을 사용하여 JSON 파일에서로드하는 객체를 만들었습니다 .

package com.jingit.mobile.testsupport;

import java.io.*;

import android.content.res.Resources;
import android.util.Log;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;


/**
 * An object for reading from a JSON resource file and constructing an object from that resource file using Gson.
 */
public class JSONResourceReader {

    // === [ Private Data Members ] ============================================

    // Our JSON, in string form.
    private String jsonString;
    private static final String LOGTAG = JSONResourceReader.class.getSimpleName();

    // === [ Public API ] ======================================================

    /**
     * Read from a resources file and create a {@link JSONResourceReader} object that will allow the creation of other
     * objects from this resource.
     *
     * @param resources An application {@link Resources} object.
     * @param id The id for the resource to load, typically held in the raw/ folder.
     */
    public JSONResourceReader(Resources resources, int id) {
        InputStream resourceReader = resources.openRawResource(id);
        Writer writer = new StringWriter();
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(resourceReader, "UTF-8"));
            String line = reader.readLine();
            while (line != null) {
                writer.write(line);
                line = reader.readLine();
            }
        } catch (Exception e) {
            Log.e(LOGTAG, "Unhandled exception while using JSONResourceReader", e);
        } finally {
            try {
                resourceReader.close();
            } catch (Exception e) {
                Log.e(LOGTAG, "Unhandled exception while using JSONResourceReader", e);
            }
        }

        jsonString = writer.toString();
    }

    /**
     * Build an object from the specified JSON resource using Gson.
     *
     * @param type The type of the object to build.
     *
     * @return An object of type T, with member fields populated using Gson.
     */
    public <T> T constructUsingGson(Class<T> type) {
        Gson gson = new GsonBuilder().create();
        return gson.fromJson(jsonString, type);
    }
}

이를 사용하려면 다음과 같이해야합니다 (예는에 있음 InstrumentationTestCase).

   @Override
    public void setUp() {
        // Load our JSON file.
        JSONResourceReader reader = new JSONResourceReader(getInstrumentation().getContext().getResources(), R.raw.jsonfile);
        MyJsonObject jsonObj = reader.constructUsingGson(MyJsonObject.class);
   }

3
gradle 파일에 종속성 {compile com.google.code.gson : gson : 2.8.2 '}을 추가하는 것을 잊지 마세요
patrics

GSON의 마지막 버전입니다implementation 'com.google.code.gson:gson:2.8.5'
다니엘

12

에서 http://developer.android.com/guide/topics/resources/providing-resources.html :

raw /
원시 형식으로 저장할 임의 파일. 원시 InputStream으로 이러한 리소스를 열려면 리소스 ID (R.raw.filename)를 사용하여 Resources.openRawResource ()를 호출합니다.

그러나 원래 파일 이름과 파일 계층에 액세스해야하는 경우에는 assets / 디렉토리에 일부 리소스를 저장하는 것이 좋습니다 (res / raw / 대신). assets /의 파일에는 리소스 ID가 제공되지 않으므로 AssetManager를 사용해서 만 읽을 수 있습니다.


5
내 앱에 JSON 파일을 삽입하려면 어디에 넣어야합니까? 자산 폴더 또는 원시 폴더에 있습니까? 감사!
Ricardo

12

@mah 상태와 마찬가지로 Android 문서 ( https://developer.android.com/guide/topics/resources/providing-resources.html )에서는 json 파일이 / res (리소스) 아래의 / raw 디렉토리에 저장 될 수 있다고 말합니다. 프로젝트의 디렉토리, 예 :

MyProject/
  src/ 
    MyActivity.java
  res/
    drawable/ 
        graphic.png
    layout/ 
        main.xml
        info.xml
    mipmap/ 
        icon.png
    values/ 
        strings.xml
    raw/
        myjsonfile.json

내부 Activity, JSON 파일은 통해 액세스 할 수 있습니다 R(참고 자료) 클래스와 String으로 읽기 :

Context context = this;
Inputstream inputStream = context.getResources().openRawResource(R.raw.myjsonfile);
String jsonString = new Scanner(inputStream).useDelimiter("\\A").next();

이것은 Java 클래스를 사용하므로 Scanner간단한 텍스트 / json 파일을 읽는 다른 방법보다 코드 줄이 적습니다. 구분자 패턴 \A은 '입력의 시작'을 의미합니다. .next()이 경우 전체 파일 인 다음 토큰을 읽습니다.

결과 json 문자열을 구문 분석하는 방법에는 여러 가지가 있습니다.


1
이것은 받아 들여진 대답이어야합니다. 단 두
줄이면 끝났습니다 .Thanks

필요import java.util.Scanner; import java.io.InputStream; import android.content.Context;
AndrewHarvey

4
InputStream is = mContext.getResources().openRawResource(R.raw.json_regions);
                            int size = is.available();
                            byte[] buffer = new byte[size];
                            is.read(buffer);
                            is.close();
                           String json = new String(buffer, "UTF-8");

1

사용 :

String json_string = readRawResource(R.raw.json)

기능 :

public String readRawResource(@RawRes int res) {
    return readStream(context.getResources().openRawResource(res));
}

private String readStream(InputStream is) {
    Scanner s = new Scanner(is).useDelimiter("\\A");
    return s.hasNext() ? s.next() : "";
}

0

발견 이 코 틀린 조각 대답은 매우 도움이 ♥ ️

원래 질문은 JSON 문자열을 요청했지만 일부는 이것이 유용하다고 생각합니다. 한 단계 더 나아가서 수정 Gson된 유형의이 작은 기능으로 이어집니다.

private inline fun <reified T> readRawJson(@RawRes rawResId: Int): T {
    resources.openRawResource(rawResId).bufferedReader().use {
        return gson.fromJson<T>(it, object: TypeToken<T>() {}.type)
    }
}

사용하려는 참고 TypeToken그냥 T::class당신이 읽는다면 그래서 List<YourType>당신이 유형의 삭제에 의해 유형을 잃지 않을 것입니다.

유형 추론을 사용하면 다음과 같이 사용할 수 있습니다.

fun pricingData(): List<PricingData> = readRawJson(R.raw.mock_pricing_data)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.