我正在尝试解析包含24,000行的大型JSON文件(它包含常规表达式以检测来自sms提供程序的短信),该文件本地存储在assets文件夹中,这是我的类的代码
public class SmsActivity extends AppCompatActivity {
ListView lv;
ArrayList<String> msg;
ArrayAdapter<String> adapter;
JSONObject obj;
JSONArray rules_array;
JSONObject rule_object = null;
String body, address, smsDate;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sms);
lv = (ListView) findViewById(R.id.list);
permission();
}
void permission() {
// first check for permissions
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_SMS) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_SMS},
10);
} else {
adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, Inbox());
lv.setAdapter(adapter);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
switch (requestCode) {
case 10: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, Inbox());
lv.setAdapter(adapter);
Toast.makeText(this, "Permission is granted",
Toast.LENGTH_SHORT).show();
} else {//If permission is not granted,then it will ask for permission .
permission();
}
}
}
}
public String loadJSONFromAsset() {
String json = null;
try {
InputStream is = getAssets().open("sms_formats.json");
int size = is.available();
byte[] buffer = new byte[size];
is.read(buffer);
is.close();
json = new String(buffer, "UTF-8");
} catch (IOException ex) {
ex.printStackTrace();
return null;
}
return json;
}
//Arraylist is used to create dynamic array.The size can be varried .
public ArrayList<String> Inbox() {
msg = new ArrayList<>();
try {
//A Uri object is usually used to tell a ContentProvider what we want to access by reference.In this ,we are accessing inbox.
Uri uri = Uri.parse("content://sms/inbox");
//ContentResolver is used to request the content.
//cursor object gets the data.
Cursor cursor = getContentResolver().query(uri, new String[]{"_id", "address", "date", "body"}, null, null, null);
obj = new JSONObject(loadJSONFromAsset());
if (!obj.isNull("rules")) {
rules_array = obj.getJSONArray("rules");
//It checks whether there is any messages in inbox.If there is no message then the following if statement will not be executed.
if (cursor != null) {
while (cursor.moveToNext()) {
address = cursor.getString(1);
body = cursor.getString(3);
String date = cursor.getString(cursor.getColumnIndex("date"));
Long timestamp = Long.parseLong(date);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(timestamp);
Date finaldate = calendar.getTime();
smsDate = finaldate.toString();
for (int i = 0; i < rules_array.length(); i++) {
rule_object = rules_array.getJSONObject(i);
if (!rule_object.isNull("name")) {
// you have a name for the rule
Log.e("NO", "error");
}
if (!rule_object.isNull("patterns")) {
JSONArray pattern_array = rule_object.getJSONArray("patterns");
for (int j = 0; j < pattern_array.length(); j++) {
JSONObject pattern_obj = pattern_array.getJSONObject(j);
if (!pattern_obj.isNull("regex")) {
String type = pattern_obj.getString("sms_type");
if (type.equals("transaction")) {
String regex = pattern_obj.getString("regex");
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(body);
if (matcher.find()) {
msg.add("\nSender=>" + address + "\n" + "Message=>" + body + "\n" + "Date and Time=>" + smsDate + "\n");
}
}
}
}
}
}
}
cursor.close();
}
}
} catch (JSONException e) {
e.printStackTrace();
}
return msg;
}
}
这里的问题是,当我使用Android工作室调试器时,我可以看到所有JSON对象和JSONArrays都有它们应该拥有的值。但是当我在手机上运行应用程序时,它给了我黑屏,没有输出。 我试图实现AsyncTask因为我认为黑屏是由于它在JSON文件的主线程上处理的大量数据,但它也没有帮助。有人可以指出我正确的方向。
Ps-我是Android开发的初学者
编辑添加的AsyncTask。
public class LoadData extends AsyncTask<String, Void, JSONObject> {
String bodyData;
@Override
protected JSONObject doInBackground(String... body) {
bodyData = body.toString();
if (!obj.isNull("rules")) {
try {
rules_array = obj.getJSONArray("rules");
for (int i = 0; i < rules_array.length(); i++) {
rule_object = rules_array.getJSONObject(i);
if (!rule_object.isNull("name")) {
// you have a name for the rule
Log.e("NO", "error");
}
if (!rule_object.isNull("patterns")) {
JSONArray pattern_array = rule_object.getJSONArray("patterns");
for (int j = 0; j < pattern_array.length(); j++) {
JSONObject pattern_obj = pattern_array.getJSONObject(j);
if (!pattern_obj.isNull("regex")) {
return pattern_obj;
}
}
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
return null;
}
@Override
protected void onPostExecute(JSONObject pattern_obj) {
super.onPostExecute(pattern_obj);
String type = null;
try {
type = pattern_obj.getString("sms_type");
if (type.equals("transaction")) {
String regex = pattern_obj.getString("regex");
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(bodyData);
if (matcher.find()) {
msg.add("\nSender=>" + address + "\n" + "Message=>" + body + "\n" + "Date and Time=>" + smsDate + "\n");
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
答案 0 :(得分:0)
解析包含24,000行的大型JSON文件是一项复杂的工作。使用AsynTask
在worker thread
中执行该操作,然后将结果发布在UI thread
当您的应用执行密集型工作以响应用户交互时,除非您正确实施应用程序,否则此单线程模型可能会产生较差的性能。具体来说,如果UI线程中发生了所有事情,则执行网络访问或数据库查询等长时间操作将阻止整个UI。线程被阻止时,不会调度任何事件,包括绘制事件。从用户的角度来看,应用程序似乎挂起了。更糟糕的是,如果UI线程被阻止超过几秒钟(当前大约5秒),则向用户呈现臭名昭着的应用程序没有响应&#34; (ANR)对话框。然后,用户可能会决定退出您的应用程序,如果他们不满意,请将其卸载。
以下内容可以在worker thread
中完成,因此您不必将其放入运行在UI线程上的onPostExecute()
(这就是您的用户界面的原因)阻挡)
String type = null;
try {
type = pattern_obj.getString("sms_type");
if (type.equals("transaction")) {
String regex = pattern_obj.getString("regex");
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(bodyData);
if (matcher.find()) {
msg.add("\nSender=>" + address + "\n" + "Message=>" + body + "\n" + "Date and Time=>" + smsDate + "\n");
}
}
} catch (JSONException e) {
e.printStackTrace();
}
所以它可能是这样的
public class LoadData extends AsyncTask<String, Void, JSONObject> {
@Override
protected JSONObject doInBackground(String... body) {
// do your complex work
// This run on Worker Thread
return aJsonObject;
}
@Override
protected void onPostExecute(JSONObject jsonObject) {
super.onPostExecute(jsonObject);
// Doing anything with your view
// This run on UI Thread
}
}