IT

Android : 활동이 실행 중인지 어떻게 확인합니까?

lottoking 2020. 6. 25. 07:45
반응형

Android : 활동이 실행 중인지 어떻게 확인합니까?


특정 활동이 활동 중인지 여부를 결정하는 간단한 방법이 있습니까? 활동중인 활동에 따라 특정 작업을 수행하고 싶습니다. 예 :

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메소드 의 서비스에 정적 리스너를 등록하면 서비스가 UI를 업데이트하려고 할 때 올바른 리스너를 사용할 수 있습니다.


나는 더 분명하게 생각합니다.

  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;
}

정적 변수를 사용하고 OOP를 따르는 것보다 훨씬 좋은 방법

Shared Preferencesactivities하나의 다른 서비스 및 서비스 와 변수를 공유하는 데 사용할 수 있습니다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를 여기


특정 서비스가 실행 중인지 확인하기위한 코드입니다. getRunningAppProcesses () 또는 getRunningTasks ()를 사용하여 getRunningServices를 변경하는 한 활동에 대해서도 작동 할 수 있다고 확신합니다. 여기 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; 
} 

이 예제는 topActivity가 사용자의 작업과 일치하는 경우 true 또는 false를 제공합니다. 따라서 확인한 활동이 표시되지 않는 경우 (즉, onPause) 일치하지 않습니다. 또한 이렇게하려면 매니페스트에 권한을 추가해야합니다.

<uses-permission  android:name="android.permission.GET_TASKS"/>

도움이 되었기를 바랍니다.


나는 받아 들인 대답이 이것을 처리하는 끔찍한 방법이라고 생각합니다.

유스 케이스가 무엇인지 모르지만 기본 클래스의 보호 된 메소드를 고려하십시오

@protected
void doSomething() {
}

파생 클래스에서 재정의합니다.

이벤트가 발생하면 기본 클래스에서이 메소드를 호출하십시오. 올바른 'active'클래스가 처리합니다. 그런 다음 클래스 자체가 아닌지 확인할 수 있습니다 Paused().

더 나은 방법은 GreenRobot 's , Square ' s 와 같은 이벤트 버스를 사용하는 것이지만 더 이상 사용되지 않으며 RxJava 사용을 제안합니다.


나는이 문제가 꽤 오래되었다는 것을 알고 있지만 다른 사람들에게 유용 할 수 있으므로 여전히 솔루션을 공유 할 가치가 있다고 생각합니다.

이 솔루션은 Android Architecture Components가 출시되기 전에는 사용할 수 없었습니다.

활동이 적어도 부분적으로 보입니다

getLifecycle().getCurrentState().isAtLeast(STARTED)

활동은 전경에 있습니다

getLifecycle().getCurrentState().isAtLeast(RESUMED)

위의 모든 것보다 훨씬 쉬운 방법이 있으며이 방법 android.permission.GET_TASKS은 매니페스트에서 사용할 필요가 없으며 허용되는 답변에서 경쟁 조건 또는 메모리 누수 문제가 지적되었습니다.

  1. 기본 활동에서 STATIC 변수를 작성하십시오. 정적은 다른 활동이 다른 활동으로부터 데이터를 수신 할 수있게합니다. onPause()이 변수를 설정 거짓을 , onResume그리고 onCreate()이 변수로 설정 사실을 .

    private static boolean mainActivityIsOpen;
    
  2. 이 변수의 getter 및 setter를 지정하십시오.

    public static boolean mainActivityIsOpen() {
        return mainActivityIsOpen;
    }
    
    public static void mainActivityIsOpen(boolean mainActivityIsOpen) {
        DayView.mainActivityIsOpen = mainActivityIsOpen;
    }
    
  3. 그런 다음 다른 활동이나 서비스에서

    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())

공식 문서에서 :

활동 #isFinishing ()

finish ()를 호출했거나 다른 사람이 완료를 요청했기 때문에이 활동이 완료 중인지 확인하십시오. 이것은 종종 onPause ()에서 활동이 단순히 일시 중지되었는지 또는 완전히 마무리되는지를 결정하는 데 사용됩니다.

활동 # isDestroyed ()

Activity에서 최종 onDestroy () 호출이 수행되었으므로이 인스턴스가 현재 종료 된 경우 true를 리턴합니다.


나는 수표를 사용했고 if (!a.isFinishing())내가 필요한 것을하는 것처럼 보인다. a활동 인스턴스입니다. 이것이 맞지 않습니까? 아무도 이것을 시도하지 않은 이유는 무엇입니까?


이건 어떤가요 activity.isFinishing()


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;
}
}

다른 활동 상태에 대한 활동 어디에서나 Ckeck :

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


Not sure it is a "proper" way to "do things".
If there's no API way to resolve the (or a) question than you should think a little, maybe you're doing something wrong and read more docs instead etc.
(As I understood static variables is a commonly wrong way in android. Of cause it could work, but there definitely will be cases when it wont work[for example, in production, on million devices]).
Exactly in your case I suggest to think why do you need to know if another activity is alive?.. you can start another activity for result to get its functionality. Or you can derive the class to obtain its functionality and so on.
Best Regards.


If you are interested in the lifecycle state of the specific instance of the activity, siliconeagle's solution looks correct except that the new "active" variable should be an instance variable, rather than static.


Use an ordered broadcast. See http://android-developers.blogspot.nl/2011/01/processing-ordered-broadcasts.html

In your activity, register a receiver in onStart, unregister in onStop. Now when for example a service needs to handle something that the activity might be able to do better, send an ordered broadcast from the service (with a default handler in the service itself). You can now respond in the activity when it is running. The service can check the result data to see if the broadcast was handled, and if not take appropriate action.


In addition to the accepted answer, if you have multiple instances of the activity, you can use a counter instead:

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--;
      }
}

Have you tried..

    if (getActivity() instanceof NameOfYourActivity){
        //Do something
    }

Found an easy workaround with the following code

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

Use the isActivity variable to check if activity is alive or not.

private boolean activityState = true;

 @Override
protected void onDestroy() {
    super.onDestroy();
    activityState = false;
}

Then check

if(activityState){
//add your code
}

This work if you don't have the same activity in foreground. If you open from notification don't work i made some adjustments and came with this:

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

That works for me with several activitys open at the same time.

참고URL : https://stackoverflow.com/questions/5446565/android-how-do-i-check-if-activity-is-running

반응형