web-dev-qa-db-fra.com

Balayage simultané de marques collantes d'arrière-plan libéré par GC

J'ai une application qui vérifie la base de données toutes les 10 secondes s'il y a de nouvelles données, s'il y a des données, elle les obtiendra et arrête de vérifier la base de données.

J'ai implémenté un observateur de texte pour vérifier si la zone de texte est vide. Si c'est le cas, la base de données sera vérifiée, si elle contient du texte, elle s'arrêtera.

Ceci est mon code:

 @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    txtBoxUser.addTextChangedListener(checkUserRent);

    getData();
}


//TEXTWATCHER FOR GETTING PERSON WHO RENTED BOX
private final TextWatcher checkUserRent = new TextWatcher() {
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    }

    public void onTextChanged(CharSequence s, int start, int before, int count) {
    }
    public void afterTextChanged(Editable s) {
        if (s.length() == 0) {
            check();
        } else {
            Toast.makeText(MainActivity.this, "STOP",
                    Toast.LENGTH_LONG).show();
        }
    }
};


public void start(View view)
{
    getData();
}

public void cancel(View view)
{
    txtBoxUser.setText("");
    txtBoxPasscode.setText("");
}

private void getData(){

  final String id = txtBoxName.getText().toString().trim();

    class GetEmployee extends AsyncTask<Void,Void,String>{
        ProgressDialog loading;
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
       //     loading = ProgressDialog.show(MainActivity.this,"Fetching...","Wait...",false,false);
        }

        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
      //      loading.dismiss();
            showEmployee(s);
        }

        @Override
        protected String doInBackground(Void... params) {
            RequestHandler rh = new RequestHandler();
            String s = rh.sendGetRequestParam(DATA_URL,id);
            return s;
        }
    }
    GetEmployee ge = new GetEmployee();
    ge.execute();
}

private void showEmployee(String json){
    try {
        JSONObject jsonObject = new JSONObject(json);
        JSONArray result = jsonObject.getJSONArray(JSON_ARRAY);
        JSONObject c = result.getJSONObject(0);
        String name = c.getString(GET_BOXUSER);
        String desg = c.getString(GET_PASSCODE);

        txtBoxUser.setText(name);
        txtBoxPasscode.setText(desg);

    } catch (JSONException e) {
        e.printStackTrace();
    }
}


private void check()
{
    getData();

}

Mais je reçois cela dans le logcat pendant qu'il attend les données. Je me demande simplement si cela va ou non?

I/art: Background sticky concurrent mark sweep GC freed 5614(449KB) AllocSpace objects, 18(288KB) LOS objects, 33% free, 1691KB/2MB, paused 5.354ms total 10.731ms
I/art: Background sticky concurrent mark sweep GC freed 7039(557KB) AllocSpace objects, 22(352KB) LOS objects, 39% free, 1561KB/2MB, paused 10.554ms total 15.931ms 
I/art: Background partial concurrent mark sweep GC freed 7279(564KB) AllocSpace objects, 21(336KB) LOS objects, 40% free, 1504KB/2MB, paused 5.721ms total 15.823ms
I/art: WaitForGcToComplete blocked for 5.375ms for cause HeapTrim
I/art: Background partial concurrent mark sweep GC freed 7650(591KB) AllocSpace objects, 22(352KB) LOS objects, 40% free, 1505KB/2MB, paused 5.511ms total 21.465ms
16
user6150841

C'est parfaitement bien. Cela signifie que vous utilisez la mémoire, puis que celle-ci est libérée par le GC. Son seul problème est soit que vous manquez de mémoire, soit que vous constatez des problèmes de performances dus à la récupération de place. Mais ce n'est pas quelque chose que vous devez courir pour réparer.

23
Gabe Sechan

J'ai eu le même problème. Votre code fonctionnera, mais si cela se bloque trop longtemps, l'application peut obtenir une erreur "App ne répond pas" et se fermer. Cela empêche également l'utilisation d'une tâche asynchrone.

Le problème est que votre AsyncTask contient une vue de texte, ce qui bloque toute autre action lors de l'exécution. Pour résoudre ce problème, rendez votre AsyncTask statique et transmettez-lui une référence à la vue Texte. Puis stockez-le dans un WeakReference.

static class GetEmployee extends AsyncTask<Void,Void,String>{

    WeakReference<TextView> textUserWeakReference;
    WeakReference<TextView> textPassWeakReference;
    GetEmployee(TextView textUser, TextView textPass) {
        textUserWeakReference = new WeakReference<>(textUser);
        textPassWeakReference = new WeakReference<>(textPass);
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
   //     loading = ProgressDialog.show(MainActivity.this,"Fetching...","Wait...",false,false);
    }

    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);
  //      loading.dismiss();
        TextView textUser = textUserWeakReference.get();
        TextView textPass = textPassWeakReference.get();
        if(textView != null && textPass != null)
            showEmployee(s, textUser, textPass);
    }

    @Override
    protected String doInBackground(Void... params) {
        RequestHandler rh = new RequestHandler();
        String s = rh.sendGetRequestParam(DATA_URL,id);
        return s;
    }
}
private static void showEmployee(String json, TextView txtBoxUser, TextView txtBoxPassCode){
try {
    JSONObject jsonObject = new JSONObject(json);
    JSONArray result = jsonObject.getJSONArray(JSON_ARRAY);
    JSONObject c = result.getJSONObject(0);
    String name = c.getString(GET_BOXUSER);
    String desg = c.getString(GET_PASSCODE);

    txtBoxUser.setText(name);
    txtBoxPasscode.setText(desg);

} catch (JSONException e) {
    e.printStackTrace();
}
}
1
Joel Page