web-dev-qa-db-ja.com

カスタムビューはonPauseが呼び出されたことを知ることができますか?

定期的にインターウェブを呼び出しているスレッド操作を実行するカスタムビューがあります。アクティビティがバックグラウンド(および/または強制終了)になった後、スレッドがバックグラウンドで動き回らないように、親アクティビティ(onPause)からそのスレッドを強制終了する必要がない方法があるかどうかを知りたいです。

ここでの意図は、カスタムビューが自己完結型であり、アクティビティからの追加の処理を必要としないことです。その方法は、親がバックグラウンドになったときにリッスンし、スレッドの無限スリープループが期限切れになるようにすることです。私はそれをする方法を見ていませんが、私は何かを見落としていることを望んでいます。

34
Genia S.

直接通知しない限り。

目的のために、View.onDetachedFromWindow()をオーバーライドして、スレッドを放棄します。次に、ビューが再び表示されたら、View.onAttachedToWindow()でスレッドをスピンアップします。 onPause()およびonResume()の問題は、画面上に表示されているビューを保持できるが、一時停止されたアクティビティに関連付けられていることです。これが発生する可能性のある例は、別のウィンドウにオーバーレイするアクティビティがある場合です。

または、ウィリアム・グーヴィアが示唆するように、フラグメントにはすでに一時停止と再開のためのライフサイクルフックがあり、ネットワークと通信するものはすべてに入るため、あなたの目的に適しているかもしれませんとにかくcontrollerレルム。

13
dcow

はい、以下のコードを使用できますが、

@Override
protected void onVisibilityChanged(@NonNull View changedView, int visibility) {
    super.onVisibilityChanged(changedView, visibility);
    if (visibility == View.VISIBLE) //onResume called
    else // onPause() called
}

@Override
public void onWindowFocusChanged(boolean hasWindowFocus) {
    super.onWindowFocusChanged(hasWindowFocus);
    if (hasWindowFocus) //onresume() called
    else // onPause() called
}

@Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        // onDestroy() called
}

@Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        // onCreate() called
}
49
Yogesh Rathi

はい、できます。必要なのは、LifecycleOwnerタイプのフィールドを持つことだけです。詳しくは 公式ドキュメント をご覧ください。私の場合、サードパーティライブラリの別のビューであるCameraViewを使用してカスタムビューを作成しました。

最初に、カスタムビューはLifecycleOberverインターフェイスを実装する必要があります

public class MakePhotoView extends ConstraintLayout implements LifecycleObserver

だから、私は私のカスタムビューにフィールドがあります:

private LifecycleOwner mLifecycleOwner;

パラメーターの1つとしてコンストラクターに渡します。

public MakePhotoView(Context context, OnPhotoMadeListener onPhotoMadeListener, LifecycleOwner lifecycleOwner) {
    super(context);
    mOnPhotoMadeListener = onPhotoMadeListener;
    mLifecycleOwner = lifecycleOwner;
    init();
}

その後、LifecycleOwnerでライフサイクルイベントのオブザーバーとしてカスタムビューを登録します。

private void init() {
    //other code
    mLifecycleOwner.getLifecycle().addObserver(this);
}

そして最後に、ライフサイクルイベントをリッスンできます。

@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
public void startCamera() {
    AppLog.logObject(this, "On Resume called for MakeCameraView");
    mCameraView.start();
}

@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
public void stopCamera() {
    AppLog.logObject(this, "On Pause called for MakeCameraView");
    mCameraView.stop();
}

@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
public void destroyCamera() {
    AppLog.logObject(this, "On Destroy called for MakeCameraView");
    mCameraView.destroy();
}
3

所有しているアクティビティがフォアグラウンドにないことをビューに知らせるか、現在フォアグラウンドにあるタスクを照会するメソッドを使用してシステムをポーリングする必要がありますが、これは非常に効率が悪いようです。

この問題に対処した2つのリンクを次に示します。

(これは実際には答えではないかもしれませんが、コメントするには大きすぎます)

2
Merlevede

Viewクラスをオーバーライドして独自のCustomViewを作成するだけで、親アクティビティによって実装されるリスナーとして機能するインターフェイスを作成できます。そのため、何かが発生した場合、イベントをトリガーし、これらのコンポーネント間の通信を確立します。

このコンポーネントにはアクティビティ(onPause/onResumeなど)に類似した独自のライフサイクルがあり、ビューがあるかどうかに関係なく独自の状態を保持し、構成の変更間で状態を保持できるため、達成したい内容に応じてフラグメントが役立ちます。

詳細は、 http://developer.Android.com/reference/Android/app/Fragment.htmlhttp://developer.Android.com/guide/components/fragments。 html

2
william gouvea