15

MAIN ACTIVITY

    public class MyActivity() extends Activity
    {
        onCreate()
        {
            MyClass myobj=new MyClass();    
        }
        public void Mymethod()
        {}
    }
//HELPER CLASS IN A SEPARATE FILE    
    public class MyClass()
    {
        MyClass(Context context)
        {

        }
    }

I tried to call Mymethod() from an instance of MyClass. I would really appreciate any help. Thanks.

Praful Bhatnagar
  • 7,425
  • 2
  • 36
  • 44
Deepak
  • 1,238
  • 3
  • 22
  • 47
  • Post the code that you've used to try calling the myMethod(). Are you instantiating a MyActivity object? If not I don't think you'll be able to call myMethod() since it is not static. You could try making myMethod() static and then you should be able to use MyActivity.myMethod() from your MyClass. P.s. I really hope you've changed the names of your classes for demonstration purposes here. If those are they names that you are actually using in your project you should seriously consider using more descriptive names. It will make your code easier to understand. – FoamyGuy Oct 20 '11 at 13:15
  • @Tim I tried to call using the context i passed to the constructor in MyClass, like so.. – Deepak Oct 20 '11 at 13:24
  • It is very bad practice to have static methods on Activities, I strongly advise you to find a way to do what you need to do without having a static method on the activity. – SnowyTracks Oct 20 '11 at 13:54

8 Answers8

27

Why not just pass the activity to the constructor like

public class MyActivity extends Activity { 

   onCreate(){ 
        MyClass myobj=new MyClass(MyActivity.this);     
   } 

   public void myMethod(){

   } 
} 

//HELPER CLASS IN A SEPARATE FILE     
public class MyClass{ 
    public MyClass(MyActivity act) { 
        act.myMethod();
    } 
} 
blessanm86
  • 31,439
  • 14
  • 68
  • 79
  • Thanks. Is this way completely safe to use? I keep hearing about memory leaks and I don't know if that applies to this. – TheEyesHaveIt Dec 31 '18 at 02:13
  • @TheEyesHaveIt I haven't coded java in over 6 years now. Tbh I don't know. – blessanm86 Jan 08 '19 at 09:17
  • After I tried this solution, I was wondering why some data will not be stored to my firebase database anymore. I debugged at another point where it still worked. I was confused when I saw that Android Studio stopped at the breakpoints before storing the data, but firebase showed that the data was stored. At other points, it was not working anymore. I fixed this bug by deinstall the app once. I can't guarantee that this caused the bug, but I've done nothing else at this moment. I would not recommend this solution. – RuhrpottDev Jul 27 '22 at 21:13
10

Make that method as static so you can call without creating the class object

public static void Mymethod()
{}

and call like this way

MainActivity.Mymethod();
Pratik
  • 30,639
  • 18
  • 84
  • 159
  • 1
    I cannot make the method as static as it references non static variables. So is making MyClass as an inner class of activity class the only solution – Deepak Oct 20 '11 at 13:40
9

This is probably the best way to do it. This is how I'm doing it. It's called a Singleton Design Pattern:

public class MyActivity extends Activity {
    private static MainActivity instance;

    public static MainActivity getInstance() {
     if(instance==null){
          setInstance(this);
        }
        return instance;
    }

    public static void setInstance(MainActivity instance) {
        MainActivity.instance = instance;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setInstance(this);
    }
}
pier shaw
  • 91
  • 1
  • 1
4

If I'm understanding you correctly I believe you can solve your problems using an interface as a callback.

////ACTIVITY/////////////////////////////////

 public class MyActivity() extends Activity {

    onCreate()
    {
        MyClass myObj=new MyClass();   

        //Set the listener on the object. Created as anonymous
        myObj.setListener(new MyClass.Listener() {
             myMethod();
        });
    }
}

public void myMethod(){

}

//////Custom Class//////////////////

public class MyClass {
     Listener mListener;

     public interface Listener {
          public void onInterestingEvent();
     }

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

