diff --git a/android/libpag/src/main/java/org/extra/tools/BroadcastUtil.java b/android/libpag/src/main/java/org/extra/tools/BroadcastUtil.java deleted file mode 100644 index 2b34fa626d..0000000000 --- a/android/libpag/src/main/java/org/extra/tools/BroadcastUtil.java +++ /dev/null @@ -1,117 +0,0 @@ -package org.extra.tools; - -import java.lang.ref.WeakReference; -import java.util.ArrayList; -import java.util.List; - -public class BroadcastUtil implements ScreenBroadcastReceiver.ScreenStateListener { - private static List> mDataList = new ArrayList<>(); - private final Object mSync = new Object(); - private ScreenBroadcastReceiver receiver = null; - - private static class Factory { - private final static BroadcastUtil INSTANCE = new BroadcastUtil(); - } - - public static BroadcastUtil getInstance() { - return Factory.INSTANCE; - } - - public void registerScreenBroadcast() { - if (receiver != null) { - return; - } - receiver = new ScreenBroadcastReceiver(this); - receiver.register(); - } - - public void unregisterScreenBroadcast() { - if (receiver != null) { - receiver.unregister(); - receiver = null; - } - } - - public void registerScreenBroadcast(ScreenBroadcastReceiver.ScreenStateListener listener) { - if (receiver == null) { - return; - } - - removeUnUse(); - if (listener == null) { - return; - } - - synchronized (mSync) { - for (WeakReference weakReference : mDataList) { - if (listener == weakReference.get()) { - return; - } - } - WeakReference weakReference = new WeakReference<>(listener); - mDataList.add(weakReference); - } - } - - public void unregisterScreenBroadcast(ScreenBroadcastReceiver.ScreenStateListener listener) { - if (receiver == null) { - return; - } - - removeUnUse(); - if (listener == null) { - return; - } - synchronized (mSync) { - WeakReference remove = null; - for (WeakReference weakReference : mDataList) { - if (listener == weakReference.get()) { - remove = weakReference; - } - } - if (remove != null) { - mDataList.remove(remove); - } - } - } - - private void removeUnUse() { - synchronized (mSync) { - List> removeList = new ArrayList<>(); - for (WeakReference weakReference : mDataList) { - if (weakReference.get() == null) { - removeList.add(weakReference); - } - } - for (WeakReference weakReference : removeList) { - mDataList.remove(weakReference); - } - } - } - - @Override - public void onScreenOff() { - removeUnUse(); - synchronized (mSync) { - for (int pos = mDataList.size() - 1; pos >= 0; pos--) { - ScreenBroadcastReceiver.ScreenStateListener listener = mDataList.get(pos).get(); - if (listener != null) { - listener.onScreenOff(); - } - } - } - } - - @Override - public void onScreenOn() { - removeUnUse(); - synchronized (mSync) { - for (int pos = mDataList.size() - 1; pos >= 0; pos--) { - ScreenBroadcastReceiver.ScreenStateListener listener = mDataList.get(pos).get(); - if (listener != null) { - listener.onScreenOn(); - } - } - } - } -} diff --git a/android/libpag/src/main/java/org/extra/tools/Lifecycle.java b/android/libpag/src/main/java/org/extra/tools/Lifecycle.java new file mode 100644 index 0000000000..637ea2484b --- /dev/null +++ b/android/libpag/src/main/java/org/extra/tools/Lifecycle.java @@ -0,0 +1,68 @@ +package org.extra.tools; + +import android.app.Activity; +import android.app.FragmentManager; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; +import android.util.Log; + +import org.libpag.PAGView; + +import java.util.HashMap; +import java.util.Map; + +public class Lifecycle implements Handler.Callback { + private static final String FRAGMENT_TAG = "io.pag.manager"; + private static final String TAG = "Lifecycle"; + + private static final int ID_REMOVE_FRAGMENT_MANAGER = 1; + private static final Lifecycle lifecycle = new Lifecycle(); + private final Handler handler; + private final Map pendingRequestManagerFragments = + new HashMap<>(); + + private Lifecycle() { + handler = new Handler(Looper.getMainLooper(), this); + } + + public static Lifecycle getInstance() { + return lifecycle; + } + + public void addListener(final PAGView pagView) { + if (pagView.getContext() instanceof Activity) { + Activity activity = (Activity) pagView.getContext(); + FragmentManager fm = activity.getFragmentManager(); + LifecycleFragment current = pendingRequestManagerFragments.get(fm); + if (current == null) { + current = (LifecycleFragment) fm.findFragmentByTag(FRAGMENT_TAG); + if (current == null) { + current = new LifecycleFragment(); + pendingRequestManagerFragments.put(fm, current); + fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss(); + handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget(); + } + } + current.addListener(pagView); + } + } + + @Override + public boolean handleMessage(Message message) { + boolean handled = true; + if (message.what == ID_REMOVE_FRAGMENT_MANAGER) { + FragmentManager fm = (FragmentManager) message.obj; + LifecycleFragment current = (LifecycleFragment) fm.findFragmentByTag(FRAGMENT_TAG); + if (fm.isDestroyed()) { + Log.w(TAG, "Parent was destroyed before our Fragment could be added."); + } else if (current != pendingRequestManagerFragments.get(fm)) { + Log.w(TAG, "adding Fragment failed."); + } + pendingRequestManagerFragments.remove(fm); + } else { + handled = false; + } + return handled; + } +} diff --git a/android/libpag/src/main/java/org/extra/tools/LifecycleFragment.java b/android/libpag/src/main/java/org/extra/tools/LifecycleFragment.java new file mode 100644 index 0000000000..de61955e04 --- /dev/null +++ b/android/libpag/src/main/java/org/extra/tools/LifecycleFragment.java @@ -0,0 +1,29 @@ +package org.extra.tools; + +import android.app.Fragment; + +import java.util.Collections; +import java.util.Set; +import java.util.WeakHashMap; + +public class LifecycleFragment extends Fragment { + private final Set lifecycleListeners = + Collections.newSetFromMap(new WeakHashMap()); + + public LifecycleFragment() { + } + + public void addListener(LifecycleListener listener) { + lifecycleListeners.add(listener); + } + + @Override + public void onResume() { + super.onResume(); + for (LifecycleListener lifecycleListener : lifecycleListeners) { + if (lifecycleListener != null) { + lifecycleListener.onResume(); + } + } + } +} diff --git a/android/libpag/src/main/java/org/extra/tools/LifecycleListener.java b/android/libpag/src/main/java/org/extra/tools/LifecycleListener.java new file mode 100644 index 0000000000..296f2d0692 --- /dev/null +++ b/android/libpag/src/main/java/org/extra/tools/LifecycleListener.java @@ -0,0 +1,5 @@ +package org.extra.tools; + +public interface LifecycleListener { + void onResume(); +} diff --git a/android/libpag/src/main/java/org/extra/tools/ScreenBroadcastReceiver.java b/android/libpag/src/main/java/org/extra/tools/ScreenBroadcastReceiver.java deleted file mode 100644 index 9ed2238310..0000000000 --- a/android/libpag/src/main/java/org/extra/tools/ScreenBroadcastReceiver.java +++ /dev/null @@ -1,68 +0,0 @@ -package org.extra.tools; - -import android.app.Application; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; - -public class ScreenBroadcastReceiver extends BroadcastReceiver { - private ScreenStateListener listener; - - ScreenBroadcastReceiver(ScreenStateListener listener) { - this.listener = listener; - } - - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - if (Intent.ACTION_SCREEN_ON.equals(action)) { - listener.onScreenOn(); - } else if (Intent.ACTION_SCREEN_OFF.equals(action)) { - listener.onScreenOff(); - } - } - - public void unregister() { - try { - Context context = getApplicationContext(); - if (context != null) { - context.unregisterReceiver(this); - } - } catch (Exception e) { - // - } - } - - public void register() { - IntentFilter filter = new IntentFilter(); - filter.addAction(Intent.ACTION_SCREEN_ON); - filter.addAction(Intent.ACTION_SCREEN_OFF); - try { - Context context = getApplicationContext(); - if (context != null) { - context.registerReceiver(this, filter); - } - } catch (Exception e) { - } - - } - - public interface ScreenStateListener { - void onScreenOn(); - - void onScreenOff(); - } - - private Context getApplicationContext() { - Context context = null; - try { - Application app = (Application) Class.forName("android.app.ActivityThread") - .getMethod("currentApplication").invoke(null, (Object[]) null); - context = app.getApplicationContext(); - } catch (Exception e) { - } - - return context; - } -} \ No newline at end of file diff --git a/android/libpag/src/main/java/org/libpag/PAGView.java b/android/libpag/src/main/java/org/libpag/PAGView.java index 975fdcbb8c..e2a4dcd417 100644 --- a/android/libpag/src/main/java/org/libpag/PAGView.java +++ b/android/libpag/src/main/java/org/libpag/PAGView.java @@ -20,14 +20,14 @@ import android.view.View; import android.view.animation.LinearInterpolator; -import org.extra.tools.BroadcastUtil; -import org.extra.tools.ScreenBroadcastReceiver; +import org.extra.tools.Lifecycle; +import org.extra.tools.LifecycleListener; import java.util.ArrayList; import java.util.List; -public class PAGView extends TextureView implements TextureView.SurfaceTextureListener, ScreenBroadcastReceiver.ScreenStateListener { +public class PAGView extends TextureView implements TextureView.SurfaceTextureListener, LifecycleListener { private final static String TAG = "PAGView"; private SurfaceTextureListener mListener; @@ -306,6 +306,7 @@ public void onAnimationRepeat(Animator animator) { }; private void setupSurfaceTexture() { + Lifecycle.getInstance().addListener(this); setOpaque(false); pagPlayer = new PAGPlayer(); setSurfaceTextureListener(this); @@ -406,7 +407,6 @@ protected void onAttachedToWindow() { isAttachedToWindow = true; super.onAttachedToWindow(); animator.addListener(mAnimatorListenerAdapter); - BroadcastUtil.getInstance().registerScreenBroadcast(this); synchronized (g_HandlerLock) { StartHandlerThread(); } @@ -417,7 +417,6 @@ protected void onAttachedToWindow() { protected void onDetachedFromWindow() { isAttachedToWindow = false; super.onDetachedFromWindow(); - BroadcastUtil.getInstance().unregisterScreenBroadcast(this); if (pagSurface != null) { // 延迟释放 pagSurface,否则Android 4.4 及之前版本会在 onDetachedFromWindow() 时 Crash。https://www.jianshu.com/p/675455c225bd pagSurface.release(); @@ -758,24 +757,6 @@ public void freeCache() { } } - @Override - public void onScreenOff() { - if (this.getVisibility() == View.VISIBLE) { - this.mSaveVisibleState = true; - // workaround 在有些手机上,如果不置成不可见,解锁以后画面会不可见 - // 在VIVO IQOO Pro表现为必现的不可见,在一加6t上表现为偶现不可见 - setVisibility(View.INVISIBLE); - } - } - - @Override - public void onScreenOn() { - if (this.mSaveVisibleState) { - this.setVisibility(View.VISIBLE); - } - this.mSaveVisibleState = false; - } - @Override public void setBackgroundDrawable(Drawable background) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N && background != null) { @@ -799,6 +780,16 @@ public void onVisibilityAggregated(boolean isVisible) { } } + @Override + public void onResume() { + // When the device is locked and then unlocked, the PAGView's content may disappear, + // use the following way to make the content appear. + if (isAttachedToWindow && getVisibility() == View.VISIBLE) { + setVisibility(View.INVISIBLE); + setVisibility(View.VISIBLE); + } + } + private void pauseAnimator() { if (_isAnimatorPreRunning == null) { _isAnimatorPreRunning = animator.isRunning(); @@ -817,8 +808,4 @@ private void resumeAnimator() { _isAnimatorPreRunning = null; doPlay(); } - - static { - BroadcastUtil.getInstance().registerScreenBroadcast(); - } }