JSON Dosyasını Android Uygulama Kaynaklarında Kullanma


88

Uygulamamdaki ham kaynaklar klasöründe JSON içeriğine sahip bir dosyam olduğunu varsayalım. JSON'u ayrıştırabilmek için bunu uygulamaya nasıl okuyabilirim?

Yanıtlar:


145

OpenRawResource'a bakın . Bunun gibi bir şey çalışmalı:

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'de dizeyi bir String kaynağına yerleştirmek ve bunu dinamik olarak getResources (). GetString (R.String.name) kullanarak kullanmak istersem ne olur?
Ankur Gautam

Benim için, okurken göz ardı edilen ve aynı zamanda kaçılamayacak gibi görünen alıntılar yüzünden işe yaramıyor
Marian Klühspies

1
ButterKnife'ın ham kaynağı bağlamasını sağlamanın bir yolu var mı ? Sadece bir dizeyi okumak için 10'dan fazla satır kod yazmak biraz abartılı gibi görünüyor.
Jezor

Kaynakların içinde json nasıl saklanır? Sadece \res\json_file.jsonklasörün içinde \res\raw\json_file.jsonmi yoksa içinde mi?
Cliff Burton

1
Bu cevap kritik bilgilerden yoksundur. Nereden getResources()aranabilir? Ham kaynak dosyası nereye gitmeli? Derleme araçlarının oluşturduğundan emin olmak için hangi kuralları izlemelisiniz R.raw.json_file?
NobodyMan

114

Kotlin artık Android için resmi dil, bu yüzden bunun birileri için yararlı olacağını düşünüyorum.

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

Bu, potansiyel olarak uzun süren bir işlemdir, bu yüzden bunun ana iş parçacığından çıkarıldığından emin olun!
Andrew Orobator

1
@AndrewOrobator Birinin uygulama kaynaklarına büyük json koyacağından şüpheliyim, ama evet, güzel nokta
Dima Rostopira

24

Kaynaklardan Gson kullanarak JSON dosyasından yüklenen bir nesne oluşturmak için @ kabuko'nun cevabını kullandım :

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);
    }
}

Kullanmak için aşağıdakine benzer bir şey yaparsınız (örnek bir içindedir 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 dosyanıza {compile com.google.code.gson: gson: 2.8.2 '} bağımlılıkları eklemeyi unutmayın
patrics

GSON'un son sürümüimplementation 'com.google.code.gson:gson:2.8.5'
Daniel

13

Gönderen http://developer.android.com/guide/topics/resources/providing-resources.html :

ham
formlarında kaydetmek için ham / keyfi dosyalar. Bu kaynakları ham bir InputStream ile açmak için, R.raw dosya adı olan kaynak kimliğiyle Resources.openRawResource () 'u çağırın.

Ancak, orijinal dosya adlarına ve dosya hiyerarşisine erişmeniz gerekiyorsa, bazı kaynakları assets / dizinine (res / raw / yerine) kaydetmeyi düşünebilirsiniz. Varlıklardaki / dosyalara bir kaynak kimliği verilmez, böylece bunları yalnızca AssetManager kullanarak okuyabilirsiniz.


5
Uygulamama bir JSON dosyası yerleştirmek istersem, nereye koymalıyım? varlıklar klasöründe mi yoksa ham klasörde mi? Teşekkürler!
Ricardo

13

@Mah'ın belirttiği gibi, Android belgeleri ( https://developer.android.com/guide/topics/resources/providing-resources.html ) json dosyalarının / res (kaynaklar) altındaki / raw dizinine kaydedilebileceğini söylüyor. projenizdeki dizin, örneğin:

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

Bir içinde Activity, json dosyasına R(Kaynaklar) sınıfı aracılığıyla erişilebilir ve bir String'e okunabilir:

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

Bu, Java sınıfını kullanır ve Scannerbasit bir metin / json dosyasını okumak için diğer bazı yöntemlerden daha az kod satırı sağlar. Sınırlayıcı model \A, 'girişin başlangıcı' anlamına gelir. .next()Bu durumda dosyanın tamamı olan bir sonraki belirteci okur.

Elde edilen json dizesini çözümlemenin birden çok yolu vardır:


1
bu kabul edilen cevap olmalı, sadece iki satır ve
tamam.Teşekkürler

ihtiyaçlarimport 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

Kullanarak:

String json_string = readRawResource(R.raw.json)

Fonksiyonlar:

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

Bulunan bu KOTLIN pasajı cevabı çok yararlı ♥ ️

Orijinal soru bir JSON Dizesi almak için sorulurken, bazılarının bunu yararlı bulabileceğini düşündüm. Bir adım daha ileri Gson, şeyleşmiş tipte bu küçük işleve yol açar:

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

TypeTokenSadece kullanmak istemediğinizi unutmayın, T::classeğer bir okursanız List<YourType>, türü silme yoluyla türü kaybetmezsiniz.

Tür çıkarımı ile daha sonra şu şekilde kullanabilirsiniz:

fun pricingData(): List<PricingData> = readRawJson(R.raw.mock_pricing_data)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.