안드로이드에서 현재 전경 활동 컨텍스트를 얻는 방법?


171

내 방송이 실행될 때마다 포 그라운드 활동에 경고를 표시하고 싶습니다.


활동의 컨텍스트를 얻으려는 위치에서. 앱 활동 또는 다른 애플리케이션일까요?
AAnkit

이것은 앱 활동입니다. broadcastreceiver onreceive () 함수에서 경고 대화 상자 코딩을 수행했습니다.
Deepali

앱 활동! 이 앱입니까? 왜 그런지 원하는 이유가 무엇이든간에 같은 대안이있을 수 있습니다.
AAnkit

포 그라운드 활동에 경고를 표시하고 싶습니다. 컨텍스트없이 포 그라운드 활동에 경고를 표시하는 다른 방법입니다.
Deepali

1
수신시에만 COntext를 매개 변수로 사용하면 context.getApplicationContext ()
AAnkit

답변:


39

알면 ActivityManager가 관리하는 활동을 , 그래서 우리는 정보 얻을 수 ActivityManager를 . 우리는 현재 포 그라운드에서 활동을 실행합니다.

ActivityManager am = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
ComponentName cn = am.getRunningTasks(1).get(0).topActivity;

업데이트 2018/10/03
getRunningTasks ()가 더 이상 사용되지 않습니다. 아래 솔루션을 참조하십시오.

이 메소드는 API 레벨 21에서 더 이상 사용되지 않습니다. Build.VERSION_CODES.LOLLIPOP부터이 메소드는 더 이상 써드 파티 애플리케이션에서 사용할 수 없습니다. 문서 중심의 최근 통화가 도입되면 발신자에게 개인 정보가 유출 될 수 있습니다. 이전 버전과의 호환성을 위해 최소한 발신자의 자체 작업과 민감한 것으로 알려진 집과 같은 다른 작업의 데이터의 작은 하위 집합을 반환합니다.


16
Martin은 그렇게 생각하지 않습니다. getRunningTasks의 SDK 도움말에서 Martin은 "참고 :이 방법은 작업 관리 사용자 인터페이스를 디버깅하고 표시하기위한 것입니다. 응용 프로그램의 핵심 논리에는 사용해서는 안됩니다"
ruhalde

3
분명히 이것은 Android 5 / Lollipop에서 실행중인 작업의 제한된 하위 집합 만 지원합니다.
Sam

7
ActivityManager.getRunningTasks () 문서에 "이 메소드는 API 레벨 21에서 더 이상 사용되지 않습니다"라고 표시되어 있습니다.
markshep

210

( 참고 : API 14에 공식 API가 추가되었습니다 : https://stackoverflow.com/a/29786451/119733 참조 )

이전 (waqas716) 답변을 사용하지 마십시오.

활동에 대한 정적 참조로 인해 메모리 누수 문제가 발생합니다. 자세한 내용은 다음 링크를 참조 하십시오 http://android-developers.blogspot.fr/2009/01/avoiding-memory-leaks.html

이를 피하려면 활동 참조를 관리해야합니다. 매니페스트 파일에 응용 프로그램 이름을 추가하십시오.

<application
    android:name=".MyApp"
    ....
 </application>

응용 프로그램 클래스 :

  public class MyApp extends Application {
        public void onCreate() {
              super.onCreate();
        }

        private Activity mCurrentActivity = null;
        public Activity getCurrentActivity(){
              return mCurrentActivity;
        }
        public void setCurrentActivity(Activity mCurrentActivity){
              this.mCurrentActivity = mCurrentActivity;
        }
  }

새로운 활동 만들기 :

public class MyBaseActivity extends Activity {
    protected MyApp mMyApp;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mMyApp = (MyApp)this.getApplicationContext();
    }
    protected void onResume() {
        super.onResume();
        mMyApp.setCurrentActivity(this);
    }
    protected void onPause() {
        clearReferences();
        super.onPause();
    }
    protected void onDestroy() {        
        clearReferences();
        super.onDestroy();
    }

    private void clearReferences(){
        Activity currActivity = mMyApp.getCurrentActivity();
        if (this.equals(currActivity))
            mMyApp.setCurrentActivity(null);
    }
}

