特定のアクティビティがアクティブかどうかを判断する簡単な方法はありますか?どの活動が活発であるかに応じて、特定のことをしたいです。例えば:
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;
}
}
唯一の落とし穴は、相互にリンクする2つのアクティビティで使用するとonStop
、最初のアクティビティがonStart
2番目のアクティビティの後に呼び出されることがあります。したがって、どちらも簡単に当てはまる可能性があります。
何をしようとしているかに応じて(サービスから現在のアクティビティを更新しますか?)。静的リスナーをサービスのアクティビティonStart
メソッドに登録するだけで、サービスがUIを更新するときに正しいリスナーを利用できるようになります。
MyActivity
しMyChildactivity
、子供がアクティブかどうかを確認したい場合はどうなりますか?
この問題はかなり古いものだと思いますが、他の人にも役立つので、私の解決策を共有する価値はあると思います。
このソリューションは、Androidアーキテクチャコンポーネントがリリースされるまでは利用できませんでした。
アクティビティは少なくとも部分的に表示されています
getLifecycle().getCurrentState().isAtLeast(STARTED)
活動は前景にあります
getLifecycle().getCurrentState().isAtLeast(RESUMED)
私はそのようにもっと明確だと思います:
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()で変化します。これは、電話でのアクティビティのレイアウトを示す開始/停止イベントです。
Activity#getWindow().getDecorView().isShown()
ですか?
私は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;
}
getRunningTasks()
廃止されたため、使用することはお勧めできません。androidxref.com
静的変数を使用してOOPを実行するよりもはるかに良い方法
Shared Preferences
変数を他のactivities
サービスと共有したり、1つのサービスを使用したりできます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をここにも
onStop()
これは、特定のサービスが実行されているかどうかを確認するためのコードです。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;
}
上記のすべてよりもはるかに簡単な方法があり、このアプローチはandroid.permission.GET_TASKS
マニフェストでの使用を必要としないか、受け入れられた回答で指摘されている競合状態またはメモリリークの問題を抱えています。
メインアクティビティでSTATIC変数を作成します。Staticを使用すると、他のアクティビティが別のアクティビティからデータを受け取ることができます。onPause()
この変数を設定偽を、onResume
そしてonCreate()
この変数を設定真実。
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()でよく使用されます。
アクティビティで最後のonDestroy()呼び出しが行われた場合はtrueを返します。そのため、このインスタンスは停止しています。
ありがとう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"/>
これがお役に立てば幸いです。
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マニフェストファイルでその参照を提供します。
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
それが「物事を行う」ための「適切な」方法であるかどうかはわかりません。
(またはa)質問を解決するためのAPIの方法が少しあるべきだと思われる場合、おそらく何かが間違っていて、代わりにもっと多くのドキュメントを読んでいる可能性があります
(静的変数はAndroidでは一般的に間違った方法です。動作する可能性はありますが、動作しない場合もあります(たとえば、本番環境では、100万台のデバイス上)。
まさにあなたのケースでは、別のアクティビティが生きているかどうかを知る必要がある理由を考えることをお勧めします。結果のために別のアクティビティを開始して、その機能を取得できます。または、クラスを派生させてその機能などを取得することもできます。
宜しくお願いします。
アクティビティの特定のインスタンスのライフサイクル状態に関心がある場合、siliconagleのソリューションは正しいように見えますが、新しい「アクティブ」変数は静的ではなくインスタンス変数である必要があります。
順序付きブロードキャストを使用します。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--;
}
}
次のコードで簡単な回避策を見つけました
@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();
}
}
アクティビティがバックスタックにあるかどうかを確認する場合は、次の手順に従ってください。1.アプリケーションクラスでArrayListを宣言しました[アプリケーションクラスはアプリケーションタグのmainfestファイルで定義されています]
private ArrayList<Class> runningActivities = new ArrayList<>();
このリストにアクセスして変更するには、次のパブリックメソッドを追加します。
public void addActivityToRunningActivityies (Class cls) {
if (!runningActivities.contains(cls)) runningActivities.add(cls);
}
public void removeActivityFromRunningActivities (Class cls) {
if (runningActivities.contains(cls)) runningActivities.remove(cls);
}
public boolean isActivityInBackStack (Class cls) {
return runningActivities.contains(cls);
}
BaseActivityでは、すべてのアクティビティがそれを拡張するため、onCreateメソッドとonDestroyメソッドをオーバーライドして、次のようにバックスタックにアクティビティを追加および削除できるようにします。
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
((MyApplicationClass)getApplication()).addActivityToRunningActivityies
(this.getClass());
}
@Override
protected void onDestroy() {
super.onDestroy();
((MyApplicationClass)getApplication()).removeActivityFromRunningActivities
(this.getClass());
}
最後に、アクティビティがバックスタックにあるかどうかを確認する場合は、この関数isActivityInBackStackを呼び出します。
例:HomeActivityがバックスタックにあるかどうかを確認したい:
if (((MyApplicationClass)
getApplication()).isActivityInBackStack(HomeActivity.class)) {
// Activity is in the back stack
} else {
// Activity is not in the back stack
}
public static boolean isActivityActive(Activity activity) {
return !activity.isFinishing() &&
(SDK_INT < JELLY_BEAN_MR1 || !activity.isDestroyed());
}
これは、フォアグラウンドで同じアクティビティがない場合に機能します。通知から開いて動作しない場合、いくつかの調整を行い、これが付属しています。
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();
}
これは、複数のアクティビティを同時に開いている場合に役立ちます。