Calling more than one callback at the same time

Asked

Viewed 61 times

1

I need a Workerclass that generates sequential numbers to print through a Callback interface these numbers in Mainactivity and a Segundaactivity when opened. My problem is that when Segundaactivity is open Mainactivity no longer receives the numbers being generated in Workerclass. Just follow my code:

Class Mainactivity

public class MainActivity extends AppCompatActivity implements MeuCallback {

    private Button button1;

    private MinhaWorkerClass minhaWorkerClass;

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

        button1 = (Button) findViewById(R.id.button1);
        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, SegundaActivity.class);
                startActivity(intent);
            }
        });

        minhaWorkerClass = minhaWorkerClass.getInstancia();
        if (minhaWorkerClass != null) {
            minhaWorkerClass.criaCallback(this);
        }
    }

    @Override
    public void imprimeNumero(int numero) {
        Log.i("Rute", "MainActivity-Numero: " + numero);
    }
}

Class Segundaactivity

public class SegundaActivity extends AppCompatActivity implements MeuCallback {

    private MinhaWorkerClass minhaWorkerClass;

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

        minhaWorkerClass = minhaWorkerClass.getInstancia();
        if (minhaWorkerClass != null) {
            minhaWorkerClass.criaCallback(this);
        }
    }

    @Override
    public void imprimeNumero(int numero) {
        Log.i("Rute", "SegundaActivity-Numero: " + numero);
    }
}

Class Minhaworkerclass

public class MinhaWorkerClass {

    private MeuCallback meuCallback;

    private static MinhaWorkerClass instancia;

    // Construtor privado:
    private MinhaWorkerClass() {

        constroiSequenciaNumeros();
    }

    public static synchronized MinhaWorkerClass getInstancia() {
        if (instancia == null) {
            instancia = new MinhaWorkerClass();
        }

        // Retorna sempre a unica instancia criada desta Classe:
        return instancia;
    }

    public void criaCallback(MeuCallback meuCallback){
        this.meuCallback = meuCallback;
    }

    private void constroiSequenciaNumeros() {

        new Thread(new Runnable() {
            @Override
            public void run() {

                for (int i = 0; i < 1000; i++) {

                    if (meuCallback != null) {
                        meuCallback.imprimeNumero(i);
                    }
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }
}

Interface Meucallback

public interface MeuCallback {

    void imprimeNumero(int numero);
}
  • Maybe the EventBus be an alternative.

  • This is easily done, even if you resort to any external api (Eventbus). However, there is a risk of memory leakage. What will you do with the numbers that Mainactivity receives while it is not visible?

  • @extension, I need to open new activities even if the Second Activity is still open.

  • You must find another way. Without knowing exactly what you want, it is impossible to find a solution. This form will "leak memory" whenever one of the Activities is destroyed by Android, for example while running the device.

  • @ramaral, this problem will be controlled because the new Activities will self-destruct after 4 seconds. My problem is that Mainactivity no longer knows what numbers are being generated in Workerclass whenever a new activity is open.

  • I did not mean the new activities but Mainactivity and Segundaactivity.

  • @ramaral, my code here exposed is just a small sketch of my actual project, and for that, it could be causing some confusion. The amount of activities that will be triggered by Mainactivity will be very few (+/- a 6) that will self-destruct. I would ask you, if possible, if you can show me your solution?

  • I repeat: the problem is not in the "activities that will be triggered by Mainactivity" but in Mainactivity and all those that use minhaWorkerClass.criaCallback(this)

  • Right, but still let me come to other conclusions and please show me your solution to get Mainactivity to receive Callback permanently?

Show 4 more comments

1 answer

2


The Minhaworkerclass class, as implemented, can only register a callback.

In order to register more than one you must store them in an array.

public class MinhaWorkerClass {

    private ArrayList<MeuCallback> callbacks = new ArrayList<>();

    ...
    ...

    public void addCallback(MeuCallback callback){

        if(!callbacks.contains(callback)){
            callbacks.add(callback);
        }
        return;
    }

    public void removeCallback(MeuCallback callback){

        callbacks.remove(callback);
        return;
    }

    private void constroiSequenciaNumeros() {

        new Thread(new Runnable() {
            @Override
            public void run() {

                for (int i = 0; i < 1000; i++) {

                    //Percorre o ArrayList e chama imprimeNumero()
                    //em todos os callbaks registados.

                    for(MeuCallback meuCallback : calbacks) {
                        meuCallback.imprimeNumero(i);
                    }

                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }
}

NOTE: This implementation can cause memory leakage if the class that implements Meucallback is an Activity/Fragment and these are destroyed/recreated by Android, this will happen, for example, whenever the device rotates.
To avoid this situation use minhaWorkerClass.removeCallback(this) in the method onDestroy().
Note that there are situations where onDestroy() may not be called.

  • ramaral, thank you for your reply, but your result is the same as mine, that is, Mainactivity’s Callback no longer receives data after opening Segundaativity. Have another solution?

  • I tested the code and it works. When I step into the second Activity, as you would expect, logs of the two activities are presented.

  • Yes it works perfectly. I had forgotten to apply the Foreach cycle to the Callbacks. Thank you very much.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.