따라서 활동에 대한 활동 클래스를 확장하는 대신 MyBaseActivity를 확장하십시오. 이제 응용 프로그램 또는 다음과 같은 활동 컨텍스트에서 현재 활동을 가져올 수 있습니다.

Activity currentActivity = ((MyApp)context.getApplicationContext()).getCurrentActivity();

9
WeakReference를 사용하면 적은 코드로 동일한 결과를 얻을 수 있습니다.
Nacho Coloma

5
@Nacho WeakReferencesGC는 안드로이드에서 사용하기 를 결코 권장하지 않습니다 .
초 rekire

4
@MaximKorobov 예 onCreate ()에서 finish ()를 호출하면 활동을 사용하여 다른 활동을 시작 하고이 활동을 중지하는 경우 가능합니다. 이 시나리오에서는 onPause () 및 onStoo ()를 건너 뜁니다. developer.android.com/training/basics/activity-lifecycle/…
Rodrigo Leitão

2
@rekire @NachoColoma의 사용은 WeakReference캐싱에 권장되지 않습니다. 이것은 캐싱이 아닙니다. 즉, mCurrentActivity살아있는 경우에만 참조가 있으므로의 위에는 WeakReference수집되지 않습니다 Activity. 그러나 @NachoColoma가 제안한 것은 WeakReference변수가 지워지지 않은 경우 재개되지 않은 (아무것도 아니거나 정상이 아닌) 활동을 여전히 참조 할 수 있기 때문에 잘못 되었습니다!
TWiStErRob

14
Android API 레벨 14부터 사용 Application .ActivityLifecycleCallbacks하는 것이 가능해야합니다 .이 방법은보다 중심적이며 모든 활동에 관리 코드를 추가하지 않아도됩니다. developer.android.com/reference/android/app/…
Filou

68

@gezdy의 답변 맨 위로 확장합니다.

모든 활동에서 Application수동 코딩으로 자체를 "등록"하는 대신 레벨 14 이후로 다음 API를 사용하여 수동 코딩을 줄이면서 유사한 목적을 달성 할 수 있습니다.

public void registerActivityLifecycleCallbacks (Application.ActivityLifecycleCallbacks callback)

http://developer.android.com/reference/android/app/Application.html#registerActivityLifecycleCallbacks%28android.app.Application.ActivityLifecycleCallbacks%29

에서 Application.ActivityLifecycleCallbacks, Activity"연결된"또는 "분리 된"을 얻을 수 있습니다.Application .

그러나이 기술은 API 레벨 14 이후에만 사용 가능합니다.


1
다른 모든 답변은 무엇입니까? 분명히 이것은이 목적을 위해 설계된 API입니다. 감사합니다, Yan 얀
마이클

2
@MichaelBushe-2012 년에 다른 답변이 작성된 시점에서 API 레벨 14에 따라 API가 최근에 출시 된 경우 (2011 년 10 월)를 감안할 때 모든 장치에서 의존 할 수있는 것은 아닙니다.
ToolmakerSteve

4
이 방법을 사용하는 방법을 보여주는 답변을 찾았습니다. stackoverflow.com/a/11082332/199364 장점은 활동 자체에 아무것도 수행 할 필요없다는 것입니다 . 코드는 모두 사용자 정의 콜백 클래스에 있습니다. 당신은 단순히 클래스를 만들고 implements Application.ActivityLifecycleCallbacks그것을 구현하는 메소드를 추가합니다. 그런 다음 해당 클래스의 생성자 (또는 인스턴스가 활성화 / 준비 될 때 실행되는 onCreate 또는 init 또는 기타 메소드) getApplication().registerActivityLifecycleCallbacks(this);에서 마지막 줄로 입력하십시오.
ToolmakerSteve

나는 당신의 대답은 최고라고 생각
burulangtu

2
좋은 대답입니다. 유일한 단점은 현재 활동에 대해 클래스를 쿼리 해야하는 경우 여전히 활동을 저장해야한다는 것입니다. 따라서 메모리 누수를 피하고 참조를 무효화해야합니다.
Raphael C

56

