як викликати метод у MainActivity з іншого класу?

Як викликати метод startChronometer в інший клас, коли метод оголошений всередині основної діяльності?

Всередині основної активності:

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

Всередині іншого класу я спробував це зробити:

MainActivity mActivity;
mActivity.startChronometer();

Але сталася помилка, яка говорить

java.lang.NullPointerException.

Чи можу я знати, що ще потрібно додати до коду?

9
Але ви впевнені, що ви не називаєте неактивні функції?
додано Автор Pankaj Kumar, джерело
Ось чому я запитував, якщо ви виконуєте якесь неактивне завдання чи ні. тут знову ви отримаєте NPE для mChronometer . Тому треба думати про це
додано Автор Pankaj Kumar, джерело
MainActivity mActivity = new MainActivity (); mActivity.startChronometer ();
додано Автор Pankaj Kumar, джерело
@ laalto Так ви правильні З тієї ж причини я намагався переконатись у свій другий коментар. Часом це трапляється, багато розробників написали звичайний клас і пишемо ім'я з активністю postfix. Дякую за ваш коментар :)
додано Автор Pankaj Kumar, джерело
@PankajKumar FWIW, майже ніколи не рекомендується використовувати new з класами активності, включаючи цей випадок. (Так, старий пост, який сьогодні був активний, коли хтось публікує нову відповідь).
додано Автор laalto, джерело
Ви повинні мати клас активності лише для цілей, пов'язаних з діяльністю. Будь ласка, визначте стандартні класи для будь-яких інших цілей, таких як хронометри. Потім використовуйте ці класи всередині вашої діяльності так само, як вам потрібно @ shannon
додано Автор STT LCU, джерело
Те, що ви намагаєтесь зробити, підкачує поганий дизайн і тісний зв'язок.
додано Автор STT LCU, джерело
Я зробив MainActivity mActivity = new MainActivity (); mActivity.startChronometer (); але це також не працює. @PankajKumar
додано Автор shannon, джерело
Чи можу я знати, як я можу поліпшити її? Що є кращим способом досягнення такого ж результату? @ STTLCU
додано Автор shannon, джерело
Так, це завдання без активності. Як я можу викликати неактивну задачу? @PankajKumar
додано Автор shannon, джерело

10 Відповіді

Ви можете легко викликати метод з будь-якого фрагмента всередині вашої діяльності, просто виконавши такі дії:

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

Сподіваюся, це допомагає!

13
додано
Це має бути відповіддю ..
додано Автор Madushan Perera, джерело
Відмінна робота Рікардо ... Я вітаю тебе, мій друг !!!
додано Автор risefire, джерело

Я хотів би запропонувати, не слід створювати об'єкт класу типу діяльності.

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

Усі дії в ОС Android повинні проходити через життєвий цикл активності, щоб вони мали дійсний контекст, який до них приєднується.

Якщо ви розглядаєте діяльність як звичайний клас Java, ви отримаєте нульовий контекст. Оскільки більшість методів у діяльності називаються в його контексті, ви отримаєте виняток нульового покажчика, тому ваш додаток збігає.

Замість цього перемістіть всі такі методи, які потрібно викликати з інших класів, у клас Утиліти, який приймає в конструкторі дійсний контекст, а потім використовуйте цей контекст у методах для виконання роботи.

8
додано
Я згоден. Це забезпечує гарне відокремлення компонентів коду. Що я роблю, це забезпечити інтерфейс, який реалізується основною діяльністю, і переданий іншим діям або потокам у їх конструкторів. Це робить тестування пристроїв набагато простішим, оскільки тестовий код може забезпечити один і той самий інтерфейс, не докладаючи його до певної реалізації.
додано Автор orodbhen, джерело

Ініціалізувати його спочатку

MainActivity mActivity= new MainActivity();

Тоді ти можеш продовжувати

mActivity.startChronometer();
8
додано
@laalto Ви маєте поставити свою ідею прямо в розділі коментарів у питанні, оскільки є коментар, який саме ініціювати можна за допомогою new
додано Автор Ruchira Gayan Ranaweera, джерело
@ laalto ahh really .. Я не подивився на них.
додано Автор Ruchira Gayan Ranaweera, джерело
@PankajKumar Вибачте, хто спочатку дає відповідь?
додано Автор Ruchira Gayan Ranaweera, джерело
@ laalto я ніколи не займався андроїдом. Це лише натяк для ініціалізації mActivity для аферу NPE . Ви можете його ініціалізувати належним чином.
додано Автор Ruchira Gayan Ranaweera, джерело
замість того, щоб дати таку ж нову відповідь, ви можете відновити існуючий. Правильно?
додано Автор Pankaj Kumar, джерело
Є буквально десятки андроїдових запитань, які публікуються кожен день, коли коренева проблема є екземпляром активності з new . Такі заходи не є корисними для чого, оскільки вони насправді ініціалізуються. Тому пропозиції щодо використання new у цьому контексті є поганими.
додано Автор laalto, джерело
FWIW, ніколи не показує класи активності за допомогою new .
додано Автор laalto, джерело

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();
}
6
додано

Але сталася помилка, яка говорить про java.lang.NullPointerException.

Це тому, що ви ніколи не ініціалізували свою основну активність. ви повинні ініціалізувати свій об'єкт, перш ніж називати його методами.

MainActivity mActivity = new MainActivity();//make sure that you pass the appropriate arguments if you have an args constructor
mActivity.startChronometer();
3
додано
Дії не мають конструкторів з аргументами! Якщо визначено, щось робиться неправильно
додано Автор cricket_007, джерело
FWIW, ніколи не показує класи активності за допомогою new .
додано Автор laalto, джерело

