diff --git a/README.md b/README.md
index 5c1393b3..b9dea27c 100644
--- a/README.md
+++ b/README.md
@@ -13,6 +13,9 @@
+
+
+
@@ -61,7 +64,7 @@
* #### ⭐**Star**鼓励开发者
* #### 👁️Watch关注开发进度
* #### 📇Pull requests(**请尽量贴合项目的源码和commit风格**)
-* #### 💡加入[群组](https://discord.com/invite/K5GN7FaQuX)讨论反馈
+* #### 💡加入[群组](https://pd.qq.com/s/1cii5y637)讨论反馈
## 安全说明
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index a0db391c..1946b029 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -5,6 +5,7 @@
+
diff --git a/app/src/main/java/com/su/mediabox/App.kt b/app/src/main/java/com/su/mediabox/App.kt
index 1723fecd..35dba4a4 100644
--- a/app/src/main/java/com/su/mediabox/App.kt
+++ b/app/src/main/java/com/su/mediabox/App.kt
@@ -3,6 +3,8 @@ package com.su.mediabox
import android.annotation.SuppressLint
import android.app.Application
import android.content.Context
+import android.os.Handler
+import android.os.Looper
import android.util.Log
import android.webkit.WebView
import com.liulishuo.filedownloader.FileDownloader
@@ -83,6 +85,7 @@ class App : Application() {
companion object {
@SuppressLint("StaticFieldLeak")
lateinit var context: Context
+ val mainHandler = Handler(Looper.getMainLooper())
init {
// 防止内存泄漏
diff --git a/app/src/main/java/com/su/mediabox/config/Const.kt b/app/src/main/java/com/su/mediabox/config/Const.kt
index a74e7409..cc85e4fb 100644
--- a/app/src/main/java/com/su/mediabox/config/Const.kt
+++ b/app/src/main/java/com/su/mediabox/config/Const.kt
@@ -31,7 +31,7 @@ interface Const {
"https://ryensx.github.io/MediaBoxPluginRepository/"
const val GITHUB_PLUGIN_REPO_DEV_DOC_URL = "https://github.com/RyensX/MediaBox/wiki"
const val USER_NOTICE_VERSION = 2
- const val GROUP_URL = "https://discord.com/invite/K5GN7FaQuX"
+ const val GROUP_URL = "https://pd.qq.com/s/1cii5y637"
const val ANNOUNCEMENT="https://raw.githubusercontent.com/RyensX/MediaBox/dev/doc/announcement.json"
val licenses = listOf(
diff --git a/app/src/main/java/com/su/mediabox/net/DnsServer.kt b/app/src/main/java/com/su/mediabox/net/DnsServer.kt
index 7ffbe762..801e7e07 100644
--- a/app/src/main/java/com/su/mediabox/net/DnsServer.kt
+++ b/app/src/main/java/com/su/mediabox/net/DnsServer.kt
@@ -29,7 +29,7 @@ object DnsServer {
override fun equals(other: Any?): Boolean {
return when (other) {
null -> false
- other === this -> true
+ (other === this) -> true
is String -> other == dnsServer
is Dns -> other.dnsServer == this.dnsServer && other.dnsName == this.dnsName
else -> false
diff --git a/app/src/main/java/com/su/mediabox/plugin/Plugin.kt b/app/src/main/java/com/su/mediabox/plugin/Plugin.kt
index 74b32155..85d93ce5 100644
--- a/app/src/main/java/com/su/mediabox/plugin/Plugin.kt
+++ b/app/src/main/java/com/su/mediabox/plugin/Plugin.kt
@@ -40,6 +40,8 @@ import java.io.File
object PluginManager {
+ private const val TAG = "PluginManager"
+
val appApiVersion by unsafeLazy {
val appInfo: ApplicationInfo = App.context.packageManager
.getApplicationInfo(
@@ -284,7 +286,7 @@ object PluginManager {
* @param pluginInfo 至少要保证包含有效[PluginInfo.sourcePath](作为下载地址)
* @param directInstall 直接下载安装,一般只用于官方仓库插件,不经安装器验证直接安装
*/
- fun downloadPlugin(pluginInfo: PluginInfo, directInstall: Boolean = false) {
+ fun downloadPlugin(pluginInfo: PluginInfo, directInstall: Boolean = false) = runCatching {
val downloadManager =
App.context.getSystemService(AppCompatActivity.DOWNLOAD_SERVICE) as DownloadManager
val uri: Uri = Uri
@@ -302,6 +304,10 @@ object PluginManager {
setAllowedOverRoaming(true)
}
downloadManager.enqueue(request)
+ }.onFailure {
+ logE(TAG, "downloadPlugin: error=${it.message} directInstall=$directInstall pluginInfo=$pluginInfo")
+ "插件下载失败: ${it.message}".showToast()
+ it.printStackTrace()
}
fun initPluginEnv() {
diff --git a/app/src/main/java/com/su/mediabox/util/Activity.kt b/app/src/main/java/com/su/mediabox/util/Activity.kt
index 31da630c..0f5610c8 100644
--- a/app/src/main/java/com/su/mediabox/util/Activity.kt
+++ b/app/src/main/java/com/su/mediabox/util/Activity.kt
@@ -29,12 +29,12 @@ fun putAction(action: T) {
}
@Suppress("UNCHECKED_CAST")
-fun getActionIns(actionClass: Class): T? =
+fun consumeActionIns(actionClass: Class): T? =
(actionPoolMap[actionClass.simpleName] as? T)?.also {
actionPoolMap.remove(actionClass.simpleName)
}
-inline fun getAction(): T? = getActionIns(T::class.java)
+inline fun consumeAction(): T? = consumeActionIns(T::class.java)
fun Activity.viewBind(inflater: (LayoutInflater) -> VB) =
lazy(LazyThreadSafetyMode.NONE) {
diff --git a/app/src/main/java/com/su/mediabox/util/CoroutineUtil.kt b/app/src/main/java/com/su/mediabox/util/CoroutineUtil.kt
index 317707d7..6b6645c7 100644
--- a/app/src/main/java/com/su/mediabox/util/CoroutineUtil.kt
+++ b/app/src/main/java/com/su/mediabox/util/CoroutineUtil.kt
@@ -52,10 +52,10 @@ private class ViewCoroutineInterceptor(
private class ViewStateListener(private val view: View, private val job: Job) :
View.OnAttachStateChangeListener, CompletionHandler {
- override fun onViewAttachedToWindow(v: View?) {}
+ override fun onViewAttachedToWindow(v: View) {}
//在Recyclerview上使用LinearLayoutManager可能并不会调用,取决于mRecycleChildrenOnDetach,因此必须手动调用setRecycleChildrenOnDetach(true)
- override fun onViewDetachedFromWindow(v: View?) {
+ override fun onViewDetachedFromWindow(v: View) {
logD("View协程", "分离视图->取消")
view.removeOnAttachStateChangeListener(this)
job.cancel()
diff --git a/app/src/main/java/com/su/mediabox/util/coil/CoilUtil.kt b/app/src/main/java/com/su/mediabox/util/coil/CoilUtil.kt
index e5180a51..3f3aceb0 100644
--- a/app/src/main/java/com/su/mediabox/util/coil/CoilUtil.kt
+++ b/app/src/main/java/com/su/mediabox/util/coil/CoilUtil.kt
@@ -53,6 +53,7 @@ object CoilUtil {
logE("loadImage", "图片来源有误!")
return@runCatching
}
+ logD("加载图片","url=$urlOrBase64")
val time = System.currentTimeMillis()
when {
urlOrBase64.startsWith("data:image") -> {
@@ -90,10 +91,10 @@ object CoilUtil {
?.let {
addHeader("Referer", it)
}
- addHeader("Host", URL(urlOrBase64).host)
- addHeader("Accept", "*/*")
- addHeader("Accept-Encoding", "gzip, deflate")
- addHeader("Connection", "keep-alive")
+// addHeader("Host", URL(urlOrBase64).host)
+// addHeader("Accept", "*/*")
+// addHeader("Accept-Encoding", "gzip, deflate")
+// addHeader("Connection", "keep-alive")
addHeader("User-Agent", Constant.Request.getRandomUserAgent())
listener { _, _ ->
logD("图片加载完毕", "time=$time url=$urlOrBase64", false)
diff --git a/app/src/main/java/com/su/mediabox/util/html/source/web/GettingWebView.kt b/app/src/main/java/com/su/mediabox/util/html/source/web/GettingWebView.kt
index d87308ed..c0c3b87f 100644
--- a/app/src/main/java/com/su/mediabox/util/html/source/web/GettingWebView.kt
+++ b/app/src/main/java/com/su/mediabox/util/html/source/web/GettingWebView.kt
@@ -40,8 +40,6 @@ class GettingWebView @JvmOverloads constructor(
}
mWebSettings.javaScriptCanOpenWindowsAutomatically = true
mWebSettings.loadsImagesAutomatically = false
- mWebSettings.setAppCacheEnabled(true)
- mWebSettings.setAppCachePath(context.cacheDir.absolutePath)
mWebSettings.databaseEnabled = true
mWebSettings.setGeolocationDatabasePath(context.getDir("database", 0).path)
mWebSettings.setGeolocationEnabled(true)
diff --git a/app/src/main/java/com/su/mediabox/view/activity/MediaClassifyActivity.kt b/app/src/main/java/com/su/mediabox/view/activity/MediaClassifyActivity.kt
index cca3dfaf..e36452c1 100644
--- a/app/src/main/java/com/su/mediabox/view/activity/MediaClassifyActivity.kt
+++ b/app/src/main/java/com/su/mediabox/view/activity/MediaClassifyActivity.kt
@@ -128,11 +128,12 @@ class MediaClassifyActivity : BasePluginActivity() {
mBinding.mediaClassifyFabProgress.invisible()
"加载分类错误:${it.throwable?.message}".showToast()
}
+ else -> {}
}
}
//如果传入分类,则直接开始加载分类数据,否则自动加载分类项数据并打开弹窗
- getAction()?.also {
+ consumeAction()?.also {
mediaClassify.currentClassifyAction = it
viewModel.getClassifyData(it)
} ?: viewModel.getClassifyItemData()
diff --git a/app/src/main/java/com/su/mediabox/view/activity/MediaDetailActivity.kt b/app/src/main/java/com/su/mediabox/view/activity/MediaDetailActivity.kt
index dc57dde3..723aeca3 100644
--- a/app/src/main/java/com/su/mediabox/view/activity/MediaDetailActivity.kt
+++ b/app/src/main/java/com/su/mediabox/view/activity/MediaDetailActivity.kt
@@ -32,7 +32,7 @@ class MediaDetailActivity : BasePluginActivity() {
logD("获取VM", "@${viewModel}")
- getAction()?.also {
+ consumeAction()?.also {
viewModel.partUrl = it.url
}
@@ -111,7 +111,7 @@ class MediaDetailActivity : BasePluginActivity() {
override fun startActivity(intent: Intent?, options: Bundle?) {
//主动向下一级路由目标提供一些信息
intent?.apply {
- getAction()?.apply {
+ consumeAction()?.apply {
coverUrl = viewModel.cover
detailPartUrl = viewModel.partUrl
videoName = viewModel.title
diff --git a/app/src/main/java/com/su/mediabox/view/activity/MediaSearchActivity.kt b/app/src/main/java/com/su/mediabox/view/activity/MediaSearchActivity.kt
index a92cc1be..6c88f2e8 100644
--- a/app/src/main/java/com/su/mediabox/view/activity/MediaSearchActivity.kt
+++ b/app/src/main/java/com/su/mediabox/view/activity/MediaSearchActivity.kt
@@ -133,7 +133,7 @@ class MediaSearchActivity : BasePluginActivity() {
}
}
- getAction()?.also {
+ consumeAction()?.also {
viewModel.getSearchData(it.keyWork)
}
}
diff --git a/app/src/main/java/com/su/mediabox/view/activity/VideoMediaPlayActivity.kt b/app/src/main/java/com/su/mediabox/view/activity/VideoMediaPlayActivity.kt
index bff5558d..0b1492b2 100644
--- a/app/src/main/java/com/su/mediabox/view/activity/VideoMediaPlayActivity.kt
+++ b/app/src/main/java/com/su/mediabox/view/activity/VideoMediaPlayActivity.kt
@@ -36,7 +36,6 @@ class VideoMediaPlayActivity : BasePluginActivity(),
VideoMediaPlayer.PlayOperatingProxy {
companion object {
- var playList: List? = null
private const val DEFAULT_SEEK_LENGTH = 15000L
const val DEFAULT_VIDEO_PRELOAD_SIZE = 5
}
@@ -63,10 +62,12 @@ class VideoMediaPlayActivity : BasePluginActivity(),
setFullScreen(window)
- getAction()?.also { action ->
+ consumeAction()?.also { action ->
this.action = action
init()
viewModel.apply {
+ val playList = action.extraData as? List
+ playList?.let { init(it) }
detailPartUrl = action.detailPartUrl
coverUrl = action.coverUrl
videoName = action.videoName
@@ -85,6 +86,7 @@ class VideoMediaPlayActivity : BasePluginActivity(),
}
visible()
}
+
is DataState.Success -> dataState.data?.also {
mBinding.vmPlay.playVideo(
it.videoPlayUrl,
@@ -93,6 +95,7 @@ class VideoMediaPlayActivity : BasePluginActivity(),
mBinding.vmLoadingLayer.gone()
mBinding.vmErrorRetry.gone()
}
+
is DataState.Failed -> {
dataState.throwable?.message?.showToast()
mBinding.vmLoadingLayer.apply {
@@ -102,6 +105,7 @@ class VideoMediaPlayActivity : BasePluginActivity(),
visible()
}
}
+
else -> Unit
}
}
@@ -211,6 +215,7 @@ class VideoMediaPlayActivity : BasePluginActivity(),
onVideoResume()
}
}
+
KeyEvent.KEYCODE_DPAD_LEFT, KeyEvent.KEYCODE_MEDIA_STEP_BACKWARD ->
//减速
if (event?.isShiftPressed == true) {
@@ -270,8 +275,6 @@ class VideoMediaPlayActivity : BasePluginActivity(),
mBinding.vmPlay.setVideoAllCallBack(null)
GSYVideoManager.releaseAllVideos()
orientationUtils.releaseListener()
- //释放播放列表
- playList = null
}
super.onDestroy()
}
diff --git a/app/src/main/java/com/su/mediabox/view/activity/WebViewActivity.kt b/app/src/main/java/com/su/mediabox/view/activity/WebViewActivity.kt
index abaf9f14..adec5a7f 100644
--- a/app/src/main/java/com/su/mediabox/view/activity/WebViewActivity.kt
+++ b/app/src/main/java/com/su/mediabox/view/activity/WebViewActivity.kt
@@ -12,7 +12,7 @@ import com.su.mediabox.databinding.ActivityWebViewBinding
import com.su.mediabox.plugin.WebUtilImpl.clearWeb
import com.su.mediabox.pluginapi.action.WebBrowserAction
import com.su.mediabox.util.Util.openUrl
-import com.su.mediabox.util.getAction
+import com.su.mediabox.util.consumeAction
import com.su.mediabox.util.logD
import com.su.mediabox.util.logE
import com.su.mediabox.util.viewBind
@@ -27,7 +27,7 @@ class WebViewActivity : BasePluginActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- mAction = getAction() ?: run {
+ mAction = consumeAction() ?: run {
finish()
return
}
diff --git a/app/src/main/java/com/su/mediabox/view/component/PointView.kt b/app/src/main/java/com/su/mediabox/view/component/PointView.kt
index 51e6b868..128b75ef 100644
--- a/app/src/main/java/com/su/mediabox/view/component/PointView.kt
+++ b/app/src/main/java/com/su/mediabox/view/component/PointView.kt
@@ -31,10 +31,10 @@ class PointView(context: Context, attributeSet: AttributeSet) : View(context, at
}
get() = paint.color
- override fun onDraw(canvas: Canvas?) {
+ override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
val radius = pointSize / 2
- canvas?.drawCircle(width / 2F, height / 2F, radius, paint)
+ canvas.drawCircle(width / 2F, height / 2F, radius, paint)
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
diff --git a/app/src/main/java/com/su/mediabox/view/component/player/VideoMediaPlayer.kt b/app/src/main/java/com/su/mediabox/view/component/player/VideoMediaPlayer.kt
index 63b66c11..810150aa 100644
--- a/app/src/main/java/com/su/mediabox/view/component/player/VideoMediaPlayer.kt
+++ b/app/src/main/java/com/su/mediabox/view/component/player/VideoMediaPlayer.kt
@@ -42,6 +42,7 @@ import com.su.mediabox.view.component.ZoomView
import com.su.mediabox.view.component.player.autoSkip.VideoAutoSkipViewController
import com.su.mediabox.view.component.textview.TypefaceTextView
import com.su.mediabox.view.listener.dsl.setOnSeekBarChangeListener
+import com.su.mediabox.viewmodel.VideoMediaPlayViewModel
import kotlinx.coroutines.*
import java.io.File
import kotlin.math.abs
@@ -426,14 +427,15 @@ open class VideoMediaPlayer : StandardGSYVideoPlayer {
tvEpisode = findViewById(R.id.tv_episode)
//播放列表
tvEpisode?.apply {
+ val playList = VideoMediaPlayViewModel.getCurrentPlayList(context)
//只有存在选集数据和VM才显示选集
- if (VideoMediaPlayActivity.playList == null || playOperatingProxy == null) {
+ if (playList == null || playOperatingProxy == null) {
gone()
return@apply
}
visible()
rvEpisode
- ?.grid(if (VideoMediaPlayActivity.playList!!.size > 8) 4 else 1)
+ ?.grid(if (playList.size > 8) 4 else 1)
?.initTypeList(DataViewMapList().registerDataViewMap()) {
vHCreateDSL {
setOnClickListener(itemView) { pos ->
@@ -478,7 +480,7 @@ open class VideoMediaPlayer : StandardGSYVideoPlayer {
//为了使下一集按钮有效,需要在第一次加载时初始化播放列表的初始定位
playPositionMemoryStoreCoroutineScope.launch {
//查找初始定位
- VideoMediaPlayActivity.playList?.forEachIndexed { index, episodeData ->
+ VideoMediaPlayViewModel.getCurrentPlayList(context)?.forEachIndexed { index, episodeData ->
if (episodeData.url.isNotBlank() && episodeData.url == playOperatingProxy?.currentPlayEpisodeUrl) {
logD("找到初始标记", index.toString())
rvEpisode?.typeAdapter()?.setTag(index)
@@ -500,8 +502,8 @@ open class VideoMediaPlayer : StandardGSYVideoPlayer {
fun playNextEpisode(): Boolean {
val episodeAdapter = rvEpisode?.typeAdapter()
episodeAdapter?.getTag()?.also { pos ->
- if (pos < (VideoMediaPlayActivity.playList?.size ?: pos) - 1)
- VideoMediaPlayActivity.playList?.getOrNull(pos + 1)?.url?.also {
+ if (pos < (VideoMediaPlayViewModel.getCurrentPlayList(context)?.size ?: pos) - 1)
+ VideoMediaPlayViewModel.getCurrentPlayList(context)?.getOrNull(pos + 1)?.url?.also {
currentPlayer.onVideoPause()
episodeAdapter.apply {
//更新上次选项
@@ -784,12 +786,15 @@ open class VideoMediaPlayer : StandardGSYVideoPlayer {
NO_REVERSE -> { // 正常
transform.setScale(1f, 1f, mTextureView.width / 2.toFloat(), 0f)
}
+
HORIZONTAL_REVERSE -> { // 左右镜像
transform.setScale(-1f, 1f, mTextureView.width / 2.toFloat(), 0f)
}
+
VERTICAL_REVERSE -> { // 上下镜像
transform.setScale(1f, -1f, 0f, mTextureView.height / 2.toFloat())
}
+
else -> return
}
mTextureViewTransform = transformSize
@@ -819,12 +824,15 @@ open class VideoMediaPlayer : StandardGSYVideoPlayer {
GSYVideoView.CURRENT_STATE_PLAYING -> {
imageView.setImageDrawable(getResDrawable(R.drawable.ic_pause_white_24))
}
+
GSYVideoView.CURRENT_STATE_ERROR -> {
imageView.setImageDrawable(getResDrawable(R.drawable.ic_play_white_24))
}
+
GSYVideoView.CURRENT_STATE_AUTO_COMPLETE -> {
imageView.setImageDrawable(getResDrawable(R.drawable.ic_refresh_white_24))
}
+
else -> {
imageView.setImageDrawable(getResDrawable(R.drawable.ic_play_white_24))
}
@@ -888,7 +896,7 @@ open class VideoMediaPlayer : StandardGSYVideoPlayer {
viewTopContainerShadow?.visible()
mUiCleared = false
- if (VideoMediaPlayActivity.playList != null)
+ if (VideoMediaPlayViewModel.getCurrentPlayList(context) != null)
ivNextEpisode?.gone()
playErrorRetry?.gone()
@@ -906,7 +914,7 @@ open class VideoMediaPlayer : StandardGSYVideoPlayer {
initFirstLoad = false
mUiCleared = false
- if (VideoMediaPlayActivity.playList != null)
+ if (VideoMediaPlayViewModel.getCurrentPlayList(context) != null)
ivNextEpisode?.visible()
ivSetting?.visible()
@@ -1019,11 +1027,13 @@ open class VideoMediaPlayer : StandardGSYVideoPlayer {
startDismissControlViewTimer()
}
}
+
R.id.thumb -> {
vgSettingContainer?.gone()
vgRightContainer?.gone()
rvEpisode?.gone()
}
+
R.id.back -> (context as Activity).finish()
//重试
R.id.play_error_retry -> prepareVideo()
@@ -1049,7 +1059,7 @@ open class VideoMediaPlayer : StandardGSYVideoPlayer {
val adapter = typeAdapter()
isVisible = true
showRightContainer()
- adapter.submitList(VideoMediaPlayActivity.playList) {
+ adapter.submitList(VideoMediaPlayViewModel.getCurrentPlayList(context)) {
//定位
adapter.getTag()?.also {
smartScrollToPosition(it)
@@ -1156,6 +1166,7 @@ open class VideoMediaPlayer : StandardGSYVideoPlayer {
MotionEvent.ACTION_DOWN -> {
touchSurfaceDown(x, y)
}
+
MotionEvent.ACTION_MOVE -> {
val deltaX = x - mDownX
val deltaY = y - mDownY
@@ -1170,6 +1181,7 @@ open class VideoMediaPlayer : StandardGSYVideoPlayer {
}
touchSurfaceMove(deltaX, deltaY, y)
}
+
MotionEvent.ACTION_UP -> {
startDismissControlViewTimer()
touchSurfaceUp()
@@ -1271,7 +1283,10 @@ open class VideoMediaPlayer : StandardGSYVideoPlayer {
override fun startAfterPrepared() {
super.startAfterPrepared()
- logD(PLAY_POS_TAG, "开始播放,当前进度:pos=${gsyVideoManager.currentPosition} url=$mOriginUrl")
+ logD(
+ PLAY_POS_TAG,
+ "开始播放,当前进度:pos=${gsyVideoManager.currentPosition} url=$mOriginUrl"
+ )
}
override fun setProgressAndTime(
diff --git a/app/src/main/java/com/su/mediabox/view/fragment/page/SettingsPageFragment.kt b/app/src/main/java/com/su/mediabox/view/fragment/page/SettingsPageFragment.kt
index 64c9fe7d..70e2b4a6 100644
--- a/app/src/main/java/com/su/mediabox/view/fragment/page/SettingsPageFragment.kt
+++ b/app/src/main/java/com/su/mediabox/view/fragment/page/SettingsPageFragment.kt
@@ -87,7 +87,6 @@ class SettingsPageFragment : PreferenceFragmentCompat(), Preference.OnPreference
}
preferenceCategory {
-
titleRes(R.string.net_category_title)
switchPreference {
key = Const.Setting.NET_REPO_PROXY
@@ -171,7 +170,7 @@ class SettingsPageFragment : PreferenceFragmentCompat(), Preference.OnPreference
}
lifecycleCollect(mediaUpdateCheckWorkerIsRunning) { isRunning ->
- listView.post {
+ App.mainHandler.post {
auto.isEnabled = !isRunning
interval.isEnabled = !isRunning
onMeteredNet.isEnabled = !isRunning
@@ -191,7 +190,7 @@ class SettingsPageFragment : PreferenceFragmentCompat(), Preference.OnPreference
summaryRes(R.string.player_bottom_progress_summary)
lifecycleCollect(Pref.isShowPlayerBottomProgressBar) {
- listView.post {
+ App.mainHandler.post {
isChecked = it
}
}
@@ -234,12 +233,16 @@ class SettingsPageFragment : PreferenceFragmentCompat(), Preference.OnPreference
AppUpdateHelper.instance.apply {
getUpdateStatus()
.observe(this@SettingsPageFragment) {
- isEnabled = it != AppUpdateStatus.CHECKING
- when (it) {
- AppUpdateStatus.VALID ->
- context.getString(R.string.app_no_update_hint).showToast()
- AppUpdateStatus.DATED -> noticeUpdate(requireActivity() as AppCompatActivity)
- else -> Unit
+ App.mainHandler.post {
+ isEnabled = it != AppUpdateStatus.CHECKING
+ when (it) {
+ AppUpdateStatus.VALID ->
+ context.getString(R.string.app_no_update_hint)
+ .showToast()
+
+ AppUpdateStatus.DATED -> noticeUpdate(requireActivity() as AppCompatActivity)
+ else -> Unit
+ }
}
}
}
diff --git a/app/src/main/java/com/su/mediabox/view/viewcomponents/VideoPlayListViewHolder.kt b/app/src/main/java/com/su/mediabox/view/viewcomponents/VideoPlayListViewHolder.kt
index 531daf12..055d1539 100644
--- a/app/src/main/java/com/su/mediabox/view/viewcomponents/VideoPlayListViewHolder.kt
+++ b/app/src/main/java/com/su/mediabox/view/viewcomponents/VideoPlayListViewHolder.kt
@@ -156,7 +156,7 @@ class VideoPlayListViewHolder private constructor(private val binding: ItemHoriz
val playList =
bindingTypeAdapter.getTag>(Const.ViewComponent.EPISODE_LIST_TAG)
if (playList != null) {
- VideoMediaPlayActivity.playList = playList
+ action.extraData = playList
}
}
action?.go(bindingContext)
diff --git a/app/src/main/java/com/su/mediabox/view/viewcomponents/ViewPagerViewHolder.kt b/app/src/main/java/com/su/mediabox/view/viewcomponents/ViewPagerViewHolder.kt
index 62bc4fbd..a90f7b55 100644
--- a/app/src/main/java/com/su/mediabox/view/viewcomponents/ViewPagerViewHolder.kt
+++ b/app/src/main/java/com/su/mediabox/view/viewcomponents/ViewPagerViewHolder.kt
@@ -166,20 +166,21 @@ class ViewPagerViewHolder private constructor(private val binding: ViewComponent
class PageViewModel : ViewModel() {
- private var pageLoader by Delegates.notNull()
- private var page by Delegates.notNull()
+ private var pageLoader: ViewPagerData.PageLoader? = null
+ private var page: Int = 0
fun bindData(pageLoader: ViewPagerData.PageLoader?, page: Int?) {
- pageLoader?.also { this.pageLoader = it }
+ this.pageLoader = pageLoader
page?.also { this.page = it }
}
- private val _pageDataLiveData: MutableLiveData> = MutableLiveData()
+ private val _pageDataLiveData: MutableLiveData?> =
+ MutableLiveData?>()
val pageDataLiveData = _pageDataLiveData.toLiveData()
fun getData() {
viewModelScope.launch(Dispatchers.PluginIO) {
- _pageDataLiveData.postValue(pageLoader.loadData(page))
+ _pageDataLiveData.postValue(pageLoader?.loadData(page))
}
}
diff --git a/app/src/main/java/com/su/mediabox/viewmodel/PluginInstallerViewModel.kt b/app/src/main/java/com/su/mediabox/viewmodel/PluginInstallerViewModel.kt
index 9b15d420..08c59458 100644
--- a/app/src/main/java/com/su/mediabox/viewmodel/PluginInstallerViewModel.kt
+++ b/app/src/main/java/com/su/mediabox/viewmodel/PluginInstallerViewModel.kt
@@ -4,6 +4,7 @@ import android.content.Intent
import android.graphics.Color
import android.graphics.Typeface
import android.net.Uri
+import android.util.Log
import android.view.Gravity
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
@@ -23,6 +24,8 @@ import com.su.mediabox.util.ResourceUtil.getString
class PluginInstallerViewModel : ViewModel() {
+ private val tag = "PluginInstaller"
+
private val _pluginInstallState =
MutableLiveData(PluginInstallState.LOADING)
val pluginInstallState = _pluginInstallState.toLiveData()
@@ -63,6 +66,9 @@ class PluginInstallerViewModel : ViewModel() {
)
}
}
+ else -> {
+ logE(tag, "install error: $data")
+ }
}
}
}
@@ -230,6 +236,9 @@ class PluginInstallerViewModel : ViewModel() {
is PluginInstallState.PREVIEW -> {
PluginManager.downloadPlugin(data.pluginInfo)
}
+ else -> {
+ logE(tag, "downloadPlugin: $data")
+ }
}
}
diff --git a/app/src/main/java/com/su/mediabox/viewmodel/VideoMediaPlayViewModel.kt b/app/src/main/java/com/su/mediabox/viewmodel/VideoMediaPlayViewModel.kt
index 2766aab9..8d042669 100644
--- a/app/src/main/java/com/su/mediabox/viewmodel/VideoMediaPlayViewModel.kt
+++ b/app/src/main/java/com/su/mediabox/viewmodel/VideoMediaPlayViewModel.kt
@@ -1,7 +1,11 @@
package com.su.mediabox.viewmodel
+import android.content.Context
+import androidx.activity.ComponentActivity
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
+import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.get
import androidx.lifecycle.viewModelScope
import com.kuaishou.akdanmaku.data.DanmakuItemData
import com.su.mediabox.Pref
@@ -9,16 +13,29 @@ import com.su.mediabox.database.DatabaseOperations.insertHistoryData
import com.su.mediabox.database.DatabaseOperations.updateFavoriteData
import com.su.mediabox.pluginapi.data.VideoPlayMedia
import com.su.mediabox.pluginapi.components.IVideoPlayPageDataComponent
+import com.su.mediabox.pluginapi.data.EpisodeData
import com.su.mediabox.util.*
import com.su.mediabox.view.activity.VideoMediaPlayActivity
import kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
+import kotlin.math.min
import kotlin.properties.Delegates
class VideoMediaPlayViewModel : ViewModel() {
+ companion object {
+ fun getCurrentPlayList(context: Context): List? {
+ return if (context !is ComponentActivity)
+ null
+ else {
+ ViewModelProvider(context).get().playList
+ }
+ }
+ }
+
private val playComponent by lazyAcquireComponent()
lateinit var detailPartUrl: String
@@ -28,6 +45,9 @@ class VideoMediaPlayViewModel : ViewModel() {
var currentPlayEpisodeUrl = ""
private set
+ var playList: List? = null
+ private set
+
private val _currentVideoPlayMedia = MutableLiveData>()
private val _currentDanmakuData = MutableLiveData?>()
@@ -42,6 +62,12 @@ class VideoMediaPlayViewModel : ViewModel() {
private val episode2VideoInfoMap = mutableMapOf()
+ private var lastAutoJob: Job? = null
+
+ fun init(playList: List) {
+ this.playList = playList
+ }
+
fun playVideoMedia(episodeUrl: String = currentPlayEpisodeUrl) {
if (episodeUrl.isNotBlank()) {
_currentVideoPlayMedia.postValue(DataState.Loading)
@@ -82,16 +108,17 @@ class VideoMediaPlayViewModel : ViewModel() {
private fun preloadVideo(curEpisodeUrl: String) {
if (!Pref.videoPreload.value)
return
- VideoMediaPlayActivity.playList?.let {
+ playList?.let {
logD("preloadVideo", "load start: cur=$curEpisodeUrl")
- viewModelScope.launch(Dispatchers.IO) {
+ lastAutoJob?.cancel()
+ lastAutoJob = viewModelScope.launch(Dispatchers.IO) {
//定位当前
val startPre = it.indexOfFirst { it.url == curEpisodeUrl }
if (startPre != -1) {
var endIndex = startPre + VideoMediaPlayActivity.DEFAULT_VIDEO_PRELOAD_SIZE
- if (endIndex > (it.size - 1)) {
- endIndex = it.size - 1
- }
+ endIndex = min(endIndex, it.size - 1)
+ logD("preloadVideo", "start $startPre to $endIndex")
+ var realSize = 0
for (i in (startPre + 1)..endIndex) {
val episodeUrl = it[i].url
//TODO 因为内置的WebUtil内部WebView问题,暂时先串行解析
@@ -105,10 +132,12 @@ class VideoMediaPlayViewModel : ViewModel() {
"load episodeUrl=$episodeUrl success result=$result"
)
episode2VideoInfoMap[episodeUrl] = result
+ realSize++
}
}
}
}
+ logD("preloadVideo", "preload success: size=$realSize")
}
}
}
@@ -124,6 +153,7 @@ class VideoMediaPlayViewModel : ViewModel() {
)
true
}
+
else -> false
}
}
@@ -142,7 +172,13 @@ class VideoMediaPlayViewModel : ViewModel() {
}
}
}
+
else -> logD("加载弹幕失败", "当前无播放媒体")
}
}
+
+ override fun onCleared() {
+ playList = null
+ super.onCleared()
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/su/mediabox/work/MediaUpdateCheckWorker.kt b/app/src/main/java/com/su/mediabox/work/MediaUpdateCheckWorker.kt
index 16502132..d292bf17 100644
--- a/app/src/main/java/com/su/mediabox/work/MediaUpdateCheckWorker.kt
+++ b/app/src/main/java/com/su/mediabox/work/MediaUpdateCheckWorker.kt
@@ -68,6 +68,10 @@ internal class MediaUpdateCheckWorker(context: Context, workerParameters: Worker
private val TAG = "媒体检查更新Worker"
private val key = ResourceUtil.getString(R.string.media_update_check_title)
+ private val notifyFlag =
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) PendingIntent.FLAG_IMMUTABLE
+ else PendingIntent.FLAG_UPDATE_CURRENT
+
private fun createForegroundInfo(): ForegroundInfo {
// val cancel = applicationContext.getString(R.string.cancel)
// val intent = WorkManager.getInstance(applicationContext)
@@ -77,7 +81,7 @@ internal class MediaUpdateCheckWorker(context: Context, workerParameters: Worker
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}
val notifyPendingIntent = PendingIntent.getActivity(
- applicationContext, 0, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT
+ applicationContext, 0, notifyIntent, notifyFlag
)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
@@ -179,7 +183,7 @@ internal class MediaUpdateCheckWorker(context: Context, workerParameters: Worker
val pluginMediaDataManageNotifyPendingIntent = PendingIntent.getActivity(
applicationContext, index,
- pluginMediaDataManageIntent, PendingIntent.FLAG_UPDATE_CURRENT
+ pluginMediaDataManageIntent, notifyFlag
)
val pluginMediaUpdateNofBuilder =
@@ -216,7 +220,7 @@ internal class MediaUpdateCheckWorker(context: Context, workerParameters: Worker
Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}
val notifyPendingIntent = PendingIntent.getActivity(
- applicationContext, 0, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT
+ applicationContext, 0, notifyIntent, notifyFlag
)
val mediaUpdateCheckNofBuilder =
diff --git a/build.gradle b/build.gradle
index 49db0ad0..7760a015 100644
--- a/build.gradle
+++ b/build.gradle
@@ -5,7 +5,7 @@ buildscript {
ext {
secret = "${rootDir}/secret.gradle"
andresguard = "${rootDir}/andresguard.gradle"
- kotlinVersion = '1.6.21'
+ kotlinVersion = '1.8.0'
}
repositories {
google()
diff --git a/version.gradle b/version.gradle
index cc74b1c5..dcf20a68 100644
--- a/version.gradle
+++ b/version.gradle
@@ -1,9 +1,9 @@
-ext.version_code = 62
-ext.version_name = "2.62"
+ext.version_code = 63
+ext.version_name = "2.63"
def build_versions = [:]
-build_versions.compile_sdk = 31
-build_versions.build_tools = "31.0.0"
+build_versions.compile_sdk = 34
+build_versions.build_tools = "34.0.0"
build_versions.min_sdk = 21
build_versions.target_sdk = 31
ext.build_versions = build_versions
@@ -11,8 +11,8 @@ ext.build_versions = build_versions
def deps = [:]
def kotlin = [:]
-kotlin.kotlin_stdlib = "org.jetbrains.kotlin:kotlin-stdlib:1.6.10"
-kotlin.core_ktx = "androidx.core:core-ktx:1.6.0"
+kotlin.kotlin_stdlib = "org.jetbrains.kotlin:kotlin-stdlib:1.8.0"
+kotlin.core_ktx = "androidx.core:core-ktx:1.8.0"
deps.kotlin = kotlin
def settings = [:]
@@ -60,9 +60,10 @@ okhttp3.okhttp_dnsoverhttps = "com.squareup.okhttp3:okhttp-dnsoverhttps:4.9.0"
deps.okhttp3 = okhttp3
def room = [:]
-room.room_runtime = "androidx.room:room-runtime:2.4.2"
-room.room_ktx = "androidx.room:room-ktx:2.4.2"
-room.room_compiler = "androidx.room:room-compiler:2.4.2"
+def room_version = "2.5.1"
+room.room_runtime = "androidx.room:room-runtime:$room_version"
+room.room_ktx = "androidx.room:room-ktx:$room_version"
+room.room_compiler = "androidx.room:room-compiler:$room_version"
deps.room = room
def jsoup = [:]
@@ -103,7 +104,7 @@ nanohttpd.nanohttpd = "org.nanohttpd:nanohttpd:2.3.1"
deps.nanohttpd = nanohttpd
def coil_kt = [:]
-coil_kt.coil = "io.coil-kt:coil:2.0.0"
+coil_kt.coil = "io.coil-kt:coil:2.5.0"
deps.coil_kt = coil_kt
def smart = [:]