[java] How to call a method in MainActivity from another class?

How do I call the method startChronometer in another class when the method is declared inside the main activity?

Inside MainActivity:

public void startChronometer() {
    mChronometer.start();
    showElapsedTime();
}

Inside another class, I tried to do this:

MainActivity mActivity;
mActivity.startChronometer();

But an error occurred which said:

java.lang.NullPointerException. 

May I know what more I need to add to the code?

This question is related to java android

The answer is


MainActivity.java

public class MainActivity extends AppCompatActivity {

    private static MainActivity instance;

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

    public static MainActivity getInstance() {
        return instance;
    }

    public void myMethod() {
       // do something...
    }
)

AnotherClass.java

public Class AnotherClass() {
     // call this method
     MainActivity.getInstance().myMethod();
}

Use this code in sub Fragment of MainActivity to call the method on it.

((MainActivity) getActivity()).startChronometer();

You can make this method static.

public static void startChronometer(){
        mChronometer.start();
        showElapsedTime();
    } 

you can call this function in other class as below:

MainActivity.startChronometer();

OR

You can make an object of the main class in second class like,

MainActivity mActivity = new MainActivity();
mActivity.startChronometer();

But an error occurred which says java.lang.NullPointerException.

Thats because, you never initialized your MainActivity. you should initialize your object before you call its methods.

MainActivity mActivity = new MainActivity();//make sure that you pass the appropriate arguments if you have an args constructor
mActivity.startChronometer();

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 startChronometer(){
        ...
    }
}

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.startChronometer();
    }
}

I would suggest, one should not make object of an Activity type class.

MainActivity mActivity = new MainActivity();  // BIG NO TO THIS.

All Activities in Android must go through the Activity lifecycle so that they have a valid context attached to them.

By treating an Activity as a normal Java class, you end up with a null context. As most methods in an Activity are called on its Context, you will get a null pointer exception, which is why your app crashes.

Instead, move all such methods which need to be called from other classes into a Utility class which accepts a valid context in its constructor, and then use that context in the methods to do the work.


You can easily call a method from any Fragment inside your Activity by doing a cast like this:

Java

((MainActivity)getActivity()).startChronometer();

Kotlin

(activity as MainActivity).startChronometer()

Just remember to make sure this Fragment's activity is in fact MainActivity before you do it.

Hope this helps!


Initialize it first

MainActivity mActivity= new MainActivity();

Then you can continue

mActivity.startChronometer();

What i have done and it works is create an instance in the MainActivity and getter for that instance:

 public class MainActivity extends AbstractMainActivity {
    private static MainActivity mInstanceActivity;
    public static MainActivity getmInstanceActivity() {
    return mInstanceActivity;
    }

And the in the onCreate method just point to that activity:

@Override
protected void onCreate(Bundle savedInstanceState) {
mInstanceActivity = this;
}

And in onDestroy you should set this instance to null:

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

Later you can call every method in whatever class you want:

MainActivity.getmInstanceActivity().yourMethod();

What I have done with no memory leaks or lint warnings is to use @f.trajkovski's method, but instead of using MainActivity, use WeakReference<MainActivity> instead.

public class MainActivity extends AppCompatActivity {
public static WeakReference<MainActivity> weakActivity;
// etc..
 public static MainActivity getmInstanceActivity() {
    return weakActivity.get();
}
}

Then in MainActivity OnCreate()

weakActivity = new WeakReference<>(MainActivity.this);

Then in another class

MainActivity.getmInstanceActivity().yourMethod();

Works like a charm


Simply, You can make this method static as below:

public static void startChronometer(){
    mChronometer.start();
    showElapsedTime();
} 

you can call this function in other class as below:

MainActivity.startChronometer();