自定义视图是否可以知道onPause已被调用?

时间:2014-03-13 03:52:57

标签: android multithreading custom-view

我有一个自定义View,它运行一个Thread操作,它定期调用interwebs。我想知道是否有一种方法可以让我不必从父Activity(onPause)中删除该线程,这样Thread就不会在Activity被后台化后在后台进行铣削(并且/或被杀死。)

这里的目的是让自定义View自给自足,不需要从Activity中进行额外处理。这样做的方法是让它在其父级被后台时监听,然后让它在线程中的无限睡眠循环到期。我没有办法做到这一点,但我希望我能忽略一些事情。

6 个答案:

答案 0 :(得分:48)

  

是的,您可以使用以下代码,

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

答案 1 :(得分:13)

除非您直接通知。

出于您的目的,覆盖View.onDetachedFromWindow()并放弃您的主题。然后,当视图再次可见时,在View.onAttachedToWindow()中重新旋转线程。 onPause()和onResume()的问题在于,您仍然可以在屏幕上看到可见的视图,但该视图会附加到暂停的活动。可能发生这种情况的一个示例是,如果窗口中有一个活动覆盖另一个活动。

或者,正如William Gouvea所说,片段可能更适合您的目的,因为它已经具有暂停和恢复的生命周期钩子,并且与网络对话的任何内容都真正属于控制器

答案 2 :(得分:2)

您必须让您的视图知道拥有的Activity不再位于前台,或者使用某种方法轮询系统以查询当前哪个任务位于前台,这似乎非常低效。

以下是解决此问题的两个链接:

(这可能不是一个真正的答案,但它对评论来说太大了)

答案 3 :(得分:2)

如果您只是覆盖View类并创建自己的CustomView,您可以创建一个充当侦听器的接口,该接口应由您的父活动实现,因此当发生某些事情时,您会触发事件并在这些组件之间建立通信来回。

根据你想要实现的目标,Fragments可能很有用,因为这个组件有你自己的生命周期类似于activity(例如onPause / onResume),拥有你自己的状态,是否具有视图并且可以保持它们之间的状态配置渐变。

详见: http://developer.android.com/reference/android/app/Fragment.html http://developer.android.com/guide/components/fragments.html

答案 4 :(得分:2)

可以。 您所需要做的就是拥有一个LifecycleOwner类型的字段。 在official documentation中有更多有关它的信息。 就我而言,我创建了一个自定义视图,其中包含来自第三方库-CameraView的另一个视图。

首先,自定义视图需要实现LifecycleOberver接口

public class MakePhotoView extends ConstraintLayout implements LifecycleObserver

因此,我的自定义视图中有一个字段:

private LifecycleOwner mLifecycleOwner;

我将其作为参数之一传递给构造函数:

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

答案 5 :(得分:1)

如果Build.VERSION.SDK_INT < Build.VERSION_CODES.N

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

然后Build.VERSION.SDK_INT >= Build.VERSION_CODES.N

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

您可以阅读ProgressBar的源代码来了解想法。