java - コールバックメッセージとは




実行可能なコールバックがアクティビティを自動的に破壊するのはなぜですか? (6)

私はアンドロイドで実行可能なコールバックを遅延( postDelayedメソッド)で処理/検出できる可能性があるかどうかを知りたがっていますか?

例えば、私は1つまたはいくつかのスプラッシュ画面を持っています(私のアプリケーション(テスト目的のアプリケーション)でhandler.postDelayed(new Runnable()... )を実行しています)このアプリケーションでは、アプリケーション内で)、そこで利用可能ないくつかのクラスはIntentServiceクラスで実行されます。

時々、アプリケーションが実行中のsplashscreenアクティビティ( Testing purpose )、私が作成しているライブラリは、いくつかのアクティビティをUIで自動的にポップアップすることがあります。 しかし、これらのアクティビティがsplashscreenアクティビティになってsplashscreenが破棄されている場合、それらのアクティビティ(自動的にポップアップするもの)も破棄され、logcatに「リークされたウィンドウ」メッセージが記録されます。

問題はそれです :

  • UIに自動的に表示されるアクティビティを自動的に閉じてはいけませんが、これは禁止されています。 そのアクティビティを閉じるためにユーザーからの対話が必要で、アプリケーションの通常の動作に戻ります。
  • また、ライブラリはアプリケーションのUIについて何も知らない。

ですから、私の質問は(UIアプリケーションの流れに情報を持たずに作成しているライブラリ側と比べて)です:

  • アプリケーションでいくつかのpostDelayedメソッドがライブラリ側に対して作成されたかどうかを検出する方法はありますか? はいの場合、どのように問題を処理できますか?

PS:通常、私は自動的に現れるアクティビティを想定してダイアログを使用しています。

更新

図の説明:

今私はスプラッシュスクリーンが実行されているケースがあります。

IntentServiceクラスを拡張したクラスは、 アクティビティを開始するインターネットからリクエストを受け取りました。

一方、スプラッシュスクリーンはpostdelayed後になり、他のアクティビティは作成され、UIに表示されます。 X秒が経過し、他のアクティビティが破棄されていない場合、 次のアクティビティが作成され、他のアクティビティは自動的に破棄されます。 その際、Androidはアクティビティに対して相対的に「漏れたウィンドウ」メッセージをスローします。


問題をよりよく説明する必要があります。 私は、スプラッシュスクリーンと他のアクティビティとの関係、および問題がpostDelayed()またはアクティビティライフサイクルに関係しているかどうかpostDelayed()しています。 私は、どのアクティビティが他のアクティビティを起動するかを説明する小さなグラフィック図を提案します。

postDelayed()に関しては、一般的に、もしあなたが

 mHandler.postDelayed(new Runnable() { ... });

毎回匿名の新しい実行ファイルを投稿しているため、削除することはできません。 私はRunnablesをあなたのライブラリ内のクラスメンバーとして宣言する、以下のアプローチを提案します:

Runnable mLaunchSplashRunnable = new Runnable() { ... };
Runnable mLaunchContactsRunnable = new Runnable() { ... };

.
.

mHandler.postDelayed (mLaunchSplashRunnable, DELAY);
mHandler.postDelayed (mLaunchContactsRunnable, DELAY);

.
.

ランナブルは匿名ではないので、いつでもキューから削除することができます:

void removeLibraryDelayedRunnables() {
   mHandler.removeCallbacks(mLaunchSplashRunnable);
   mHandler.removeCallbacks(mLaunchContactsRunnable);
}

投稿されたランナブルがない場合、前のメソッドは失敗しないので、いつでも呼び出すことができます。

特定のRunnableが待機中のafaikが存在しない場合にHandlerに問い合わせるメソッドですが、 booleanフラグを使用したり、実行可能ファイルがキューに入れられたときにそのファイルを設定したり、 Runnableが実行されたときにリセットしたり保留中。

私があなたの問題をよりよく理解すれば、私はもっと助けることができます。


私はあなたがプログラムで論理を反転させるべきだと思います。 アクティビティは、サービスからではなく、アクティビティから開始する必要があります。

これを実現するには、各アクティビティの作成時にBroadcastReceiverを登録することができます。https: //developer.android.com/reference/android/content/BroadcastReceiver.html https://developer.android.com/guide/componentsからsendBroadcastを使用します放送受信機に必要な活動を開始するように命令するために、活動を開始するときには/broadcasts.htmlが必要である。


アクティビティはいつでも破壊される可能性があります。その場合、破壊されているダイアログも処理する必要があります。 アクティビティのライフサイクルでは、「ダイアログ」を破棄する必要があります。そうしないと、「リークウィンドウ」が表示されます。

また、アクティビティーを参照するダイアログは、アクティビティーにweakReferenceを使用することで利益を得ます。弱い参照を使用して、ユーザーのアクションをアクティビティーに報告します。

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    listener = new WeakReference<>((MyActionListener) activity);
    activityWeakReference = new WeakReference<>(activity);
}

ダイアログを表示する前に、アクティビティが終了していないことを確認します。

if (myActivityWeakReference.get() != null && !myActivityWeakReference.get().isFinishing()) {
  // show dialog
}

次に、アクティビティが再作成されるデバイスのローテーションを制御する場合は、ダイアログとともに以下を使用できます。

    @Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setRetainInstance(true);
}

/**
 * Prevent the dialog being dismissed when rotated, when using setRetainInstance
 */
@Override
public void onDestroyView() {
    if (getDialog() != null && getRetainInstance()) {
        getDialog().setDismissMessage(null);
    }
    super.onDestroyView();
}

一時的に結合されたアクティビティを持つコールバックを使用すると、SDKのデザインがうまくいかない場合があります。 Observableを使用して、ネットワーク層からデータを必要とするアクティビティにデータを取得することを検討してください。

データが必要なアクティビティにオブザーバを追加すると、ネットワークコールが完了したかどうかを監視し、アクティブなオブザーバにのみデータを公開します。 このようにして、コールが完了する前にアクティビティが閉じられると、クローズされたアクティビティにデータが「プッシュ」されることはありません。

これにより、ウィンドウの漏れを心配する必要がない方法で、ライブラリへの弱い参照を作成することもできます


静的ブール変数を使用して、スプラッシュ画面が呼び出されようとしているかどうかを判断するのはなぜですか。


問題は、アプリケーションが次々にアクティビティを開始すると、アプリケーションがメモリを大量に消費してしまった後に、アンドロイドが以前のアクティビティを破棄してシステムを最適化し、デバイスのスローダウンを避けることができると仮定した場合です。ので、APIを消費しているあなたの主な活動はシステムによって破壊される:活動のライフサイクルを理解してください:

https://developer.android.com/guide/components/activities/activity-lifecycle.html

onStop()の後を見てください...これはあなたのアプリの場合です。

これがあなたを助けることを願っています...





android-looper