업데이트 2 : 공식 API가 추가되었으므로 ActivityLifecycleCallbacks를 대신 사용하십시오 .

최신 정보:

@gezdy가 지적한 것처럼, 나는 그것에 대해 감사합니다. 모든 onResume을 업데이트하는 대신 현재 활동에 대해 참조를 null로 설정하여 메모리 누수 문제를 피하기 위해 모든 onResume에서 null로 설정하십시오.

얼마 전 나는 같은 기능이 필요했으며 여기에 내가 달성 한 방법이 있습니다. 모든 활동에서 이러한 수명주기 방법을 대체하십시오.

@Override
protected void onResume() {
    super.onResume();
    appConstantsObj.setCurrentActivity(this);

}

@Override
protected void onPause() {
   clearReferences();
   super.onPause();
}

@Override
protected void onDestroy() {        
   clearReferences();
   super.onDestroy();
}

private void clearReferences(){
          Activity currActivity = appConstantsObj.getCurrentActivity();
          if (this.equals(currActivity))
                appConstantsObj.setCurrentActivity(null);
}

이제 방송 클래스에서 현재 활동에 액세스하여 경고를 표시 할 수 있습니다.


3
이 답변은 실제로 더 많은 투표, 간단한 솔루션을 얻을 수 있지만 활동을 조작해야하지만 활동 자체는 아닙니다.
ryvianstyron

액티비티 객체의 정적 참조에 관한 것입니다. 원하는 위치에 만들 수 있습니다 :). 중요하지 않습니다.
와카 스

이것은 이전 답변과 동일합니다. Application한 번만 생성되며 정적 변수처럼 가비지 수집되지 않습니다.
zapl

1
계층 활동에 문제가 있습니다. 자녀 활동에서 부모 활동으로 돌아올 때 : (1) 자녀의 onPause라고합니다. (2) 부모의 이력서; (3) 자녀의 onDestroy ==> 현재 활동은 null입니다. clearReferences 메소드의 예제에서 @gezdy와 같은 검사를 수행해야합니다.
Arts

4
@ waqas716 나는에 조건을 단순화하는 것이 좋습니다 것 clearReferences()까지 (this.equals(currActivity)).
naXa

51

@lockwobr 업데이트 주셔서 감사합니다

github에서 코드를 읽으면 Kitcurrent에서 "currentActivityThread"함수가 변경되었으므로 api 버전 16에서 100 % 작동하지 않습니다. 따라서 버전 19ish라고 말하고 싶습니다. .

전류에 접근하는 Activity것이 매우 편리합니다. getActivity불필요한 질문없이 현재 활동을 반환 하는 정적 메소드 를 갖는 것이 좋지 않습니까?

Activity클래스는 매우 유용하다. 응용 프로그램의 UI 스레드, 뷰, 리소스 등에 액세스 할 수 있습니다. 수많은 메소드가 필요 Context하지만 포인터를 얻는 방법은 무엇입니까? 몇 가지 방법이 있습니다.

  • 재정의 된 수명주기 방법을 사용하여 응용 프로그램의 상태를 추적합니다. 현재 활동을 정적 변수에 저장해야하며 모든 활동의 코드에 액세스해야합니다.
  • 인스 트루먼 테이션을 사용하여 애플리케이션 상태 추적 매니페스트에서 인스 트루먼 테이션을 선언하고 구현 한 후 해당 메소드를 사용하여 활동 변경 사항을 추적하십시오. 활동에 사용 된 메소드 및 클래스에 활동 포인터 전달 코드 삽입 라이브러리 중 하나를 사용하여 포인터를 주입합니다. 이러한 모든 접근 방식은 다소 불편합니다 . 운 좋게도 현재 활동을 얻는 훨씬 쉬운 방법이 있습니다.
  • 위에서 언급 한 문제없이 시스템이 모든 활동에 액세스해야하는 것 같습니다. 따라서 정적 호출 만 사용하여 활동을 얻는 방법이있을 수 있습니다. grepcode.com의 Android 소스를 파고 많은 시간을 보냈으며 찾고 있던 것을 발견했습니다. 라는 클래스가 있습니다ActivityThread 있습니다. 이 클래스는 모든 활동에 액세스 할 수 있으며 더 나은 것은 current를 얻는 정적 메소드를 가지고 ActivityThread있습니다. 한 가지 작은 문제가 있습니다. 활동 목록에는 패키지 액세스 권한이 있습니다.

