25

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?

Vasilis G.
  • 7,556
  • 4
  • 19
  • 29
shannon
  • 579
  • 2
  • 10
  • 22
  • 7
    `MainActivity mActivity = new MainActivity(); mActivity.startChronometer();` – Pankaj Kumar Jun 26 '13 at 09:08
  • But are you sure you are not calling non-activity functions? – Pankaj Kumar Jun 26 '13 at 09:09
  • I did MainActivity mActivity = new MainActivity(); mActivity.startChronometer(); but it doesn't work too. @PankajKumar – shannon Jun 26 '13 at 09:55
  • May I know how can I improve on it? What is a better way of achieving the same result? @STTLCU – shannon Jun 26 '13 at 09:57
  • 1
    thats the reason I was asking about if you are doing some non-activity task or not. here again you will get NPE for `mChronometer`. So you should think about it – Pankaj Kumar Jun 26 '13 at 10:02
  • Yes it's a non-activity task. How can I call a non-activity task then? @PankajKumar – shannon Jun 26 '13 at 10:27
  • 1
    You should have activity classes only for activity related purposes. Please define standard classes for any non-activity purposes, like chronometers. Then use those classes inside your activity as much as you need @shannon – STT LCU Jun 26 '13 at 10:30
  • 2
    @PankajKumar FWIW, it's almost never a good idea to use `new` with activity classes, including this case. (Yeah, old post, got active today by someone posting a new answer.) – laalto Aug 12 '14 at 12:42
  • @laalto Yes you are correct. Same reason I was trying to make sure into my second comment. Sometime it happens, many developer wrote normal class and write name with activity postfix. Thank you for your valuable comment :) – Pankaj Kumar Aug 12 '14 at 14:14
  • Hi @shannon! My answer https://stackoverflow.com/a/25260557/3767765 seems to be helping a lot of people even though it isn't the accepted answer. Can you accept it, please? – RicardoSousaDev Mar 14 '19 at 14:42

12 Answers12

42

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!

RicardoSousaDev
  • 893
  • 9
  • 9
  • 14
    This doesn't answer the question. Not from FRAGMENT, but from another ACTIVITY class. – ekashking Jun 15 '19 at 20:26
  • I see your point but you should never call an Activity from another Activity class @ekashking, it would lead to memory leaks if you do it. At most you can have an observer pattern to update an Activity that's not on screen. – RicardoSousaDev Jun 17 '19 at 10:39
30

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();
}
Ahamadullah Saikat
  • 4,437
  • 42
  • 39
15

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

Steve Marcus
  • 199
  • 1
  • 9
4

Initialize it first

MainActivity mActivity= new MainActivity();

Then you can continue

mActivity.startChronometer();
Ruchira Gayan Ranaweera
  • 34,993
  • 17
  • 75
  • 115
3

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

((MainActivity) getActivity()).startChronometer();
OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
Akash Arora
  • 71
  • 1
  • 14
3

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();
    }
}
Tmthetom
  • 69
  • 3
  • You can call methods or fields from `Activity` in another class like this: `((MainActivity)context)startChronometer();` but how do you plain to triger that method in your custom class? – Yupi Nov 08 '17 at 17:14
  • Sorry, iam not sure if i fully understand your question. You are saying, that i can call method of MainActivity by its context, but still, you need to pass that context just like MainActivity instance reference by "this" when calling constructor of AnotherClass. So i assume, its same approach. Then there is question how do i plan to trigger (call) that method (startChronometer?) in my solution (in AnotherClass). So my answer is, i will call that method by mainActivity.startChronometer(); Do I understand it correctly? Thank you for yours post :) – Tmthetom Nov 09 '17 at 20:42
  • I mean how do you gonna call `((MainActivity)context)startChronometer();` in your `AnotherClass`? – Yupi Nov 09 '17 at 20:55
  • Same way like you. You are just retyping context to MainActivity, iam using MainActivity from start, so i dont need to retype like you. mainActivity.startChronometer(); – Tmthetom Nov 10 '17 at 21:31
2

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();
f.trajkovski
  • 794
  • 9
  • 24
  • 1
    This will cause memory leaks and break instant run – Tssomas Mar 04 '18 at 20:37
  • I have used this on three applications which are in production now and there is no memory leaks or break instant run. You are creating a reference to point to a object how can this cause memory leak? Have you tested it ? – f.trajkovski Mar 05 '18 at 10:20
  • I have used this in non-activity classes but I was under the impression storing an activity object is bad. You also get a lint error saying this with android studio if you store an activity object. – Tssomas Mar 05 '18 at 12:27
  • I don't get the part: storing an activity object is bad. In this scenario android is creating the object, with this code you are just creating a reference that will point to that object. It doesn't matter where you are using it until the activity is alive. For that reason usually I am checking if the activity is alive or not. – f.trajkovski Mar 05 '18 at 14:43
  • If its your main activity perhaps it would be okay because it will continue to be used while the app is being used, but its still bad practice. There is quite a lot of material out there explaining why storing static context references is bad, im still getting up to scratch on the subject myself – Tssomas Mar 05 '18 at 16:04
  • Thanks for that information, basically what needs to be added in this scenario is to set this instance to null in onDestroy. – f.trajkovski Mar 06 '18 at 10:30
1

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();
PermGenError
  • 45,977
  • 8
  • 87
  • 106
0

In Kotlin, if passing MainActivity as a Context into a fragment, you can also do:

(context as MainActivity).startChronometer()

to cast context to MainActivity and before using it.

Raymo111
  • 514
  • 8
  • 24
-1

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();
Avadhani Y
  • 7,566
  • 19
  • 63
  • 90
-1

Easy method

Use "static" keyword just like this

public static void startChronometer()
{
  // Your code
}

Then call method from your other class like this

MainActivity.startChronometer();

Hope this work thank you

Giuseppe Garassino
  • 2,272
  • 1
  • 27
  • 47
  • Please provide additional details in your answer. As it's currently written, it's hard to understand your solution. – Community Sep 01 '21 at 19:02
-3

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();
Muhammad Aamir Ali
  • 20,419
  • 10
  • 66
  • 57