2017-08-09 3 views
0

Ich versuche, eine große JSON-Datei zu analysieren, die 24.000 Zeilen enthält (es enthält regelmäßige Ausdrücke zum Erkennen von SMS von SMS-Anbieter), die Datei wird lokal im Ordner Vermögenswerte gespeichert hier ist der Code von meine Klasseschwarzer Bildschirm beim Parsen lokalen JSON-Datei Android

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

}

das Problem hier ist, wenn ich Android Studio-Debugger verwenden kann ich sehen, dass alle JSON-Objekte und JSONArrays die Werte haben sie sollen have.But, wenn ich die App auf der Flucht Telefon es gibt mir schwarzen Bildschirm ohne Ausgabe. Ich habe versucht, AsyncTask zu implementieren, weil ich dachte, der schwarze Bildschirm sei aufgrund der großen Datenmenge, die er im Hauptthread verarbeitet hat, aus der JSON-Datei, aber auch nicht hilfreich. Kann mir bitte jemand in die richtige Richtung zeigen?

Ps-Ich bin ein Anfänger in Android Entwicklung

bearbeiten hinzugefügt 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

akzeptieren Antworten auf die Frage, die Ihnen geholfen haben, Ihr Problem zu lösen. Es ist eine kleine Belohnung für Leute, die Zeit mit ihnen verschwenden – Proxy

+0

Ja, Sir! Ich tu das sicher. :) –

+0

Wie implementieren Sie AsyncTask? Kannst du uns das teilen? –

Antwort

0

eine große JSON-Datei parsen, die 24.000 Zeilen enthält, ist komplexe Arbeit. AsynTask Mit in worker thread das Zeug durchzuführen, dann Ergebnis veröffentlicht in UI thread

Wenn Ihre App intensive Arbeit in Reaktion auf Benutzerinteraktion durchführt, kann dieses einzelne Thread-Modell schlechte Leistung liefern, wenn Sie richtig Ihre Anwendung implementieren. Insbesondere, wenn alles im UIhread passiert, werden lange Operationen wie Netzwerkzugriff oder Datenbankabfragen die gesamte UI blockieren. Wenn der Thread blockiert ist, können keine Ereignisse ausgelöst werden, auch keine Zeichnungsereignisse. Aus Sicht des Benutzers scheint die Anwendung zu hängen. Schlimmer noch, wenn der UI-Thread länger als einige Sekunden blockiert ist (etwa 5 Sekunden aktuell), wird dem Benutzer der berüchtigte Dialog "Anwendung reagiert nicht" (ANR) angezeigt. Der Benutzer könnte dann entscheiden, Ihre Anwendung zu beenden und sie zu deinstallieren, wenn sie unzufrieden sind.

Die unten Sachen in worker thread getan werden könnten, so müssen Sie es nicht in onPostExecute() setzen, die auf UI-Thread ausgeführt wird (Das ist der Grund, Ihre UI blockiert worden ist)

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

es also könnte so etwas sein

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 
    } 
} 
+0

ausgeführt Danke jetzt kann ich meine Tätigkeit sehen, aber die Daten werden nie angezeigt (ich setze den Adapter in onPostExecute()). Kann sein, dass es immer noch im Hintergrund läuft (ich warte wie 3 Minuten, aber es ist nie fertig), gibt es eine Möglichkeit, dass ich 10 Elemente in der Liste anzeigen kann und während der Benutzer scrollt, lade die restlichen Elemente gleichzeitig. –

+0

Hey, kannst du deinen Code auf github hochladen oder irgendwo, damit ich einen Blick darauf werfen kann –

Verwandte Themen