Sử dụng tệp JSON trong Tài nguyên ứng dụng Android


87

Giả sử tôi có một tệp có nội dung JSON trong thư mục tài nguyên thô trong ứng dụng của mình. Làm cách nào để tôi có thể đọc nội dung này vào ứng dụng để có thể phân tích cú pháp JSON?

Câu trả lời:


143

Xem openRawResource . Một cái gì đó như thế này sẽ hoạt động:

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
Điều gì sẽ xảy ra nếu tôi muốn đặt chuỗi trong tài nguyên Chuỗi trong android và sử dụng nó động bằng cách sử dụng getResources (). GetString (R.String.name)?
Ankur Gautam

Đối với tôi nó doesn't công việc vì có dấu ngoặc kép, được bỏ qua khi đọc và đó cũng dường như không thể trốn thoát
Marian Klühspies

1
Có cách nào để làm cho ButterKnife liên kết tài nguyên thô không? Viết hơn 10 dòng mã chỉ để đọc một chuỗi có vẻ hơi quá mức cần thiết.
Jezor

Json được lưu trữ bên trong các tài nguyên như thế nào? Đơn giản chỉ cần bên trong \res\json_file.jsonthư mục hoặc bên trong \res\raw\json_file.json?
Cliff Burton

Câu trả lời này thiếu thông tin quan trọng. Có getResources()thể gọi là ở đâu? Tệp tài nguyên thô nên đi đâu? Bạn nên tuân theo quy ước nào để đảm bảo các công cụ xây dựng được tạo ra R.raw.json_file?
NobodyMan

112

Kotlin hiện là ngôn ngữ chính thức cho Android, vì vậy tôi nghĩ điều này sẽ hữu ích cho ai đó

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

Đây là một hoạt động có khả năng hoạt động lâu dài, vì vậy hãy đảm bảo rằng thao tác này được gọi ra khỏi chuỗi chính!
Andrew Orobator

@AndrewOrobator Tôi đã nghi ngờ rằng ai đó sẽ đưa json lớn vào bên trong tài nguyên ứng dụng, nhưng vâng, điểm tốt
Dima Rostopira

24

Tôi đã sử dụng câu trả lời của @ kabuko để tạo một đối tượng tải từ tệp JSON, sử dụng Gson , từ Tài nguyên:

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

Để sử dụng nó, bạn sẽ làm như sau (ví dụ trong một 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
Đừng quên thêm phần phụ thuộc {compile com.google.code.gson: gson: 2.8.2 '} vào tệp gradle của bạn
patrics

phiên bản cuối cùng của GSON làimplementation 'com.google.code.gson:gson:2.8.5'
Daniel

12

Từ http://developer.android.com/guide/topics/resources/providing-resources.html :


tệp thô / Tùy ý để lưu ở dạng thô. Để mở các tài nguyên này bằng InputStream thô, hãy gọi Resources.openRawResource () với ID tài nguyên là R.raw.filename.

Tuy nhiên, nếu bạn cần quyền truy cập vào tên tệp gốc và phân cấp tệp, bạn có thể cân nhắc lưu một số tài nguyên trong thư mục nội dung / (thay vì res / raw /). Các tệp trong nội dung / không được cung cấp ID tài nguyên, vì vậy bạn chỉ có thể đọc chúng bằng AssetManager.


5
Nếu tôi muốn nhúng tệp JSON vào ứng dụng của mình, tôi nên đặt tệp đó ở đâu? trong thư mục tài sản hay thư mục thô? Cảm ơn!
Ricardo

12

Giống như trạng thái @mah, tài liệu Android ( https://developer.android.com/guide/topics/resources/providing-resources.html ) cho biết tệp json có thể được lưu trong thư mục / raw trong / res (tài nguyên) thư mục trong dự án của bạn, ví dụ:

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

Bên trong một Activity, tệp json có thể được truy cập thông qua lớp R(Tài nguyên) và đọc đến một Chuỗi:

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

Điều này sử dụng lớp Java Scanner, dẫn đến ít dòng mã hơn so với một số phương pháp đọc tệp văn bản / json đơn giản khác. Mẫu dấu phân cách \Acó nghĩa là 'đầu của đầu vào'. .next()đọc mã thông báo tiếp theo, là toàn bộ tệp trong trường hợp này.

Có nhiều cách để phân tích cú pháp chuỗi json kết quả:


1
đây phải là câu trả lời được chấp nhận, chỉ cần hai dòng và xong. Cảm ơn
Ashana.Jackol

nhu cầuimport 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

Sử dụng:

String json_string = readRawResource(R.raw.json)

Chức năng:

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

Tìm thấy câu trả lời đoạn trích Kotlin này rất hữu ích ♥ ️

Trong khi câu hỏi ban đầu yêu cầu lấy Chuỗi JSON, tôi nghĩ một số có thể thấy điều này hữu ích. Một bước xa hơn với Gsondẫn đến chức năng nhỏ này với loại được sửa đổi:

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

Lưu ý rằng bạn không muốn sử dụng TypeTokenchỉ T::classnhư vậy nếu bạn đọcList<YourType> bạn sẽ không bị mất loại theo loại tẩy xóa.

Với kiểu suy luận bạn có thể sử dụng như sau:

fun pricingData(): List<PricingData> = readRawJson(R.raw.mock_pricing_data)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.