리플렉션을 사용하여 쉽게 해결 :

public static Activity getActivity() {
    Class activityThreadClass = Class.forName("android.app.ActivityThread");
    Object activityThread = activityThreadClass.getMethod("currentActivityThread").invoke(null);
    Field activitiesField = activityThreadClass.getDeclaredField("mActivities");
    activitiesField.setAccessible(true);

    Map<Object, Object> activities = (Map<Object, Object>) activitiesField.get(activityThread);
    if (activities == null)
        return null;

    for (Object activityRecord : activities.values()) {
        Class activityRecordClass = activityRecord.getClass();
        Field pausedField = activityRecordClass.getDeclaredField("paused");
        pausedField.setAccessible(true);
        if (!pausedField.getBoolean(activityRecord)) {
            Field activityField = activityRecordClass.getDeclaredField("activity");
            activityField.setAccessible(true);
            Activity activity = (Activity) activityField.get(activityRecord);
            return activity;
        }
    }

    return null;
}

이러한 방법은 앱의 어느 곳에서나 사용할 수 있으며 언급 된 모든 방법보다 훨씬 편리합니다. 또한 보이는 것만 큼 안전하지 않은 것 같습니다. 새로운 잠재적 누출이나 널 포인터를 도입하지 않습니다.

위의 코드 스 니펫에는 예외 처리가 없으며 첫 번째 실행중인 활동이 우리가 찾고있는 활동이라고 순진하게 가정합니다. 추가 검사를 추가 할 수도 있습니다.

블로그 포스트


2
Kitkat 이상에서 mActivities는 HashMap이 아니라 ArrayMap이므로이 행을 변경해야합니다. HashMap Activities = (HashMap) ActivitiesField.get (activityThread); 다음과 같이 : ArrayMap Activities = (ArrayMap) ActivitiesField.get (activityThread);
팔레 한 드로

7
지지체 모두의 API (18 위 이하) 수준을 위해 사용해야 @Palejandro Map인터페이스 대신에 HashMap또는 ArrayMap. @AZ_ 답변을 편집했습니다.
Yuriy Kolbasinskiy

2
이 API를의 시간의 100 % 작동하지 않습니다 버전 16 은 GitHub의에 코드를 기능 "currentActivityThread"Kitkat으로 있었다 변화를 읽으면 내가 버전 말하고 싶은, 그래서, 19ish을 GitHub의에서 릴리스에 대한 API 버전과 일치하는 종류의 하드로, .
lockwobr

@ lockwobr 감사합니다, 솔루션 업데이트 의견
:)

2
리플렉션을 통해 내부 API에 액세스하는 것은 지원되지 않으며 모든 장치에서 작동하지 않을 수도 있습니다.
Pei

9

나는 Kotlin에서 다음을 수행했습니다.

  1. 응용 프로그램 클래스 만들기
  2. 다음과 같이 응용 프로그램 클래스 편집

    class FTApplication: MultiDexApplication() {
    override fun attachBaseContext(base: Context?) {
        super.attachBaseContext(base)
        MultiDex.install(this)
    }
    
    init {
        instance = this
    }
    
    val mFTActivityLifecycleCallbacks = FTActivityLifecycleCallbacks()
    
    override fun onCreate() {
        super.onCreate()
    
        registerActivityLifecycleCallbacks(mFTActivityLifecycleCallbacks)
    }
    
    companion object {
        private var instance: FTApplication? = null
    
        fun currentActivity(): Activity? {
    
            return instance!!.mFTActivityLifecycleCallbacks.currentActivity
        }
    }
    
     }
  3. ActivityLifecycleCallbacks 클래스 만들기

    class FTActivityLifecycleCallbacks: Application.ActivityLifecycleCallbacks {
    
    var currentActivity: Activity? = null
    
    override fun onActivityPaused(activity: Activity?) {
        currentActivity = activity
    }
    
    override fun onActivityResumed(activity: Activity?) {
        currentActivity = activity
    }
    
    override fun onActivityStarted(activity: Activity?) {
        currentActivity = activity
    }
    
    override fun onActivityDestroyed(activity: Activity?) {
    }
    
    override fun onActivitySaveInstanceState(activity: Activity?, outState: Bundle?) {
    }
    
    override fun onActivityStopped(activity: Activity?) {
    }
    
    override fun onActivityCreated(activity: Activity?, savedInstanceState: Bundle?) {
        currentActivity = activity
    }
    
    }
  4. 이제 다음을 호출하여 모든 클래스에서 사용할 수 있습니다. FTApplication.currentActivity()


