提问人:user3298565 提问时间:11/2/2023 最后编辑:user3298565 更新时间:11/3/2023 访问量:53
解析JSON文件并快速存储
Parsing JSON file and store it fast
问:
我正在开发一个 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。
有没有更好的方法来存储我需要的这些值,然后读取这些值,而不是再次解析整个文件?
答: 暂无答案
评论
I want to optimize my code:
如果不显示代码,则不清楚您对我们帮助您进行优化的期望。