Emm ... non dovrebbe fare questo.
perché il modo in cui una classe anonima accede al metodo o al campo della classe padre memorizzando un riferimento invisibile alla classe genitore.
per esempio, si ha un Activity
:
public class MyActivity
extends Activity
{
public void someFunction() { /* do some work over here */ }
public void someOtherFunction() {
Runnable r = new Runnable() {
@Override
public void run() {
while (true)
someFunction();
}
};
new Thread(r).start(); // use it, for example here just make a thread to run it.
}
}
il compilatore in realtà generare qualcosa di simile:
private static class AnonymousRunnable {
private MyActivity parent;
public AnonymousRunnable(MyActivity parent) {
this.parent = parent;
}
@Override
public void run() {
while (true)
parent.someFunction();
}
}
Così, quando i vostri genitori Activity
distrugge (a causa di modifica della configurazione, ad esempio) e la tua classe anonima esiste ancora, l'intera attività non può essere gc-ed. (perché qualcuno ha ancora un riferimento.)
CHE DIVENTA UNA PERDITA DI MEMORIA E FAI LA TUA APP GO LIMBO !!!
Se me è stato, vorrei attuare il "onProgressUpdate()" per i caricatori in questo modo:
public class MyLoader extends AsyncTaskLoader<Something> {
private Observable mObservable = new Observable();
synchronized void addObserver(Observer observer) {
mObservable.addObserver(observer);
}
synchronized void deleteObserver(Observer observer) {
mObservable.deleteObserver(observer);
}
@Override
public void loadInBackground(CancellationSignal signal)
{
for (int i = 0;i < 100;++i)
mObservable.notifyObservers(new Integer(i));
}
}
E nella classe Activity
public class MyActivity extends Activity {
private Observer mObserver = new Observer() {
@Override
public void update(Observable observable, Object data) {
final Integer progress = (Integer) data;
mTextView.post(new Runnable() {
mTextView.setText(data.toString()); // update your progress....
});
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreated(savedInstanceState);
MyLoader loader = (MyLoader) getLoaderManager().initLoader(0, null, this);
loader.addObserver(mObserver);
}
@Override
public void onDestroy() {
MyLoader loader = (MyLoader) getLoaderManager().getLoader(0);
if (loader != null)
loader.deleteObserver(mObserver);
super.onDestroy();
}
}
ricordarsi di deleteObserver()
durante onDestroy()
è importante in questo modo il caricatore non tiene per sempre un riferimento alla tua attività. (il caricatore sarà probabilmente tenuto in vita durante il ciclo di vita Application
...)
Penso che questo sia un trucco molto intelligente. Non ci avevo mai pensato. Stavo cercando il modo di inviare i miei aggiornamenti di avanzamento tramite Loaders. Ci proverò e ti farò sapere. Penso che la tua soluzione dovrebbe funzionare !! – douggynix
Il collegamento sembra essere andato male. [Qui] (https://yadi.sk/d/qovznXrpUbbum) è funzionante (penso sia lo stesso). – EmmanuelMess