1

There is a scenario in which i need to pass activity and its button to a java class.

I did following and its working fine, I am only concerned if its the right way of integrating this.

MainActivity

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

    button= findViewById(R.id.btn);

    UIComponents uiComponents= new UIComponents();
    uiComponents.setActivity(this, button);

}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    Log.d("result", String.valueOf(requestCode));
}

UIComponents.class

public class UIComponents {

    public void setActivity(final AppCompatActivity activity, Button btn){

        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent= new Intent(activity, ResultActivity.class);
               activity.startActivityForResult(intent, 999);
            }
        });

    }

This works perfectly fine, It displays toast message on my activity screen, also i am able to receive onActivityResult callback on my activity. I am concerned if this can lead to any performance related issues.

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
dev90
  • 7,187
  • 15
  • 80
  • 153
  • 1
    https://stackoverflow.com/questions/24775425/is-it-bad-practice-to-pass-the-instance-of-an-activity-as-a-parameter-and-finish – AskNilesh May 14 '18 at 11:30

2 Answers2

1

you can just pass only the Button and use the getContext method available e.g

public class UIComponents {

public void setActivity(Button btn){
    Context activity = btn.getContext();
    btn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent= new Intent(activity, ResultActivity.class);
           activity.startActivityForResult(intent, 999);
        }
    });

}
Thankgod Richard
  • 507
  • 6
  • 16
1

The most important thing to consider here is the lifecycle of your components. In general you shouldn't pass a reference to an activity to any object which might outlive it. In theory (probably very rear), your activity might be killed between the time the user clicks the button and the time the OnClickListener (if it wasn't garbage collected yet) will be executed and you'll get a NullPointerException. Also, you might pass (even accidentally) UIComponents to some other object with a different lifecycle.

Best practice in such a case is usually using MVP architecture. The specific case of handling button clicks is described here among other places.

In addition, following the "Guide to App Architecture" by Google is probably a good idea.

Sir Codesalot
  • 7,045
  • 2
  • 50
  • 56
  • Thanks @SirCodesalot, I have also added another method in interface called `clearData`, I call it in onDestory() of activity, and it sets `null` to activity and button references. I am using MVP pattern in my app, but i am doing this for Single Sign on. – dev90 May 14 '18 at 12:21
  • Happy to help. You shouldn't rely on `onDestroy` because it often won't get called. See here: https://stackoverflow.com/questions/19608948/is-ondestroy-not-always-called/19608985#19608985 – Sir Codesalot May 14 '18 at 12:23