5

getCurrentActivity ()도 ReactContextBaseJavaModule에 있습니다.
(이 질문은 처음에 요청되었으므로 많은 Android 앱에도 ReactNative 구성 요소-하이브리드 앱이 있습니다.)

ReactNative의 ReactContext 클래스는 getCurrentActivity ()에 반환되는 mCurrentActivity를 유지하기위한 전체 로직 세트를 갖습니다.

참고 : getCurrentActivity ()가 Android Application 클래스에서 구현되기를 바랍니다.


어떤 경우에는 ReactContextBaseJavaModule의이 컨텍스트가 널입니다. 이유를 알고 있습니까?
Moxor

4

우리 팀이 만족할만한 해결책을 찾을 수 없었기 때문에 우리는 우리 자신을 굴 렸습니다. 우리 ActivityLifecycleCallbacks는 현재 활동을 추적 한 다음 서비스를 통해 노출합니다. 자세한 내용은 https://stackoverflow.com/a/38650587/10793


2

이전 버전과의 호환성을 위해 :

ComponentName cn;
ActivityManager am = (ActivityManager) getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
    cn = am.getAppTasks().get(0).getTaskInfo().topActivity;
} else {
    //noinspection deprecation
    cn = am.getRunningTasks(1).get(0).topActivity;
}

4
ComponentName에서 Activity의 현재 인스턴스로 이동하는 방법이 없으면 IMO 질문에 대답하지 않습니다.
nasch

@nasch 클래스 WeakReference에서 핸들을 유지하고 처리 할 수 있지만 원하는 작업이 실행중인 작업 목록 위에 있는지 확인 해야합니다. 이것이 이것이 질문에 완전히 대답하지 못하면 받아 들여진 대답도 그렇지 않습니다. ApplicationComponentNameActivity
Martin Zeitler

동의 한 답변도 질문에 완전히 대답하지는 않습니다.
nasch

1
topActivityAndroid Q
Eugen Martynov

1

개인적으로 "Cheok Yan Cheng"이 말한대로했지만 "List"를 사용하여 모든 활동의 "백 스택"을 사용했습니다.

현재 활동을 확인하려면 목록에서 마지막 활동 클래스를 가져와야합니다.

"응용 프로그램"을 확장하는 응용 프로그램을 작성하고 다음을 수행하십시오.

