This commit is contained in:
Mariotaku Lee 2017-03-01 09:11:56 +08:00
parent c765c47daf
commit 983913967c
No known key found for this signature in database
GPG Key ID: 15C10F89D7C33535
8 changed files with 68 additions and 41 deletions

View File

@ -51,7 +51,7 @@ import org.mariotaku.restfu.http.RestHttpClient
import org.mariotaku.twidere.BuildConfig import org.mariotaku.twidere.BuildConfig
import org.mariotaku.twidere.TwidereConstants.SHARED_PREFERENCES_NAME import org.mariotaku.twidere.TwidereConstants.SHARED_PREFERENCES_NAME
import org.mariotaku.twidere.activity.iface.IControlBarActivity import org.mariotaku.twidere.activity.iface.IControlBarActivity
import org.mariotaku.twidere.activity.iface.IExtendedActivity import org.mariotaku.twidere.activity.iface.IBaseActivity
import org.mariotaku.twidere.activity.iface.IThemedActivity import org.mariotaku.twidere.activity.iface.IThemedActivity
import org.mariotaku.twidere.constant.themeColorKey import org.mariotaku.twidere.constant.themeColorKey
import org.mariotaku.twidere.constant.themeKey import org.mariotaku.twidere.constant.themeKey
@ -72,7 +72,7 @@ import java.util.*
import javax.inject.Inject import javax.inject.Inject
@SuppressLint("Registered") @SuppressLint("Registered")
open class BaseActivity : ChameleonActivity(), IExtendedActivity<BaseActivity>, IThemedActivity, open class BaseActivity : ChameleonActivity(), IBaseActivity<BaseActivity>, IThemedActivity,
IControlBarActivity, OnFitSystemWindowsListener, SystemWindowsInsetsCallback, IControlBarActivity, OnFitSystemWindowsListener, SystemWindowsInsetsCallback,
KeyboardShortcutCallback, OnPreferenceDisplayDialogCallback { KeyboardShortcutCallback, OnPreferenceDisplayDialogCallback {
@ -103,7 +103,7 @@ open class BaseActivity : ChameleonActivity(), IExtendedActivity<BaseActivity>,
@Inject @Inject
lateinit var restHttpClient: RestHttpClient lateinit var restHttpClient: RestHttpClient
private val actionHelper = IExtendedActivity.ActionHelper(this) private val actionHelper = IBaseActivity.ActionHelper(this)
// Registered listeners // Registered listeners
private val controlBarOffsetListeners = ArrayList<IControlBarActivity.ControlBarOffsetListener>() private val controlBarOffsetListeners = ArrayList<IControlBarActivity.ControlBarOffsetListener>()
@ -261,8 +261,8 @@ open class BaseActivity : ChameleonActivity(), IExtendedActivity<BaseActivity>,
actionHelper.dispatchOnResumeFragments() actionHelper.dispatchOnResumeFragments()
} }
override fun executeAfterFragmentResumed(action: (BaseActivity) -> Unit) { override fun executeAfterFragmentResumed(useHandler: Boolean, action: (BaseActivity) -> Unit) {
actionHelper.executeAfterFragmentResumed(action) actionHelper.executeAfterFragmentResumed(useHandler, action)
} }
override final val currentThemeBackgroundAlpha by lazy { override final val currentThemeBackgroundAlpha by lazy {

View File

@ -46,8 +46,8 @@ import org.mariotaku.mediaviewer.library.*
import org.mariotaku.mediaviewer.library.subsampleimageview.SubsampleImageViewerFragment.EXTRA_MEDIA_URI import org.mariotaku.mediaviewer.library.subsampleimageview.SubsampleImageViewerFragment.EXTRA_MEDIA_URI
import org.mariotaku.twidere.R import org.mariotaku.twidere.R
import org.mariotaku.twidere.TwidereConstants.* import org.mariotaku.twidere.TwidereConstants.*
import org.mariotaku.twidere.activity.iface.IBaseActivity
import org.mariotaku.twidere.activity.iface.IControlBarActivity.ControlBarShowHideHelper import org.mariotaku.twidere.activity.iface.IControlBarActivity.ControlBarShowHideHelper
import org.mariotaku.twidere.activity.iface.IExtendedActivity
import org.mariotaku.twidere.annotation.CacheFileType import org.mariotaku.twidere.annotation.CacheFileType
import org.mariotaku.twidere.fragment.PermissionRequestDialog import org.mariotaku.twidere.fragment.PermissionRequestDialog
import org.mariotaku.twidere.fragment.ProgressDialogFragment import org.mariotaku.twidere.fragment.ProgressDialogFragment
@ -450,7 +450,7 @@ class MediaViewerActivity : BaseActivity(), IMediaViewerActivity, MediaSwipeClos
private val PROGRESS_FRAGMENT_TAG = "progress" private val PROGRESS_FRAGMENT_TAG = "progress"
override fun dismissProgress() { override fun dismissProgress() {
val activity = context as IExtendedActivity<*> val activity = context as IBaseActivity<*>
activity.executeAfterFragmentResumed { activity -> activity.executeAfterFragmentResumed { activity ->
val fm = activity.supportFragmentManager val fm = activity.supportFragmentManager
val fragment = fm.findFragmentByTag(PROGRESS_FRAGMENT_TAG) as? DialogFragment val fragment = fm.findFragmentByTag(PROGRESS_FRAGMENT_TAG) as? DialogFragment
@ -459,7 +459,7 @@ class MediaViewerActivity : BaseActivity(), IMediaViewerActivity, MediaSwipeClos
} }
override fun showProgress() { override fun showProgress() {
val activity = context as IExtendedActivity<*> val activity = context as IBaseActivity<*>
activity.executeAfterFragmentResumed { activity -> activity.executeAfterFragmentResumed { activity ->
val fragment = ProgressDialogFragment() val fragment = ProgressDialogFragment()
fragment.isCancelable = false fragment.isCancelable = false

View File

@ -27,14 +27,14 @@ import java.util.*
/** /**
* Created by mariotaku on 15/12/28. * Created by mariotaku on 15/12/28.
*/ */
interface IExtendedActivity<out A : FragmentActivity> { interface IBaseActivity<out A : FragmentActivity> {
fun executeAfterFragmentResumed(action: (A) -> Unit) fun executeAfterFragmentResumed(useHandler: Boolean = false, action: (A) -> Unit)
class ActionHelper<out A : FragmentActivity>(private val activity: A) { class ActionHelper<out A : FragmentActivity>(private val activity: A) {
private var fragmentResumed: Boolean = false private var fragmentResumed: Boolean = false
private val actionQueue = LinkedList<(A) -> Unit>() private val actionQueue = LinkedList<ExecuteInfo<A>>()
private val handler = Handler(Looper.getMainLooper()) private val handler = Handler(Looper.getMainLooper())
fun dispatchOnPause() { fun dispatchOnPause() {
@ -49,19 +49,25 @@ interface IExtendedActivity<out A : FragmentActivity> {
private fun executePending() { private fun executePending() {
if (!fragmentResumed) return if (!fragmentResumed) return
var action: ((A) -> Unit)? var info: ExecuteInfo<A>?
do { do {
action = actionQueue.poll() val cur = actionQueue.poll()
// Sometimes actions called too fast, so we wait for next loop cur?.let { cur ->
handler.post { if (cur.useHandler) {
action?.invoke(activity) handler.post { cur.action(activity) }
} else {
cur.action(activity)
}
} }
} while (action != null) info = cur
} while (info != null)
} }
fun executeAfterFragmentResumed(action: (A) -> Unit) { fun executeAfterFragmentResumed(useHandler: Boolean = false, action: (A) -> Unit) {
actionQueue.add(action) actionQueue.add(ExecuteInfo(action, useHandler))
executePending() executePending()
} }
private data class ExecuteInfo<in A : FragmentActivity>(val action: (A) -> Unit, val useHandler: Boolean)
} }
} }

View File

@ -46,7 +46,7 @@ import org.mariotaku.kpreferences.get
import org.mariotaku.sqliteqb.library.Expression import org.mariotaku.sqliteqb.library.Expression
import org.mariotaku.twidere.R import org.mariotaku.twidere.R
import org.mariotaku.twidere.TwidereConstants.* import org.mariotaku.twidere.TwidereConstants.*
import org.mariotaku.twidere.activity.iface.IExtendedActivity import org.mariotaku.twidere.activity.iface.IBaseActivity
import org.mariotaku.twidere.adapter.DraftsAdapter import org.mariotaku.twidere.adapter.DraftsAdapter
import org.mariotaku.twidere.constant.IntentConstants import org.mariotaku.twidere.constant.IntentConstants
import org.mariotaku.twidere.constant.textSizeKey import org.mariotaku.twidere.constant.textSizeKey
@ -244,7 +244,7 @@ class DraftsFragment : BaseFragment(), LoaderCallbacks<Cursor?>, OnItemClickList
override fun onPreExecute() { override fun onPreExecute() {
val activity = activityRef.get() ?: return val activity = activityRef.get() ?: return
(activity as IExtendedActivity<*>).executeAfterFragmentResumed { activity -> (activity as IBaseActivity<*>).executeAfterFragmentResumed { activity ->
val f = ProgressDialogFragment.show(activity.supportFragmentManager, FRAGMENT_TAG_DELETING_DRAFTS) val f = ProgressDialogFragment.show(activity.supportFragmentManager, FRAGMENT_TAG_DELETING_DRAFTS)
f.isCancelable = false f.isCancelable = false
} }
@ -252,7 +252,7 @@ class DraftsFragment : BaseFragment(), LoaderCallbacks<Cursor?>, OnItemClickList
override fun onPostExecute(result: Unit) { override fun onPostExecute(result: Unit) {
val activity = activityRef.get() ?: return val activity = activityRef.get() ?: return
(activity as IExtendedActivity<*>).executeAfterFragmentResumed { activity -> (activity as IBaseActivity<*>).executeAfterFragmentResumed { activity ->
val fm = activity.supportFragmentManager val fm = activity.supportFragmentManager
val f = fm.findFragmentByTag(FRAGMENT_TAG_DELETING_DRAFTS) val f = fm.findFragmentByTag(FRAGMENT_TAG_DELETING_DRAFTS)
if (f is DialogFragment) { if (f is DialogFragment) {

View File

@ -95,7 +95,7 @@ import org.mariotaku.twidere.activity.AccountSelectorActivity
import org.mariotaku.twidere.activity.BaseActivity import org.mariotaku.twidere.activity.BaseActivity
import org.mariotaku.twidere.activity.ColorPickerDialogActivity import org.mariotaku.twidere.activity.ColorPickerDialogActivity
import org.mariotaku.twidere.activity.LinkHandlerActivity import org.mariotaku.twidere.activity.LinkHandlerActivity
import org.mariotaku.twidere.activity.iface.IExtendedActivity import org.mariotaku.twidere.activity.iface.IBaseActivity
import org.mariotaku.twidere.adapter.SupportTabsAdapter import org.mariotaku.twidere.adapter.SupportTabsAdapter
import org.mariotaku.twidere.annotation.AccountType import org.mariotaku.twidere.annotation.AccountType
import org.mariotaku.twidere.annotation.Referral import org.mariotaku.twidere.annotation.Referral
@ -1652,7 +1652,7 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener,
val checkedPositions = dialog.listView.checkedItemPositions val checkedPositions = dialog.listView.checkedItemPositions
val weakActivity = WeakReference(activity) val weakActivity = WeakReference(activity)
promiseOnUi { promiseOnUi {
val activity = weakActivity.get() as? IExtendedActivity<*> ?: return@promiseOnUi val activity = weakActivity.get() as? IBaseActivity<*> ?: return@promiseOnUi
activity.executeAfterFragmentResumed { activity -> activity.executeAfterFragmentResumed { activity ->
ProgressDialogFragment.show(activity.supportFragmentManager, "update_lists_progress") ProgressDialogFragment.show(activity.supportFragmentManager, "update_lists_progress")
} }
@ -1677,7 +1677,7 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener,
throw UpdateListsException(successfulStates) throw UpdateListsException(successfulStates)
} }
}.alwaysUi { }.alwaysUi {
val activity = weakActivity.get() as? IExtendedActivity<*> ?: return@alwaysUi val activity = weakActivity.get() as? IBaseActivity<*> ?: return@alwaysUi
activity.executeAfterFragmentResumed { activity -> activity.executeAfterFragmentResumed { activity ->
val manager = activity.supportFragmentManager val manager = activity.supportFragmentManager
val df = manager.findFragmentByTag("update_lists_progress") as? DialogFragment val df = manager.findFragmentByTag("update_lists_progress") as? DialogFragment

View File

@ -84,15 +84,18 @@ interface IBaseFragment<out F : Fragment> {
private fun executePending() { private fun executePending() {
if (!fragmentResumed) return if (!fragmentResumed) return
var info: ExecuteInfo<F> var info: ExecuteInfo<F>?
while (true) { do {
info = actionQueue.poll() ?: break val cur = actionQueue.poll()
if (info.useHandler) { cur?.let { cur ->
handler.post { info.action(fragment) } if (cur.useHandler) {
} else { handler.post { cur.action(fragment) }
info.action(fragment) } else {
cur.action(fragment)
}
} }
} info = cur
} while (info != null)
} }
fun executeAfterFragmentResumed(useHandler: Boolean = false, action: (F) -> Unit) { fun executeAfterFragmentResumed(useHandler: Boolean = false, action: (F) -> Unit) {

View File

@ -33,6 +33,7 @@ import android.view.ViewGroup
import com.google.android.exoplayer2.* import com.google.android.exoplayer2.*
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory
import com.google.android.exoplayer2.source.ExtractorMediaSource import com.google.android.exoplayer2.source.ExtractorMediaSource
import com.google.android.exoplayer2.source.LoopingMediaSource
import com.google.android.exoplayer2.source.TrackGroupArray import com.google.android.exoplayer2.source.TrackGroupArray
import com.google.android.exoplayer2.trackselection.AdaptiveVideoTrackSelection import com.google.android.exoplayer2.trackselection.AdaptiveVideoTrackSelection
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector import com.google.android.exoplayer2.trackselection.DefaultTrackSelector
@ -49,6 +50,8 @@ import org.mariotaku.twidere.constant.IntentConstants.EXTRA_POSITION
import org.mariotaku.twidere.fragment.iface.IBaseFragment import org.mariotaku.twidere.fragment.iface.IBaseFragment
import org.mariotaku.twidere.fragment.media.VideoPageFragment.Companion.EXTRA_PAUSED_BY_USER import org.mariotaku.twidere.fragment.media.VideoPageFragment.Companion.EXTRA_PAUSED_BY_USER
import org.mariotaku.twidere.fragment.media.VideoPageFragment.Companion.EXTRA_PLAY_AUDIO import org.mariotaku.twidere.fragment.media.VideoPageFragment.Companion.EXTRA_PLAY_AUDIO
import org.mariotaku.twidere.fragment.media.VideoPageFragment.Companion.isControlDisabled
import org.mariotaku.twidere.fragment.media.VideoPageFragment.Companion.isLoopEnabled
import org.mariotaku.twidere.fragment.media.VideoPageFragment.Companion.isMutedByDefault import org.mariotaku.twidere.fragment.media.VideoPageFragment.Companion.isMutedByDefault
import org.mariotaku.twidere.fragment.media.VideoPageFragment.Companion.media import org.mariotaku.twidere.fragment.media.VideoPageFragment.Companion.media
import org.mariotaku.twidere.util.UserAgentUtils import org.mariotaku.twidere.util.UserAgentUtils
@ -97,7 +100,7 @@ class ExoPlayerPageFragment : MediaViewerFragment(), IBaseFragment<ExoPlayerPage
playbackCompleted = playWhenReady playbackCompleted = playWhenReady
hideProgress() hideProgress()
} }
else -> { ExoPlayer.STATE_IDLE -> {
hideProgress() hideProgress()
} }
} }
@ -134,6 +137,7 @@ class ExoPlayerPageFragment : MediaViewerFragment(), IBaseFragment<ExoPlayerPage
this.playAudio = !this.playAudio this.playAudio = !this.playAudio
updateVolume() updateVolume()
} }
playerView.useController = !isControlDisabled
updateVolume() updateVolume()
} }
@ -158,7 +162,6 @@ class ExoPlayerPageFragment : MediaViewerFragment(), IBaseFragment<ExoPlayerPage
} }
} }
override fun onStop() { override fun onStop() {
super.onStop() super.onStop()
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) { if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {
@ -166,6 +169,17 @@ class ExoPlayerPageFragment : MediaViewerFragment(), IBaseFragment<ExoPlayerPage
} }
} }
override fun setUserVisibleHint(isVisibleToUser: Boolean) {
super.setUserVisibleHint(isVisibleToUser)
if (activity != null && !isDetached) {
if (isVisibleToUser) {
initializePlayer()
} else {
releasePlayer()
}
}
}
override fun onCreateMediaView(inflater: LayoutInflater, parent: ViewGroup?, savedInstanceState: Bundle?): View { override fun onCreateMediaView(inflater: LayoutInflater, parent: ViewGroup?, savedInstanceState: Bundle?): View {
return inflater.inflate(R.layout.layout_media_viewer_exo_player_view, parent, false) return inflater.inflate(R.layout.layout_media_viewer_exo_player_view, parent, false)
} }
@ -203,7 +217,7 @@ class ExoPlayerPageFragment : MediaViewerFragment(), IBaseFragment<ExoPlayerPage
positionBackup = player.currentPosition positionBackup = player.currentPosition
pausedByUser = !player.playWhenReady pausedByUser = !player.playWhenReady
player.removeListener(playerListener) player.removeListener(playerListener)
player.release(); player.release()
playerView.player = null playerView.player = null
} }
@ -223,9 +237,13 @@ class ExoPlayerPageFragment : MediaViewerFragment(), IBaseFragment<ExoPlayerPage
} }
val uri = getDownloadUri() ?: return val uri = getDownloadUri() ?: return
val mediaSource = ExtractorMediaSource(uri, mediaDataSourceFactory, DefaultExtractorsFactory(), val uriSource = ExtractorMediaSource(uri, mediaDataSourceFactory, DefaultExtractorsFactory(),
null, null) null, null)
playerView.player.prepare(mediaSource) if (isLoopEnabled) {
playerView.player.prepare(LoopingMediaSource(uriSource))
} else {
playerView.player.prepare(uriSource)
}
updateVolume() updateVolume()
} }

View File

@ -22,7 +22,7 @@ package org.mariotaku.twidere.task
import android.content.Context import android.content.Context
import android.net.Uri import android.net.Uri
import android.support.v4.app.DialogFragment import android.support.v4.app.DialogFragment
import org.mariotaku.twidere.activity.iface.IExtendedActivity import org.mariotaku.twidere.activity.iface.IBaseActivity
import org.mariotaku.twidere.fragment.ProgressDialogFragment import org.mariotaku.twidere.fragment.ProgressDialogFragment
import java.io.File import java.io.File
@ -37,7 +37,7 @@ abstract class ProgressSaveFileTask(
) : SaveFileTask(context, source, destination, getMimeType) { ) : SaveFileTask(context, source, destination, getMimeType) {
override fun showProgress() { override fun showProgress() {
(context as IExtendedActivity<*>).executeAfterFragmentResumed { activity -> (context as IBaseActivity<*>).executeAfterFragmentResumed { activity ->
val fragment = ProgressDialogFragment() val fragment = ProgressDialogFragment()
fragment.isCancelable = false fragment.isCancelable = false
fragment.show(activity.supportFragmentManager, PROGRESS_FRAGMENT_TAG) fragment.show(activity.supportFragmentManager, PROGRESS_FRAGMENT_TAG)
@ -45,7 +45,7 @@ abstract class ProgressSaveFileTask(
} }
override fun dismissProgress() { override fun dismissProgress() {
(context as IExtendedActivity<*>).executeAfterFragmentResumed { activity -> (context as IBaseActivity<*>).executeAfterFragmentResumed { activity ->
val fm = activity.supportFragmentManager val fm = activity.supportFragmentManager
val fragment = fm.findFragmentByTag(PROGRESS_FRAGMENT_TAG) as? DialogFragment val fragment = fm.findFragmentByTag(PROGRESS_FRAGMENT_TAG) as? DialogFragment
fragment?.dismiss() fragment?.dismiss()