解析本地JSON文件android时的黑屏

时间:2017-08-09 14:43:48

标签: android json regex parsing

我正在尝试解析包含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();
        }

    }
}

1 个答案:

答案 0 :(得分:0)

解析包含24,000行的大型JSON文件是一项复杂的工作。使用AsynTaskworker 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
    }
}