     public void someUsefulThingTheClassDoes() {
          //Do your code here and when you're ready to call the activity's method do this
          mListener.onInterestingEvent();
     }
}
neonDion
  • 2,278
  • 2
  • 20
  • 39
3

I had an inner class that I wanted to pull out into a more general library "Helper" class. I had the same issue you do. I got around it by making the helper class abstract, with a single abstract method. Then in my project package I extended the helper class with a constructor call in the specific class.

public class MyActivity extends Activity {
    onCreate() {
        MyHelperClass = new MyHelperClass(this, "foobar");
    }

    public void myMethod() {
        // Code...
    }
}

// In a different file
public class MyHelperClass extends HelperClass {
    private MyActivity mInstance;

    public MyHelperClass(MyActivity act, String data) {
        super();
        this.mInstance = act;
        this.mActivity = act;  // Useful for calling generic Activity methods in the HelperClass
        this.mData = data;
    }

    protected void callMyActivityMethod() {
        mInstance.myMethod();
    }
}

// In a different file
public abstract class HelperClass {
    protected Activity  mActivity;
    protected String    mData;

    public HelperClass() {
        // Subclass will set variables
    }

    protected abstract void callMyActivityMethod();

    // More code for all the other stuff the class does
}

In this way, I have a helper class that contains the vast majority of the "work", and all I have to do is make a subclass with the constructor and one method in order to get access to the calling activity's method of interest.

XtopherSD
  • 333
  • 2
  • 11
2

You have to pass instance of MainActivity into another class, then you can call everything public (in MainActivity) from everywhere.

MainActivity.java

public class MainActivity extends AppCompatActivity {

    // Instance of AnotherClass for future use
    private AnotherClass anotherClass;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // Create new instance of AnotherClass and
        // pass instance of MainActivity by "this"
        anotherClass = new AnotherClass(this);
    }

    // Method you want to call from another class
    public void myMethod(){
        ...
    }
}

AnotherClass.java

public class AnotherClass {

    // Main class instance
    private MainActivity mainActivity;  

    // Constructor
    public AnotherClass(MainActivity activity) {

        // Save instance of main class for future use
        mainActivity = activity;  

        // Call method in MainActivity
        mainActivity.myMethod();
    }
}
Tmthetom
  • 69
  • 3
  • 1
    If I use your solution and have say 2 activities that might have to access the class, is there any way in the class to determine which activity context is being used? My particular class is accessed by 2 different activities, I am able to set it us as you have shown for each, just wondering if possible to set the context to a general variable which can be used in my class? Something like currentContext= which ever activity context is being used, so when I have to reference context I can use currentcContext in place of mainActivity or secondActivity. – snowman Feb 18 '18 at 01:09
0

In MainActivity.class file You have to pass MainActivity context from MainActivity Class. Then in MyClass you have to Get MainActivity context. Remember Context and MyActivity are two different reference.

public class MyActivity extends Activity
{
    onCreate(){
        MyClass myobj=new MyClass(MyActivity context);    
    }
    public void Mymethod(){}
}

//HELPER CLASS IN A SEPARATE FILE

public class MyClass()
{
    MyActivity context;
    MyClass(MyActivity context)
    {
      this.context = context;

      this.context.Mymethod();
      //Or you can directly use activity context
      context.Mymethod();
    }
}
Tushar
  • 3,527
  • 9
  • 27
  • 49
Yash
  • 482
  • 4
  • 12
-12

I decided to write the HelperClass MyClass as an inner class of MyActivity class. This allows it full access to parent class but the bad thing is now MyClass is restricted to MyActivity class only.

public class MyActivity() extends Activity
{
    onCreate()
    { 
        MyClass myobj=new MyClass();

    } 

    public void myMethod()
    {

    } 
} 
//INNER CLASS
    public class MyClass
    { 
        public MyClass() 
        { 

        } 
        //I can directly access the MyMethod
        myMethod();
    }
Deepak
  • 1,238
  • 3
  • 22
  • 47