public class MyApplication extends Application implements Application.ActivityLifecycleCallbacks,
EndSyncReceiver.IEndSyncCallback {

private List<Class> mActivitiesBackStack;
private EndSyncReceiver mReceiver;
    private Merlin mMerlin;
    private boolean isMerlinBound;
    private boolean isReceiverRegistered;

@Override
    public void onCreate() {
        super.onCreate();
        [....]
RealmHelper.initInstance();
        initMyMerlin();
        bindMerlin();
        initEndSyncReceiver();
        mActivitiesBackStack = new ArrayList<>();
    }

/* START Override ActivityLifecycleCallbacks Methods */
    @Override
    public void onActivityCreated(Activity activity, Bundle bundle) {
        mActivitiesBackStack.add(activity.getClass());
    }

    @Override
    public void onActivityStarted(Activity activity) {
        if(!isMerlinBound){
            bindMerlin();
        }
        if(!isReceiverRegistered){
            registerEndSyncReceiver();
        }
    }

    @Override
    public void onActivityResumed(Activity activity) {

    }

    @Override
    public void onActivityPaused(Activity activity) {

    }

    @Override
    public void onActivityStopped(Activity activity) {
        if(!AppUtils.isAppOnForeground(this)){
            if(isMerlinBound) {
                unbindMerlin();
            }
            if(isReceiverRegistered){
                unregisterReceiver(mReceiver);
            }
            if(RealmHelper.getInstance() != null){
                RealmHelper.getInstance().close();
                RealmHelper.getInstance().logRealmInstanceCount("AppInBackground");
                RealmHelper.setMyInstance(null);
            }
        }
    }

    @Override
    public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {

    }

    @Override
    public void onActivityDestroyed(Activity activity) {
        if(mActivitiesBackStack.contains(activity.getClass())){
            mActivitiesBackStack.remove(activity.getClass());
        }
    }
    /* END Override ActivityLifecycleCallbacks Methods */

/* START Override IEndSyncCallback Methods */
    @Override
    public void onEndSync(Intent intent) {
        Constants.SyncType syncType = null;
        if(intent.hasExtra(Constants.INTENT_DATA_SYNC_TYPE)){
            syncType = (Constants.SyncType) intent.getSerializableExtra(Constants.INTENT_DATA_SYNC_TYPE);
        }
        if(syncType != null){
            checkSyncType(syncType);
        }
    }
    /* END IEndSyncCallback Methods */

private void checkSyncType(Constants.SyncType){
    [...]
    if( mActivitiesBackStack.contains(ActivityClass.class) ){
         doOperation()     }
}

}

제 경우에는 "Application.ActivityLifecycleCallbacks"를 사용하여 다음을 수행했습니다.

  • Merlin 인스턴스 바인드 / 바인드 해제 (예 : 모바일 데이터를 닫거나 열 때와 같이 앱의 연결이 끊어 지거나 이벤트가 발생하는 경우 이벤트를 얻는 데 사용). "OnConnectivityChanged"의도 조치가 사용 불가능한 후에 유용합니다. MERLIN에 대한 자세한 내용은 MERLIN INFO LINK를 참조하십시오.

  • 응용 프로그램이 닫히면 마지막 Realm 인스턴스를 닫습니다. BaseActivity 내부에서 초기화하고 다른 모든 활동에서 확장되고 개인 RealmHelper 인스턴스가 있습니다. REALM에 대한 자세한 내용은 다음을 참조하십시오. REALM INFO LINK 예를 들어, "RealmHelper"클래스 내에 정적 "RealmHelper"인스턴스가 있으며이 애플리케이션은 "onCreate"내에서 인스턴스화됩니다. Realm이 "Thread-Linked"이고 Realm 인스턴스가 다른 스레드 내에서 작동 할 수 없기 때문에 새로운 "RealmHelper"를 생성하는 동기화 서비스가 있습니다. 따라서 Realm Documentation "시스템 리소스 누수를 피하기 위해 열려있는 Realm 인스턴스를 모두 닫아야합니다"를 따르기 위해이 작업을 수행하기 위해 "Application.ActivityLifecycleCallbacks"를 사용했습니다.

  • 마지막으로 수신기 동기화가 완료되면 응용 프로그램 동기화가 시작된 다음 동기화 종료시 "IEndSyncCallback" "onEndSync"메서드를 호출하여 필요한 경우 ActivitiesBackStack 목록에 특정 활동 클래스가 있는지 확인합니다. 동기화에서 데이터를 업데이트하고 앱 동기화 후 다른 작업을 수행해야 할 경우 뷰의 데이터를 업데이트합니다.

그게 다야, 이것이 도움이되기를 바랍니다. 당신을 참조하십시오 :)


-1

waqas716 의 답변 이 좋습니다. 코드와 유지 관리가 덜 필요한 특정 사례에 대한 해결 방법을 만들었습니다.

정적 메소드가 포 그라운드에 있다고 생각되는 활동에서 뷰를 가져 와서 특정 해결 방법을 찾았습니다. 모든 활동을 반복하고 원하는 답변이 있는지 확인하거나 Martin의 답변 에서 활동 이름을 가져옵니다.

ActivityManager am = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
ComponentName cn = am.getRunningTasks(1).get(0).topActivity; 