Ви можете зробити цей метод статичним.

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

ви можете викликати цю функцію в іншому класі, як показано нижче:

MainActivity.startChronometer();

АБО

Ви можете зробити об'єкт основного класу у другому класі, як, наприклад,

MainActivity mActivity = new MainActivity();
mActivity.startChronometer();
2
додано
замість того, щоб дати таку ж нову відповідь, ви можете відновити існуючий. Правильно?
додано Автор Pankaj Kumar, джерело
FWIW, ніколи не показує класи активності за допомогою new .
додано Автор laalto, джерело
М-хронометр, здається, є приватною власністю майнової діяльності. Це не спрацює, якщо mChronometer не є статичним.
додано Автор STT LCU, джерело

Використовуйте цей код у фрагменті MainActivity , щоб викликати на нього метод.

((MainActivity) getActivity()).startChronometer();
2
додано
Найкраща відповідь я знайшла !!! Дякую
додано Автор Maksim Kniazev, джерело

Просто Ви можете зробити цей метод статичним, як показано нижче:

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

ви можете викликати цю функцію в іншому класі, як показано нижче:

MainActivity.startChronometer();
1
додано
mChronometer має бути статичним, а не прив'язаним до екземпляру класу, в якому існує об'єкт ... Downvote
додано Автор cricket_007, джерело
замість того, щоб дати таку ж нову відповідь, ви можете відновити існуючий. Правильно?
додано Автор Pankaj Kumar, джерело

Що я зробив, і це працює, є створення примірника в MainActivity і getter для цього прикладу:

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

І в методі onCreate просто вкажіть на цю активність:

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

І в onDestroy ви повинні встановити цей екземпляр на нуль:

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

Пізніше ви можете викликати кожен метод будь-якого класу, який ви хочете:

MainActivity.getmInstanceActivity().yourMethod();
0
додано
Якщо вашою основною діяльністю, можливо, буде добре, оскільки воно продовжуватиме використовуватися під час використання додатка, але це все ще погана практика. Існує досить багато матеріалу, де пояснюється, чому зберігання статичних контекстних посилань є поганим, я все ще підкорююся на предмет самостійно
додано Автор Tssomas, джерело
додано Автор Tssomas, джерело
Я використовував це в класах без активності, але я мав враження, що зберігання об'єкта дії є поганим. Ви також отримаєте помилку lint про це з студією Android, якщо ви зберігаєте об'єкт активності.
додано Автор Tssomas, джерело
Це призведе до витоку пам'яті та припиненні миттєвого запуску
додано Автор Tssomas, джерело
Я використовував це в трьох додатках, що знаходяться у виробництві, і немає ніяких витоків пам'яті або перерв миттєвого запуску. Ви створюєте посилання, щоб вказати на об'єкт, як це може призвести до витоку пам'яті? Ви протестували це?
додано Автор f.trajkovski, джерело
Я не отримую частини: зберігання активності об'єкта погано. У цьому сценарії Android створює об'єкт, за допомогою цього коду ви просто створюєте посилання, яке вказуватиме на цей об'єкт. Не має значення, де ви використовуєте його, поки активна діяльність. З цієї причини я зазвичай перевіряю, чи активна активність чи ні.
додано Автор f.trajkovski, джерело
Дякуємо за цю інформацію, в основному те, що потрібно додати в цьому сценарії, полягає в тому, щоб встановити цей екземпляр на нуль на onDestroy.
додано Автор f.trajkovski, джерело

Ви повинні передати екземпляр MainActivity в інший клас, після чого ви можете викликати всю публіку (в MainActivity) звідусіль.

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();
    }
}
0
додано
Я маю на увазі, як ви називатимете ((MainActivity) контекст) startChronometer (); у своєму AnotherClass ?
додано Автор Yupi, джерело
Ви можете викликати методи або поля з Activity в іншому класі, подібному до цього: ((MainActivity) контексті) startChronometer (); , але як ви розумієте, як запустити цей метод у своєму користувальницькому клас
додано Автор Yupi, джерело
На жаль, я не знаю, чи я повністю розумію ваше запитання. Ви кажете, що я можу викликати метод MainActivity за його контекстом, але все-таки ви маєте передати цей контекст так, як посилання на екземпляр MainActivity за допомогою "цього" при виклику конструктора AnotherClass. Отже, я припускаю, той же підхід. Тоді виникає питання, як я буду планувати викликати (викликати) цей метод (startChronometer?) У моєму рішенні (в AnotherClass). Тому моя відповідь полягає в тому, що я зателефоную цьому методу за допомогою mainActivity.startChronometer (); Чи правильно я це розумію? Дякую за вашу посаду :)
додано Автор Tmthetom, джерело
Той же спосіб, як ти. Ви просто повторюєте контекст для MainActivity, iam використовуючи MainActivity від початку, так що мені не потрібно повторювати як ти. mainActivity.startChronometer ();
додано Автор Tmthetom, джерело
ІТ КПІ - Java
ІТ КПІ - Java
436 учасників

android_jobs_ua
android_jobs_ua
120 учасників

Публикуем вакансии и запросы на поиск работы по направлению Android. Здесь всё: full-time, part-time, remote и разовые подработки.

Mobile Dev Jobs UA
Mobile Dev Jobs UA
20 учасників

Публикуем вакансии и запросы на поиск работы по направлению iOS, Android, Xamarin, RN и т.д.