解析JSON文件并快速存储

Parsing JSON file and store it fast

提问人:user3298565 提问时间:11/2/2023 最后编辑:user3298565 更新时间:11/3/2023 访问量:53

问:

我正在开发一个 Android 应用程序。

当应用程序打开时,它会使用 Recycler View 启动新片段。 Recycler View 的所有数据都位于一个文件夹(用户选择)中。

当片段开始时,它会列出该文件夹中的所有 DocumentFile[],如果 mimetype 为 Jason,则开始解析并将其保存到数组(自定义类 CallLogItem)中。

我的 CallLogItem 有几个变量:名称、电话、呼叫持续时间、呼叫方向。

现在我想优化我的代码:实际上它在加载器中使用 Gson 解析所有文件。我试图将其保存在共享首选项中

myPref.edit().putString(fileName, gson.toJson(my all)).apply()

我检查是否

myPref.getString(fileName,"").equals("")

一切正常,但速度并不快。

例如:在 420 个文件上,有 210 个是 JSON,需要 6 秒才能加载,检查首选项中是否存在字符串并解析值。有没有更快的东西?

这是我的JSON:



{

    "timestamp_unix_ms": 1698934275594,

    "timestamp": "2023-11-02T15:11:15.594+01:00",

    "direction": "out",

    "sim_slot": 1,

    "call_log_name": "Segr Telefonica",

    "calls": [

        {

            "phone_number": "42020",

            "phone_number_formatted": "42020",

            "caller_name": null,

            "contact_name": "Segr Telefonica"

        }

    ],

    "output": {

        "format": {

            "type": "OGG\/Opus",

            "mime_type_container": "audio\/ogg",

            "mime_type_audio": "audio\/opus",

            "parameter_type": "bitrate",

            "parameter": 48000

        },

        "recording": {

            "frames_total": 168960,

            "frames_encoded": 168960,

            "sample_rate": 48000,

            "channel_count": 1,

            "duration_secs_total": 3.52,

            "duration_secs_encoded": 3.52,

            "buffer_frames": 3840,

            "buffer_overruns": 0,

            "was_ever_paused": false,

            "was_ever_holding": false

        }

    }

}

当我保存到 SharedPreference 时,我只保存一些值,例如电话号码、方向、持续时间、simslot。

有什么帮助吗?

谢谢。

我试图将所有内容保存到 SharedPreference。

---编辑---- 这是我的代码:

片段: 在 onCreateView 中:

LoaderManager.getInstance(this).initLoader(LOADER_ID, null, this);

我的装载机:

@NonNull
    @Override
    public Loader<List<CallLogItem>> onCreateLoader(int id, @Nullable Bundle args) {
        progressBar.setVisibility(View.VISIBLE);

        chrono.setBase(SystemClock.elapsedRealtime());
        chrono.start();
        return new JsonFileLoader(requireActivity().getApplicationContext(), storedUriString, contactList);
    }

JsonFileLoader:

@Override
    public List<CallLogItem> loadInBackground() {
        List<CallLogItem> yourListOfItems = new ArrayList<>();
        SharedPreferences preferences = mContext.getSharedPreferences("JsonPref", Context.MODE_PRIVATE);


        if (storedUriString != null && !storedUriString.isEmpty()) {
            Uri treeUri = Uri.parse(storedUriString);
            DocumentFile pickedDir = DocumentFile.fromTreeUri(getContext(), treeUri);
            Log.d("JsonFileLoader.loadInBackground", "treeUri: " + treeUri + ", pickedDir: " + pickedDir);
            if (pickedDir!= null && pickedDir.isDirectory()) {
                // Get the list of files in the directory
                String documentId = DocumentsContract.getTreeDocumentId(treeUri);

                // Build a URI for the root directory
                Uri dirUri = DocumentsContract.buildChildDocumentsUriUsingTree(treeUri, documentId);

                // Use ContentResolver to query for files in the directory
                Cursor cursor = getContext().getContentResolver().query(
                        dirUri,
                        new String[]{
                                DocumentsContract.Document.COLUMN_DISPLAY_NAME,
                                DocumentsContract.Document.COLUMN_MIME_TYPE,
                                DocumentsContract.Document.COLUMN_DOCUMENT_ID
                        },
                        null,
                        null,
                        null
                );
                if (cursor != null && cursor.moveToFirst()) {
                    do {
                        // Retrieve file information from the cursor
                        String fileName = cursor.getString(1);
                        String mimeType = cursor.getString(2);
                        Log.d("JsonFileLoader.loadInBackground", "File: " + fileName + ", Type: " + mimeType);
                        if (mimeType.equals("application/json")) {
                            if (preferences.getString(fileName, "").equals("")) {
                                Log.d("JsonFileLoader.loadInBackground", "File not parsed: " + fileName);
                                StringBuilder content = new StringBuilder();
                                try {
                                    InputStream inputStream = mContext.getContentResolver().openInputStream(Uri.parse(cursor.getString(3)));
                                    if (inputStream != null) {

                                        BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
                                        CharArrayWriter charArrayWriter = new CharArrayWriter();
                                        char[] buffer = new char[1024];
                                        int bytesRead;
                                        InputStreamReader reader = new InputStreamReader(bufferedInputStream);
                                        while ((bytesRead = reader.read(buffer)) != -1) {
                                            charArrayWriter.write(buffer, 0, bytesRead);
                                        }
                                        content.append(charArrayWriter.toCharArray());

                                        reader.close();
                                        inputStream.close();
                                    }
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                                String jsonResponse = content.toString();
                                try {
                                    Gson gson = new GsonBuilder().create();
                                    CallLogResponse callLogResponse = gson.fromJson(jsonResponse, CallLogResponse.class);

[...]

                                    CallRegistration registration = new CallRegistration(contactUri, isContactSaved,
                                            callLogName, phoneNumber, phoneNumberFormatted, direction, timestamp, timestampDate.toString(), String.valueOf(durationSecsTotal), simSlot,
                                            audioFileUri.toString(), fileName, fileOutput);
                                    Log.d("JsonFileLoader.loadInBackground", "CallRegistration: " + gson.toJson(registration));
                                    editor.putString(fileName, gson.toJson(registration));
                                    editor.apply();
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                                //}
                                Log.d("File Info", "Name: " + fileName + ", Type: " + mimeType);
                            } else {
                                // Retrieve the JSON string from SharedPreferences
                                String json = preferences.getString(fileName, null);
                                Log.d("JsonFileLoader.loadInBackground", "json: " + json);
                                if (json!=null) {
                                    Gson gson = new GsonBuilder().create();
                                    CallRegistration callReg = gson.fromJson(json, CallRegistration.class);

                                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX", Locale.getDefault());
                                    Date timestampDate;
                                    try {
                                        timestampDate = sdf.parse(callReg.getTimestamp());
                                    } catch (ParseException e) {
                                        throw new RuntimeException(e);
                                    }
                                    Uri contactIcon = null;
                                    if (callReg.getContactIcon() != null)
                                        contactIcon = Uri.parse(callReg.getContactIcon());
                                    Log.d("JsonFileLoader.loadInBackground", "Contact: " + callReg.getContactName() + ", Number: " + callReg.getPhoneNumber() + ", saved: " + callReg.getContactSaved() + ", default icon" + (contactIcon == null));
                                    yourListOfItems.add(new CallLogItem(contactIcon, checkIfContactIsSaved(callReg.getPhoneNumber()),
                                            getContactName(callReg.getPhoneNumber()), callReg.getPhoneNumber(), callReg.getPhoneNumberFormatted(), callReg.getDirection(), callReg.getTimestamp(), timestampDate, Double.parseDouble(callReg.getDuration()), callReg.getSimSlot(),
                                            callReg.getAudioFileUri(), callReg.getFileName(), callReg.getFileOutput()));
                                }
                            }
                        }
                        // Continue processing the file information as needed
                        Log.d("File Info", "Name: " + fileName + ", Type: " + mimeType);
                    } while (cursor.moveToNext());

                    // Close the cursor after processing
                    cursor.close();
                }
            } else {
                // Handle the case where the selected item is not a directory
                Log.e("Error", "The selected item is not a directory");
            }
        }  // Handle the case where the URI is not stored or is invalid

        // Sort yourListOfItems by timestampDate in descending order (newest first)
        yourListOfItems.sort((item1, item2) -> item2.getTimestampDate().compareTo(item1.getTimestampDate()));
        return yourListOfItems;
    }

呼叫注册:

public class CallRegistration {
    private final String contact_icon_uri;
    private final boolean contact_saved;
    private final String contact_name;
    private final String phone_number;
    private final String phone_number_formatted;
    private final String timestamp;
    private final String timestamp_date;
    private final String duration;
    private final String direction;
    private final int sim_slot;
    private final String audio_file_uri;
    private final String file_name;
    private final String file_output;

    public CallRegistration(String contactIcon, boolean contactSaved, String contactName,
                            String phoneNumber, String phoneNumberFormatted, String direction,
                            String timestamp, String timestampDate, String duration, int simSlot,
                            String audioFileUri, String fileName, String fileOutputUri) {
        this.contact_icon_uri = contactIcon;
        this.contact_saved = contactSaved;
        this.contact_name = contactName;
        this.phone_number = phoneNumber;
        this.phone_number_formatted = phoneNumberFormatted;
        this.direction = direction;
        this.timestamp = timestamp;
        this.timestamp_date = timestampDate;
        this.duration = duration;
        this.sim_slot = simSlot;
        this.audio_file_uri = audioFileUri;
        this.file_name = fileName;
        this.file_output = fileOutputUri;
    }

    public String getContactIcon() {
        return contact_icon_uri;
    }

    public boolean getContactSaved() {
        return contact_saved;
    }

    public String getContactName() {
        return contact_name;
    }

    public String getPhoneNumber() {
        return phone_number;
    }

    public String getPhoneNumberFormatted() {
        return phone_number_formatted;
    }

    public String getTimestamp() {
        return timestamp;
    }

    public String getTimestampDate() {
        return timestamp_date;
    }

    public String getDuration() {
        return duration;
    }

    public String getDirection() {
        return direction;
    }

    public int getSimSlot() {
        return sim_slot;
    }

    public String getAudioFileUri() {
        return audio_file_uri;
    }

    public String getFileName() {
        return file_name;
    }

    public String getFileOutput() {
        return file_output;
    }

}

因此,在我第一次为dir中的每个文件创建一个循环时,如果文件被存储,我解析存储的json,否则我解析本地json并保存解析为新的json。

有没有更好的方法来存储我需要的这些值,然后读取这些值,而不是再次解析整个文件?

Android JSON 共享首选项

评论

0赞 blackapps 11/2/2023
目前尚不清楚您在共享首选项中保存的确切内容。整个json文件?
0赞 user3298565 11/3/2023
@blackapps我正在保存我的应用程序所需的值:时间戳、方向、simslot、电话号码。目前我保存了优先解析的值,例如:gson.toJson(带有一个声明的类,其中包含我需要的所有元素),然后下次我只检查preference.getString是否不为空,所以我解析存储的字符串(即JSON)
0赞 blackapps 11/3/2023
I want to optimize my code:如果不显示代码,则不清楚您对我们帮助您进行优化的期望。
0赞 user3298565 11/3/2023
确定!我不在家,会编辑帖子!
0赞 blackapps 11/3/2023
好的,我们继续。第一次通过时 6 秒,随后通过多少秒?

答: 暂无答案