35

I am trying to make listener interface between two activities Act1 and Act2. Act1 will start Act2. If there is some event occurred in Act2, it will inform it to Act1. Problem is that I am starting new activity using Intent, so how Act1 will assign itself as listener to Act2's interface?

Act1.java

public class Act1 extends ActionBarActivity implements
        ActionBar.OnNavigationListener {

    ActionBar actionbar;
    Intent pizzaIntent;
    boolean visibleFirstTime = true;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.menutab);

        //set actionbar here
    }

@Override
    public boolean onNavigationItemSelected(int arg0, long arg1)// item pos,
                                                                // itemid
    {
        switch (arg0) {
        case 0:
            if(this.visibleFirstTime == false)
            {
            if(pizzaIntent == null)
            {
                pizzaIntent = new Intent(this,Act2.class);
                //how to call setChangeListener?
            }
            startActivity(pizzaIntent);
            }
            else
                this.visibleFirstTime = false;
            break;
        case 1:
            System.out.println("selected: " + arg0);
            break;
        case 2:
            System.out.println("selected: " + arg0);
            break;
        case 3:
            System.out.println("selected: " + arg0);
            break;
        default:
            break;
        }
        return true;
    }
}

Act2.java

public class Act2 extends Activity {

     selectionChangeListener listener;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.pizza_slice_selection);
    }

    public void setChangeListener(selectionChangeListener listener)
    {
        this.listener = listener;
    }

    private interface selectionChangeListener
    {
        public void selectionMadeAtIndex(int index);
    }
}

Note: Please don't suggest me to use fragments. I want to use activities currently.

NightFury
  • 13,436
  • 6
  • 71
  • 120

3 Answers3

77

I would suggest to create a model class. Let me give you an example:

Model class:

public class CustomModel {

    public interface OnCustomStateListener {
        void stateChanged();
    }

    private static CustomModel mInstance;
    private OnCustomStateListener mListener;
    private boolean mState;

    private CustomModel() {}

    public static CustomModel getInstance() {
        if(mInstance == null) {
            mInstance = new CustomModel();
        }
        return mInstance;
    }

    public void setListener(OnCustomStateListener listener) {
        mListener = listener;
    }

    public void changeState(boolean state) {
        if(mListener != null) {
            mState = state;
            notifyStateChange();
        }
    }

    public boolean getState() {
        return mState;
    }

    private void notifyStateChange() {
        mListener.stateChanged();
    }
}

And here's how you would use this:

// Imports
public class MainActivity extends Activity implements OnCustomStateListener {

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

        boolean modelState = CustomModel.getInstance().getState();
        Log.d(TAG, "Current state: " + String.valueOf(modelState));

        Intent intent = new Intent(this, SecondActivity.class);
        startActivity(intent);
    }

    @Override
    public void stateChanged() {
        boolean modelState = CustomModel.getInstance().getState();
        Log.d(TAG, "MainActivity says: Model state changed: " + 
            String.valueOf(modelState));
    }
}

Changing the member state in second activity:

// Imports
public class SecondActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        CustomModel.getInstance().changeState(true);
    }
}

LogCat output:

Current state: false

MainActivity says: Model state changed: true

vilpe89
  • 4,656
  • 1
  • 29
  • 36
  • 2
    Worst idea ever ... you should never store Activity references in some singleton ...while simple `Log` statment in `stateChanged` may work ... any UI interaction is not allowed! – Selvin Jul 23 '15 at 11:58
  • @Selvin Well of course you need to remove the listener in onDestroy when the current instance of listening activity is not alive anymore if you want to interact with UI but that was not the point here, sorry.... – vilpe89 Jul 27 '15 at 11:12
35

Have you considered using LocalBroadcastManager?

In Act1's onCreate:

act2InitReceiver= new BroadcastReceiver()
    {

        @Override
        public void onReceive(Context context, Intent intent)
        {
            // do your listener event stuff
        }
    };
LocalBroadcastManager.getInstance(this).registerReceiver(act2InitReceiver, new IntentFilter("activity-2-initialized"));

In Act1's onDestroy:

LocalBroadcastManager.getInstance(this).unregisterReceiver(act2InitReceiver);

In Act2's onCreate:

LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent("activity-2-initialized"));

Give me a comment if the code doesn't compile, I'm writing it by hand.

npace
  • 4,218
  • 1
  • 25
  • 35
  • 6
    This answer helped me in understanding local broadcast more better. http://stackoverflow.com/a/8875292/437146 – NightFury Sep 26 '13 at 12:28
  • 1
    This is not the answer of question. Question is a different and answer is different – Shafqat Kamal May 14 '20 at 11:17
  • 1
    This answer is pretty old now, 7 years later. LocalBroadcastManager has been deprecated. A more up-to-date approach would be to have a shared model object (maybe a singleton) and have both Activities use that to share data. You should be careful to never store Activity references in that model, though! – npace Jul 02 '20 at 09:18
-2

The best, shortest and the easiest way to do this is to use static variables, like this:

class Main extends Activity {
  static String message = "Hi";
}

class Another extends Activity {
  public onCreate() {
     Log.i(Main.message); // implementation of the message, 'Hi' 
  }
}
LEMUEL ADANE
  • 8,336
  • 16
  • 58
  • 72