Vasile Doe
Vasile Doe

Reputation: 1754

activity to activity callback listener

Let's suppose 2 activities Activity1 and Activity2. I need to call method methodAct1() (inside Activity1) from methodAct2 (inside Activity2). I think it should work using callback listener - I don't want to use EventBus libs!

I get java.lang.NullPointerException using this code:

interface:

public interface MyListener {
    public void listen();
}

Activity where event is created:

public class Activity2 extends Activity {

    private MyListener  myListener;

    public void setUpListener(MyListener myListener) {
        this.myListener = myListener;
    }

    private void doWork(){
        //do stuff 
        myListener.listen();
    }
}

Activity where I'd like to get that event when work is done:

public class Activity1 extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Activity2 activity2 = new Activity2();
        activity2.setUpListener(new setUpListener() {
            @Override
            public void listen() {
                // get the event here

            }
        });
    }
}

Upvotes: 4

Views: 28228

Answers (4)

Tushar Pramanik
Tushar Pramanik

Reputation: 211

You could do that in your approach like this....

public class Activity2 extends AppCompatActivity {

    private static MyListener  myListener;

    public static void setUpListener(MyListener Listener) {
        myListener = Listener;
    }

    public void doWork(View view) {
        myListener.listen();
    }
}


public class Activity1 extends AppCompatActivity {

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

        Activity2.setUpListener(new MyListener() {
            @Override
            public void listen() {
                Log.d("Hello", "Hello World");
            }
        });
    }

    public void goToAnotherActivity(View view) {
        startActivity(new Intent(Activity1.this, Activity2.class));
    }
}

Though it's not best approach and in order to work with this mechanism your activity1 needs to be created.

Upvotes: 4

tdjprog
tdjprog

Reputation: 719

You can do it like this > - STEP 01: Implement a shared interface


public interface SharedCallback {
    public String getSharedText(/*you can define arguments here*/);
}
  • STEP 02: Implement a shared class

final class SharedMethode {
    private static Context mContext;

    private static SharedMethode sharedMethode = new SharedMethode();

    private SharedMethode() {
        super();
    }

    public static SharedMethode getInstance() {
        return sharedMethode;
    }

    public void setContext(Context context) {
        if (mContext != null)
            return;

        mContext = context;
    }

    public boolean contextAssigned() {
        return mContext != null;
    }

    public Context getContext() {
        return mContext;
    }

    public void freeContext() {
        mContext = null;
    }
}

- STEP 03 :: Play with code in First Activity


public class FirstActivity extends Activity implements SharedCallback {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.your_layout);

        // call playMe from here or there
        playMe();
    }

    private void playMe() {
        SharedMethode.getInstance().setContext(this);
        Intent intent = new Intent(this, SecondActivity.class);
        startActivity(intent);
    }

    @Override
    public String getSharedText(/*passed arguments*/) {
        return "your result";
    }

}
  • STEP 04 :: Finalize the game in SecondActivity

public class SecondActivity extends Activity {

    private SharedCallback sharedCallback;

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

        if (SharedMethode.getInstance().contextAssigned()) {
            if (SharedMethode.getInstance().getContext() instanceof SharedCallback)
                sharedCallback = (SharedCallback) SharedMethode.getInstance().getContext();

            // to prevent memory leak. no further needs
            SharedMethode.freeContext();
        }

        // You can now call your implemented methodes from anywhere at any time
        if (sharedCallback != null)
            Log.d("TAG", "Callback result = " + sharedCallback.getSharedText());

    }

        @Override
        protected void onDestroy() {
        sharedCallback = null;
        super.onDestroy();
    }

}

you can also implement a backword callback (from First to Second) to get some results from SecondAvtivity or call some methods

Upvotes: -1

The NPE is happening because of your statement:

Activity2 activity2 = new Activity2(); <--

you should never do this, and instead you should do in the Activity 1:

Intent intent = new Intent(this, Activity2.class);
intent.putExtra("dataKey", "dataValue");
startActivityForResult(pickContactIntent, CALLBACK_REQUEST);

the startActivityForResult() offers a callback from Activity 2 to Activity 1, and you have to override the result in activity 1:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // Check which request we're responding to
    if (requestCode == CALLBACK_REQUEST) {
        // Make sure the request was successful
        if (resultCode == RESULT_OK) {
            // The Intent's data Uri identifies which contact was selected.

            // Do something with the contact here (bigger example below)
        }
    }
}

Upvotes: 5

Knossos
Knossos

Reputation: 16068

This is absolutely not possible. You never instanciate a new Activity yourself. You will not have two Activities running at the same time.

If you want another Activity to do something, based on what your previous Activity wants, then you need to add that to your Intent.

Intent intent = new Intent(this, Activity2.class);
intent.putExtra("data field", "data value");
startActivity(intent);

If you want specific functionality through a callback then you might be thinking of Fragments. In this way, you can have the same Activity running and it can tell individual Fragments what they need to do.

Upvotes: 7

Related Questions