그런 다음 뷰가 null이 아닌지 확인하고 getContext ()를 통해 컨텍스트를 가져옵니다.

View v = SuspectedActivity.get_view();

if(v != null)
{
    // an example for using this context for something not 
    // permissible in global application context. 
    v.getContext().startActivity(new Intent("rubberduck.com.activities.SomeOtherActivity"));
}

비슷한 문제를 찾고 있습니다. stackoverflow.com/questions/22788289 / ... "SuspectedActivity"는 어떻게 얻습니까? 이 기본 API입니까?
Stella

2
하지만 대한 문서에서 getRunningTasks: "Note: this method is only intended for debugging and presenting task management user interfaces. This should never be used for core logic in an application, ..."developer.android.com/reference/android/app/...
ToolmakerSteve

3
ActivityManager.getRunningTasks () 문서에 "이 메소드는 API 레벨 21에서 더 이상 사용되지 않습니다"라고 표시되어 있습니다.
markshep

-2

나는 다른 답변을 좋아하지 않습니다. ActivityManager는 현재 활동을 가져 오는 데 사용되지 않습니다. 수퍼 클래 싱 및 onDestroy에 따른 디자인 또한 깨지기 쉬우 며 최고의 디자인은 아닙니다.

솔직히, 지금까지 생각해 낸 최선은 내 응용 프로그램에서 열거 형을 유지하는 것입니다. 활동이 생성 될 때 설정됩니다.

다른 권장 사항은 가능한 경우 여러 활동을 사용하지 않는 것이 좋습니다. 이것은 조각을 사용하거나 선호하는 사용자 정의보기에서 수행 할 수 있습니다.


1
열거 형? 현재 포 그라운드 활동 인스턴스를 찾는 데 어떻게 도움이됩니까?
ToolmakerSteve

"슈퍼 분류 및 onDestroy에 따라 취약하기도합니다"어떻게 그 연약한가?
ToolmakerSteve

-3

다소 간단한 해결책은 하나 이상의 활동에 대한 참조 또는 앱 전체에서 액세스하려는 다른 항목을 저장할 수있는 싱글 톤 관리자 클래스를 만드는 것입니다.

UberManager.getInstance().setMainActivity( activity );주 활동의 onCreate를 호출 하십시오.

UberManager.getInstance().getMainActivity();앱의 아무 곳이나 호출 하여 앱을 검색하십시오. (UI가 아닌 스레드에서 토스트를 사용할 수 있도록 이것을 사용하고 있습니다.)

UberManager.getInstance().cleanup();앱이 파괴 될 때 전화를 추가해야합니다 .

import android.app.Activity;

public class UberManager
{
    private static UberManager instance = new UberManager();

    private Activity mainActivity = null;

    private UberManager()
    {

    }

    public static UberManager getInstance()
    {
        return instance;
    }

    public void setMainActivity( Activity mainActivity )
    {
        this.mainActivity = mainActivity;
    }

    public Activity getMainActivity()
    {
        return mainActivity;
    }

    public void cleanup()
    {
        mainActivity = null;
    }
}

이는 방해가되며 모든 활동을 변경해야합니다. AZ_답변 은 코드베이스에서 다른 변경을 요구하지 않고 완전히 현지화되고 독립형이므로 훨씬 좋습니다.
markshep

-7

나는 3 년 늦었지만 어쨌든 누군가가 내가 한 것처럼 이것을 발견하면 대답 할 것입니다.

나는 이것을 간단히 사용하여 이것을 해결했다.

    if (getIntent().toString().contains("MainActivity")) {
        // Do stuff if the current activity is MainActivity
    }

"getIntent (). toString ()"에는 패키지 이름 및 활동에 대한 의도 필터와 같은 다른 텍스트가 포함되어 있습니다. 기술적으로 우리는 활동이 아닌 현재 의도를 확인하고 있지만 결과는 같습니다. 예를 들어 Log.d ( "test", getIntent (). toString ()); 모든 텍스트를 보려면 이 솔루션은 약간 해 키지 만 코드에서 훨씬 깨끗하고 기능은 동일합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.