2016-04-19 7 views
1

Ich habe eine benutzerdefinierte Einstellung erstellt, die zwei Schaltflächen einbettet (hier habe ich Button als FastButton subclassed). Das Problem ist das Ausführen der persistInt zum Speichern der Einstellung drastisch verlangsamt die Reaktion der Schaltfläche.PersistInt Verlangsamung Schaltfläche Antwort in benutzerdefinierten Voreinstellung

Ich hatte die Idee, die persistInt nur auszuführen, wenn der Lebenszyklus der Präferenz beendet ist, aber keine geeignete Methode zum Überschreiben finden konnte (d. H. Es gibt nichts wie onPause() für die Preference-Klasse).

Ich war auch nicht erfolgreich bei der Verwendung von AsyncTask, um die persistInt aus dem UI-Thread zu entfernen.

Irgendwelche Vorschläge darüber, wie ich den Effekt von persistInt auf meine UI-Antwort abmildern sollte?

public final class StepperPreference extends Preference { 

public int mCurrentValue = 1; 
public int maxValue = Integer.MAX_VALUE; 
public int minValue = Integer.MIN_VALUE; 
private TextView mText; 

private FastButton plusButton; 
private FastButton minusButton; 

public StepperPreference(Context context) { 
    super(context); 
} 

public StepperPreference(Context context, AttributeSet attrs) { 

    super(context, attrs); 
    parseCustomAttributes(attrs); 
} 

public StepperPreference(Context context, AttributeSet attrs, int defStyle) { 
    super(context, attrs, defStyle); 
    parseCustomAttributes(attrs); 
} 

public void setmCurrentValue(int value) { 
    if (mCurrentValue != value) { 
     mCurrentValue = value; 
     persistInt(mCurrentValue); 
    } 
} 

private void parseCustomAttributes(AttributeSet attrs) { 

    int maxValueAttrInt=Integer.MAX_VALUE; 
    int minValueAttrInt=Integer.MIN_VALUE; 

    if (attrs!=null) { 
     TypedArray a=getContext() 
       .obtainStyledAttributes(attrs, 
         R.styleable.StepperPreference, 
         0, 0); 

     maxValueAttrInt = a.getInt(R.styleable.StepperPreference_maxValue, Integer.MAX_VALUE); 
     minValueAttrInt = a.getInt(R.styleable.StepperPreference_minValue, Integer.MIN_VALUE); 
     a.recycle(); 
    } 

    if (maxValueAttrInt > minValueAttrInt) { 
     maxValue = maxValueAttrInt; 
     minValue = minValueAttrInt; 
    } 
} 

@Override 
protected View onCreateView(ViewGroup parent) { 
    LayoutInflater li = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 

    View view = (View) li.inflate(R.layout.stepper_preference, parent, false); 

    mText = (TextView) view.findViewById(R.id.text_view); 
    Context context = getContext(); 

    int localDefaultValue = 0; 
    mCurrentValue = getPersistedInt(localDefaultValue); 
    mText.setText(Integer.toString(mCurrentValue)); 


    plusButton = (FastButton) view.findViewById(R.id.plus_button); 
    plusButton.setOnClickListener(new View.OnClickListener() { 
     public void onClick(View v) { 
      if (mCurrentValue < maxValue) { 
       mCurrentValue++; 
       mText.setText(Integer.toString(mCurrentValue)); 
       persistInt(mCurrentValue); 

      } 
     } 
    }); 

    minusButton = (FastButton) view.findViewById(R.id.minus_button); 
    minusButton.setOnClickListener(new View.OnClickListener() { 
     public void onClick(View v) { 
      if (mCurrentValue > minValue) { 
       mCurrentValue--; 
       mText.setText(Integer.toString(mCurrentValue)); 
       persistInt(mCurrentValue); 
      } 
     } 
    }); 

    return view; 
} 

@Override 
protected Object onGetDefaultValue(TypedArray a, int index) { 
    int localDefaultValue = 0; 
    Object result = a.getInt(index, localDefaultValue); 
    return result; 
} 

@Override 
protected void onSetInitialValue(boolean restoreValue, Object defaultValue) { 
    int localDefaultValue = 0; 
    setmCurrentValue(restoreValue ? this.getPersistedInt(localDefaultValue) : (int) defaultValue); 
} 

} 
+1

Hmmm ... 'CheckBoxPreference' (über die Eltern' TwoStatePreference' Klasse) ruft 'persistBoolean() 'auf, wenn' CheckBox' aktiviert oder deaktiviert ist, also sollte Ihr Ansatz in Ordnung sein. Versuchen Sie es mit Methodenverfolgung, um genau zu sehen, wo Sie Ihre Zeit verbringen. – CommonsWare

+0

Wenn ich einfach die persistInt() auskommentieren, dann sehe ich die Schaltfläche Antwort dramatisch beschleunigt. Das hat mich dazu gebracht, zu glauben, dass das Bleibende mein Engpass ist. –

+1

Oh, ich stelle das nicht in Frage. Der Schlüssel ist: Warum ist 'persistInt()' so schlecht für dich, wenn es nicht so aussieht, als hätte 'CheckBoxPreference' eine schlechte Zeit mit' persistBoolean() '? Meine Hoffnung ist, dass die Methodenverfolgung, wenn man sieht, was stromabwärts von 'persistInt()' geschieht, einige Hinweise gibt. Ich habe nicht implementiert, was ich eine "Inline-Präferenz" nenne, wie das, was Sie tun - ich habe nur Unterklassen von 'DialogPreference' implementiert, wo es klare Punkte zum Laden/Speichern von Daten gibt. – CommonsWare

Antwort

1

CheckBoxPreference über seine TwoStatePreference geordnete Klasse verwendet persistBoolean() den Präferenzwert für das Speichern, so wie Sie persistInt() verwenden. Ich empfinde keine signifikante Latenz in der Verarbeitung des CheckBox. Das bedeutet, eines von zwei Dingen:

  1. Ich bin ein troglodyte und bin nicht in der Lage offensichtlich Verzögerungen bei Animationen zu sehen, und so

  2. CheckBoxPreference zeigt nicht die Probleme, die Sie in Ihrem StepperPreference

  3. sehen

Anmerkung: diese beiden Möglichkeiten schließen sich nicht aus

Wenn wir annehmen, dass # 2 korrekt ist, dann ist etwas anderes im Gange. Methode Tracing, um zu sehen, wo Sie Zeit "Downstream" von persistInt() verbringen, kann sich als nützlich für die Bestimmung, was ist anders an StepperPreference.

In Ihrem Kommentar reagierte ein Listener auf Präferenzänderungen, und das verursachte die langsame Reaktion. "Inline" -Präferenzen, wie CheckBoxPreference und StepperPreference, werden etwas "schwankender" sein als DialogPreference Unterklassen wie , einfach deshalb, weil es weniger Arbeit erfordert, den Präferenzzustand zu ändern (z. B. ein Bildschirmabgriff gegen 2+). Als Ergebnis müssen Zuhörer billiger sein. Beispielsweise könnten Sie so lange arbeiten, bis der Benutzer die PreferenceFragment verlassen hat und Sie wissen, dass die Präferenzwerte wahrscheinlich für mindestens eine Sekunde stabil sind.

Verwandte Themen