Есть ли простой способ определить, активна ли какая-либо деятельность? Я хочу делать определенные вещи в зависимости от активности. например:
if(activityrunning == activity1)
//do this
else if (activityrunning == activity2)
//do something else
Есть ли простой способ определить, активна ли какая-либо деятельность? Я хочу делать определенные вещи в зависимости от активности. например:
if(activityrunning == activity1)
//do this
else if (activityrunning == activity2)
//do something else
В операции можно использовать переменную static
.
class MyActivity extends Activity {
static boolean active = false;
@Override
public void onStart() {
super.onStart();
active = true;
}
@Override
public void onStop() {
super.onStop();
active = false;
}
}
Единственная проблема заключается в том, что если вы используете ее в двух действиях, которые ссылаются друг на друга, тогда onStop
на первом иногда вызывается после onStart
во втором. Таким образом, оба момента могут быть верными.
В зависимости от того, что вы пытаетесь сделать (обновить текущую активность от службы?). Вы можете просто зарегистрировать статический прослушиватель в службе в вашем действии onStart
, тогда правильный слушатель будет доступен, когда ваша служба хочет обновить интерфейс.
Мне кажется более понятным:
public boolean isRunning(Context ctx) {
ActivityManager activityManager = (ActivityManager) ctx.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningTaskInfo> tasks = activityManager.getRunningTasks(Integer.MAX_VALUE);
for (RunningTaskInfo task : tasks) {
if (ctx.getPackageName().equalsIgnoreCase(task.baseActivity.getPackageName()))
return true;
}
return false;
}
Опция без использования какой-либо вспомогательной переменной:
activity.getWindow().getDecorView().getRootView().isShown()
где действует fe: this или getActivity().
Значение, возвращаемое этим выражением, изменяется в onStart()/onStop(), которые являются событиями, которые запускают/останавливают показ макета активности на телефоне.
Я использовал метод MyActivity.class и getCanonicalName, и я получил ответ.
protected Boolean isActivityRunning(Class activityClass)
{
ActivityManager activityManager = (ActivityManager) getBaseContext().getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> tasks = activityManager.getRunningTasks(Integer.MAX_VALUE);
for (ActivityManager.RunningTaskInfo task : tasks) {
if (activityClass.getCanonicalName().equalsIgnoreCase(task.baseActivity.getClassName()))
return true;
}
return false;
}
Намного лучше, чем использование статической переменной и последующего ООП
Shared Preferences
можно использовать для обмена переменными с другими activities
и службами с одного application
public class example extends Activity {
@Override
protected void onStart() {
super.onStart();
// Store our shared preference
SharedPreferences sp = getSharedPreferences("OURINFO", MODE_PRIVATE);
Editor ed = sp.edit();
ed.putBoolean("active", true);
ed.commit();
}
@Override
protected void onStop() {
super.onStop();
// Store our shared preference
SharedPreferences sp = getSharedPreferences("OURINFO", MODE_PRIVATE);
Editor ed = sp.edit();
ed.putBoolean("active", false);
ed.commit();
}
}
Используйте общие настройки. Он имеет самую надежную информацию о состоянии, меньше проблем с коммутацией/уничтожением приложений, избавляет нас от запроса еще одного разрешения, и это дает нам больше контроля, чтобы решить, когда наша деятельность на самом деле самая верхняя. см. подробности здесь abd здесь также
Это код для проверки того, работает ли конкретная служба. Я уверен, что он может работать и на активность, пока вы меняете getRunningServices с помощью getRunningAppProcesses() или getRunningTasks(). Посмотрите здесь http://developer.android.com/reference/android/app/ActivityManager.html#getRunningAppProcesses()
Измените Constants.PACKAGE и Constants.BACKGROUND_SERVICE_CLASS соответственно
public static boolean isServiceRunning(Context context) {
Log.i(TAG, "Checking if service is running");
ActivityManager activityManager = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningServiceInfo> services = activityManager.getRunningServices(Integer.MAX_VALUE);
boolean isServiceFound = false;
for (int i = 0; i < services.size(); i++) {
if (Constants.PACKAGE.equals(services.get(i).service.getPackageName())){
if (Constants.BACKGROUND_SERVICE_CLASS.equals(services.get(i).service.getClassName())){
isServiceFound = true;
}
}
}
Log.i(TAG, "Service was" + (isServiceFound ? "" : " not") + " running");
return isServiceFound;
}
спасибо kkudi! Я смог адаптировать свой ответ для работы для своей деятельности... вот что сработало в моем приложении.
public boolean isServiceRunning() {
ActivityManager activityManager = (ActivityManager)Monitor.this.getSystemService (Context.ACTIVITY_SERVICE);
List<RunningTaskInfo> services = activityManager.getRunningTasks(Integer.MAX_VALUE);
isServiceFound = false;
for (int i = 0; i < services.size(); i++) {
if (services.get(i).topActivity.toString().equalsIgnoreCase("ComponentInfo{com.lyo.AutoMessage/com.lyo.AutoMessage.TextLogList}")) {
isServiceFound = true;
}
}
return isServiceFound;
}
этот пример предоставит вам true или false, если topActivity соответствует тому, что делает пользователь. Поэтому, если действие, которое ваша проверка не отображается (т.е. OnPause), вы не получите соответствия. Кроме того, для этого вам нужно добавить разрешение на манифест.
<uses-permission android:name="android.permission.GET_TASKS"/>
Я надеюсь, что это было полезно!
Я думаю, что принятый ответ - ужасный способ справиться с этим.
Я не знаю, что такое вариант использования, но, пожалуйста, рассмотрите защищенный метод в базовом классе
@protected
void doSomething() {
}
и переопределить его в производном классе.
Когда событие происходит, просто вызовите этот метод в базовом классе. Тогда правильный "активный" класс будет обрабатывать. Сам класс может проверить, не является ли это Paused()
.
Еще лучше использовать шину событий, например GreenRobot, Square, но этот устарел и предлагает использовать RxJava
Я понимаю, что эта проблема довольно старая, но я думаю, что все же стоит поделиться своим решением, поскольку это может быть полезно для других.
Это решение не было доступно до выпуска компонентов архитектуры Android.
Активность хотя бы частично видна
getLifecycle().getCurrentState().isAtLeast(STARTED)
Деятельность на переднем плане
getLifecycle().getCurrentState().isAtLeast(RESUMED)
Существует намного более простой способ, чем все выше, и этот подход не требует использования android.permission.GET_TASKS
в манифесте или проблемы с условиями гонки или утечками памяти, отмеченными в принятом ответе.
Сделайте переменную STATIC в основной деятельности. Static позволяет другим действиям получать данные из другой активности. onPause()
установите эту переменную false, onResume
и onCreate()
установите эту переменную true.
private static boolean mainActivityIsOpen;
Назначьте геттеры и сеттеры этой переменной.
public static boolean mainActivityIsOpen() {
return mainActivityIsOpen;
}
public static void mainActivityIsOpen(boolean mainActivityIsOpen) {
DayView.mainActivityIsOpen = mainActivityIsOpen;
}
И затем из другого действия или службы
if (MainActivity.mainActivityIsOpen() == false)
{
//do something
}
else if(MainActivity.mainActivityIsOpen() == true)
{//or just else. . . ( or else if, does't matter)
//do something
}
if(!activity.isFinishing() && !activity.isDestroyed())
Из официальных документов:
Проверьте, находится ли это действие в процессе завершения, потому что вы вызвали на нем метод finish() или кто-то еще запросил его завершение. Это часто используется в onPause(), чтобы определить, просто ли действие приостанавливается или полностью завершается.
Возвращает true, если последний вызов onDestroy() был сделан для Activity, поэтому этот экземпляр теперь мертв.
Я использовал чек if (!a.isFinishing())
, и он, похоже, делает то, что мне нужно. a
- это экземпляр действия. Это неверно? Почему никто не попробовал это?
ActivityLifecycleCallbacks - отличный способ отслеживать все действия в приложении:
public class BaseActivityLifecycleCallbacks implements Application.ActivityLifecycleCallbacks {
private ActivityState homeState, contentState;
@Override
public void onActivityCreated(Activity activity, Bundle bundle) {
if (activity instanceof HomeActivityv2) {
homeState = ActivityState.CREATED;
} else if (activity instanceof ContentDisplayActivity) {
contentState = ActivityState.CREATED;
}
}
@Override
public void onActivityStarted(Activity activity) {
if (activity instanceof HomeActivityv2) {
homeState = ActivityState.STARTED;
} else if (activity instanceof ContentDisplayActivity) {
contentState = ActivityState.STARTED;
}
}
@Override
public void onActivityResumed(Activity activity) {
if (activity instanceof HomeActivityv2) {
homeState = ActivityState.RESUMED;
} else if (activity instanceof ContentDisplayActivity) {
contentState = ActivityState.RESUMED;
}
}
@Override
public void onActivityPaused(Activity activity) {
if (activity instanceof HomeActivityv2) {
homeState = ActivityState.PAUSED;
} else if (activity instanceof ContentDisplayActivity) {
contentState = ActivityState.PAUSED;
}
}
@Override
public void onActivityStopped(Activity activity) {
if (activity instanceof HomeActivityv2) {
homeState = ActivityState.STOPPED;
} else if (activity instanceof ContentDisplayActivity) {
contentState = ActivityState.STOPPED;
}
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
}
@Override
public void onActivityDestroyed(Activity activity) {
if (activity instanceof HomeActivityv2) {
homeState = ActivityState.DESTROYED;
} else if (activity instanceof ContentDisplayActivity) {
contentState = ActivityState.DESTROYED;
}
}
public ActivityState getHomeState() {
return homeState;
}
public ActivityState getContentState() {
return contentState;
}
}
ActivityState:
public enum ActivityState {
CREATED, STARTED, RESUMED, PAUSED, STOPPED, DESTROYED;
}
Расширьте класс Application и предоставьте его ссылку в файле Android Manifest:
import android.app.Application;
public final class BaseApplication extends Application {
private BaseActivityLifecycleCallbacks baseALC;
@Override
public void onCreate() {
super.onCreate();
baseALC = new BaseActivityLifecycleCallbacks();
this.registerActivityLifecycleCallbacks(baseALC);
}
public BaseActivityLifecycleCallbacks getBaseALC() {
return baseALC;
}
}
Нажмите в любом месте Activity для статуса другой активности:
private void checkAndLaunchHomeScreen() {
Application application = getApplication();
if (application instanceof BaseApplication) {
BaseApplication baseApplication = (BaseApplication) application;
if (baseApplication.getBaseALC().getHomeState() == null || baseApplication.getBaseALC().getHomeState() == ActivityState.DESTROYED) {
//Do anything you want
}
}
}
https://developer.android.com/reference/android/app/Application.ActivityLifecycleCallbacks.html
как насчет activity.isFinishing()
Не уверен, что это "правильный" способ "делать что-то".
Если нет пути API для решения (или) вопроса, чем вы должны думать немного, возможно, вы делаете что-то неправильно и читаете больше документов и т.д.
(Как я понял, статические переменные являются обычно неправильным способом в android. Из-за этого он может работать, но определенно будут случаи, когда он не будет работать (например, в производстве, на миллионах устройств)).
Именно в вашем случае я предлагаю подумать, почему вам нужно знать, жив ли другой актив?.. вы можете начать другое действие для получения результата, чтобы получить его функциональность. Или вы можете получить класс, чтобы получить его функциональность и т.д.
С наилучшими пожеланиями.
Если вас интересует состояние жизненного цикла конкретного экземпляра активности, решение силикона выглядит корректно, за исключением того, что новая "активная" переменная должна быть переменной экземпляра, а не статикой.
Используйте упорядоченную трансляцию. См. http://android-developers.blogspot.nl/2011/01/processing-ordered-broadcasts.html
В своей деятельности зарегистрируйте приемник в onStart, отмените регистрацию в onStop. Теперь, когда, например, служба должна обрабатывать то, что активность может быть лучше, отправить упорядоченную трансляцию из службы (с помощью обработчика по умолчанию в самой службе). Теперь вы можете отвечать на действия, когда они запущены. Служба может проверять данные результата, чтобы посмотреть, была ли обработана трансляция, и если не предпринять соответствующие действия.
В дополнение к принятому ответу, если у вас есть несколько экземпляров активности, вы можете использовать счетчик вместо:
class MyActivity extends Activity {
static int activeInstances = 0;
static boolean isActive() {
return (activeInstance > 0)
}
@Override
public void onStart() {
super.onStart();
activeInstances++;
}
@Override
public void onStop() {
super.onStop();
activeInstances--;
}
}
Ты пытался..
if (getActivity() instanceof NameOfYourActivity){
//Do something
}
Обнаружено легкое обходное решение со следующим кодом
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if ((getIntent().getFlags() & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != 0) {
// Activity is being brought to front and not being created again,
// Thus finishing this activity will bring the last viewed activity to foreground
finish();
}
}
Используйте переменную isActivity, чтобы проверить, активна ли активность или нет.
private boolean activityState = true;
@Override
protected void onDestroy() {
super.onDestroy();
activityState = false;
}
Тогда проверь
if(activityState){
//add your code
}
Эта работа, если у вас нет такой же активности на переднем плане. Если вы открываете уведомление, не работайте, я сделал некоторые настройки и пришел с этим:
public static boolean ativo = false;
public static int counter = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
counter++;
}
@Override
protected void onStart() {
super.onStart();
ativo = true;
}
@Override
protected void onStop() {
super.onStop();
if (counter==1) ativo = false;
}
@Override
protected void onDestroy() {
counter--;
super.onDestroy();
}
Это работает для меня одновременно с несколькими действиями.