更新 Gradle 配置,升级依赖库版本,移除 VasSonic 相关代码,以支持新的依赖管理方式。

This commit is contained in:
vipyinzhiwei
2025-05-10 20:22:24 +08:00
parent da1181b447
commit 881bedccbe
16 changed files with 43 additions and 495 deletions

View File

@@ -80,7 +80,6 @@ Through this project, I hope to help you better learn Jetpack and MVVM architect
- [PhotoView][25] Support gesture zoom picture
- [Circleimageview][26] Round image
- [GSYVideoPlayer][27] Video player
- [VasSonic][28] Improve H5 first screen loading speed
- [Leakcanary][29] Memory leak detection
- [Kotlinx Coroutines][30] Simplify code management background threads and callbacks
@@ -132,7 +131,6 @@ limitations under the License.
[25]:https://github.com/chrisbanes/PhotoView
[26]:https://github.com/hdodenhof/CircleImageView
[27]:https://github.com/CarGuo/GSYVideoPlayer
[28]:https://github.com/Tencent/VasSonic
[29]:https://github.com/square/leakcanary
[30]:https://github.com/Kotlin/kotlinx.coroutines
[31]:https://m.apkpure.com/cn/%E5%BC%80%E7%9C%BC/com.wandoujia.eyepetizer/versions

View File

@@ -80,7 +80,6 @@
- [PhotoView][25] 支持手势缩放图片
- [Circleimageview][26] 圆形图像
- [GSYVideoPlayer][27] 视频播放器
- [VasSonic][28] 提升H5首屏加载速度
- [Leakcanary][29] 内存泄漏检测
- [Kotlinx Coroutines][30] 简化代码管理后台线程与回调
@@ -132,7 +131,6 @@ limitations under the License.
[25]:https://github.com/chrisbanes/PhotoView
[26]:https://github.com/hdodenhof/CircleImageView
[27]:https://github.com/CarGuo/GSYVideoPlayer
[28]:https://github.com/Tencent/VasSonic
[29]:https://github.com/square/leakcanary
[30]:https://github.com/Kotlin/kotlinx.coroutines
[31]:https://m.apkpure.com/cn/%E5%BC%80%E7%9C%BC/com.wandoujia.eyepetizer/versions

View File

@@ -7,13 +7,12 @@ apply plugin: 'kotlin-parcelize'
apply plugin: 'kotlin-kapt'
android {
compileSdkVersion 32
buildToolsVersion "32.0.0"
compileSdk 34
defaultConfig {
applicationId "com.eyepetizer.android"
minSdkVersion 21
targetSdkVersion 32
targetSdkVersion 34
versionCode 7
versionName "1.0.6"
multiDexEnabled true
@@ -74,50 +73,49 @@ android {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.4.2'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
//常用依赖库
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4'
implementation 'androidx.recyclerview:recyclerview:1.2.1'
implementation 'com.google.android.material:material:1.6.1'
implementation 'androidx.recyclerview:recyclerview:1.3.2'
implementation 'com.google.android.material:material:1.10.0'
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.squareup.retrofit2:converter-scalars:2.5.0'
implementation 'com.github.bumptech.glide:glide:4.13.2'
kapt 'com.github.bumptech.glide:compiler:4.11.0'
implementation 'com.github.bumptech.glide:okhttp3-integration:4.9.0'
implementation 'jp.wasabeef:glide-transformations:4.1.0'
implementation 'com.github.bumptech.glide:glide:4.16.0'
kapt 'com.github.bumptech.glide:compiler:4.16.0'
implementation 'com.github.bumptech.glide:okhttp3-integration:4.16.0'
implementation 'jp.wasabeef:glide-transformations:4.3.0'
implementation 'org.greenrobot:eventbus:3.1.1'
implementation 'androidx.viewpager2:viewpager2:1.0.0'
implementation 'com.permissionx.guolindev:permissionx:1.2.2'
implementation 'com.guolindev.permissionx:permissionx:1.7.1'
//Android Jetpack 组件
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
implementation 'androidx.work:work-runtime:2.7.1'
implementation "androidx.startup:startup-runtime:1.1.1"
implementation "androidx.datastore:datastore-preferences:1.0.0"
implementation "androidx.paging:paging-runtime:3.1.1"
implementation 'androidx.work:work-runtime:2.8.1'
implementation 'androidx.startup:startup-runtime:1.1.1'
implementation 'androidx.datastore:datastore-preferences:1.0.0'
implementation 'androidx.paging:paging-runtime:3.2.1'
//Android KTX
implementation 'androidx.core:core-ktx:1.8.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.5.1'
implementation "androidx.fragment:fragment-ktx:1.5.1"
implementation 'androidx.core:core-ktx:1.12.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2'
implementation 'androidx.fragment:fragment-ktx:1.6.2'
//特定功能依赖库
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.10'
implementation 'com.flyco.tablayout:FlycoTabLayout_Lib:2.1.2@aar'
implementation 'com.scwang.smart:refresh-header-material:2.0.0'
implementation 'com.scwang.smart:refresh-layout-kernel:2.0.0'
implementation 'io.github.h07000223:flycoTabLayout:3.0.0'
implementation 'io.github.scwang90:refresh-header-material:3.0.0-alpha'
implementation 'io.github.scwang90:refresh-layout-kernel:3.0.0-alpha'
implementation 'com.github.zhpanvip:BannerViewPager:3.1.2'
implementation 'com.gyf.immersionbar:immersionbar:3.0.0'
implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2'
implementation 'com.github.chrisbanes:PhotoView:2.3.0'
implementation 'de.hdodenhof:circleimageview:3.1.0'
implementation 'com.android.support:multidex:1.0.3'
implementation 'androidx.multidex:multidex:2.0.1'
implementation 'com.shuyu:GSYVideoPlayer:8.1.2'
implementation 'com.tencent.sonic:sdk:3.1.0'
implementation 'com.umeng.umsdk:common:9.3.8'
implementation 'com.umeng.umsdk:asms:1.2.2'

View File

@@ -21,9 +21,7 @@ import android.app.Application
import android.content.Context
import androidx.multidex.MultiDex
import androidx.work.WorkManager
import com.eyepetizer.android.extension.preCreateSession
import com.eyepetizer.android.ui.SplashActivity
import com.eyepetizer.android.ui.common.ui.WebViewActivity
import com.eyepetizer.android.ui.common.view.NoStatusFooter
import com.eyepetizer.android.util.DialogAppraiseTipsWorker
import com.eyepetizer.android.util.GlobalUtil
@@ -73,7 +71,6 @@ class EyepetizerApplication : Application() {
super.onCreate()
context = this
IjkPlayerManager.setLogLevel(if (BuildConfig.DEBUG) IjkMediaPlayer.IJK_LOG_WARN else IjkMediaPlayer.IJK_LOG_SILENT)
WebViewActivity.DEFAULT_URL.preCreateSession()
if (!SplashActivity.isFirstEntryApp && DialogAppraiseTipsWorker.isNeedShowDialog) {
WorkManager.getInstance(this).enqueue(DialogAppraiseTipsWorker.showDialogWorkRequest)
}

View File

@@ -18,10 +18,6 @@ package com.eyepetizer.android.extension
import android.widget.Toast
import com.eyepetizer.android.EyepetizerApplication
import com.eyepetizer.android.ui.common.ui.vassonic.SonicRuntimeImpl
import com.tencent.sonic.sdk.SonicConfig
import com.tencent.sonic.sdk.SonicEngine
import com.tencent.sonic.sdk.SonicSessionConfig
/**
* 弹出Toast提示。
@@ -30,18 +26,4 @@ import com.tencent.sonic.sdk.SonicSessionConfig
*/
fun CharSequence.showToast(duration: Int = Toast.LENGTH_SHORT) {
Toast.makeText(EyepetizerApplication.context, this, duration).show()
}
/**
* VasSonic预加载session。
*
* @param CharSequence 预加载url
*/
fun CharSequence.preCreateSession(): Boolean {
if (!SonicEngine.isGetInstanceAllowed()) {
SonicEngine.createInstance(SonicRuntimeImpl(EyepetizerApplication.context), SonicConfig.Builder().build())
}
val sessionConfigBuilder = SonicSessionConfig.Builder().apply { setSupportLocalServer(true) }
val preloadSuccess = SonicEngine.getInstance().preCreateSession(this.toString(), sessionConfigBuilder.build())
return preloadSuccess
}

View File

@@ -23,19 +23,10 @@ import android.graphics.Bitmap
import android.net.Uri
import android.os.Bundle
import android.view.View
import android.view.WindowManager
import android.webkit.*
import com.eyepetizer.android.databinding.ActivityWebViewBinding
import com.eyepetizer.android.extension.logD
import com.eyepetizer.android.extension.preCreateSession
import com.eyepetizer.android.extension.visible
import com.eyepetizer.android.ui.common.ui.vassonic.OfflinePkgSessionConnection
import com.eyepetizer.android.ui.common.ui.vassonic.SonicJavaScriptInterface
import com.eyepetizer.android.ui.common.ui.vassonic.SonicRuntimeImpl
import com.eyepetizer.android.ui.common.ui.vassonic.SonicSessionClientImpl
import com.eyepetizer.android.util.GlobalUtil
import com.tencent.sonic.sdk.*
/**
* 展示网页共通界面。
@@ -58,16 +49,11 @@ class WebViewActivity : BaseActivity() {
private var isTitleFixed: Boolean = false
private var sonicSession: SonicSession? = null
private var sonicSessionClient: SonicSessionClientImpl? = null
private var mode: Int = MODE_DEFAULT
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
initParams()
preloadInitVasSonic()
_binding = ActivityWebViewBinding.inflate(layoutInflater)
setContentView(binding.root)
}
@@ -76,12 +62,7 @@ class WebViewActivity : BaseActivity() {
super.setupViews()
initTitleBar()
initWebView()
if (sonicSessionClient != null) {
sonicSessionClient?.bindWebView(binding.webView)
sonicSessionClient?.clientReady()
} else {
binding.webView.loadUrl(linkUrl)
}
binding.webView.loadUrl(linkUrl)
}
override fun onBackPressed() {
@@ -94,8 +75,6 @@ class WebViewActivity : BaseActivity() {
override fun onDestroy() {
binding.webView.destroy()
sonicSession?.destroy()
sonicSession = null
_binding = null
super.onDestroy()
}
@@ -120,12 +99,9 @@ class WebViewActivity : BaseActivity() {
mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW
javaScriptEnabled = true
binding.webView.removeJavascriptInterface("searchBoxJavaBridge_")
intent.putExtra(SonicJavaScriptInterface.PARAM_LOAD_URL_TIME, System.currentTimeMillis())
binding.webView.addJavascriptInterface(SonicJavaScriptInterface(sonicSessionClient, intent), "sonic")
allowContentAccess = true
databaseEnabled = true
domStorageEnabled = true
setAppCacheEnabled(true)
savePassword = false
saveFormData = false
useWideViewPort = true
@@ -143,49 +119,6 @@ class WebViewActivity : BaseActivity() {
}
}
/**
* 使用VasSonic框架提升H5首屏加载速度。
*/
private fun preloadInitVasSonic() {
window.addFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED)
// init sonic engine if necessary, or maybe u can do this when application created
if (!SonicEngine.isGetInstanceAllowed()) {
SonicEngine.createInstance(SonicRuntimeImpl(application), SonicConfig.Builder().build())
}
// if it's sonic mode , startup sonic session at first time
if (MODE_DEFAULT != mode) { // sonic mode
val sessionConfigBuilder = SonicSessionConfig.Builder()
sessionConfigBuilder.setSupportLocalServer(true)
// if it's offline pkg mode, we need to intercept the session connection
if (MODE_SONIC_WITH_OFFLINE_CACHE == mode) {
sessionConfigBuilder.setCacheInterceptor(object : SonicCacheInterceptor(null) {
override fun getCacheData(session: SonicSession): String? {
return null // offline pkg does not need cache
}
})
sessionConfigBuilder.setConnectionInterceptor(object : SonicSessionConnectionInterceptor() {
override fun getConnection(session: SonicSession, intent: Intent): SonicSessionConnection {
return OfflinePkgSessionConnection(this@WebViewActivity, session, intent)
}
})
}
// create sonic session and run sonic flow
sonicSession = SonicEngine.getInstance().createSession(linkUrl, sessionConfigBuilder.build())
if (null != sonicSession) {
sonicSession?.bindClient(SonicSessionClientImpl().also { sonicSessionClient = it })
} else {
// this only happen when a same sonic session is already running,
// u can comment following codes to feedback as a default mode.
// throw new UnknownError("create session fail!");
logD(TAG, "${title},${linkUrl}:create sonic session fail!")
}
}
}
class UIWebViewClient(val binding: ActivityWebViewBinding, val activity: WebViewActivity) : WebViewClient() {
override fun onPageStarted(view: WebView, url: String, favicon: Bitmap?) {
activity.linkUrl = url
@@ -195,15 +128,10 @@ class WebViewActivity : BaseActivity() {
override fun onPageFinished(view: WebView, url: String) {
super.onPageFinished(view, url)
activity.sonicSession?.sessionClient?.pageFinish(url)
binding.progressBar.visibility = View.INVISIBLE
}
override fun shouldInterceptRequest(view: WebView?, request: WebResourceRequest?): WebResourceResponse? {
if (activity.sonicSession != null) {
val requestResponse = activity.sonicSessionClient?.requestResource(request?.url.toString())
if (requestResponse is WebResourceResponse) return requestResponse
}
return super.shouldInterceptRequest(view, request)
}
}
@@ -253,14 +181,12 @@ class WebViewActivity : BaseActivity() {
* @param mode 加载模式MODE_DEFAULT 默认使用WebView加载MODE_SONIC 使用VasSonic框架加载 MODE_SONIC_WITH_OFFLINE_CACHE 使用VasSonic框架离线加载
*/
fun start(context: Context, title: String, url: String, isShare: Boolean = true, isTitleFixed: Boolean = true, mode: Int = MODE_SONIC) {
url.preCreateSession() //预加载url
val intent = Intent(context, WebViewActivity::class.java).apply {
putExtra(TITLE, title)
putExtra(LINK_URL, url)
putExtra(IS_SHARE, isShare)
putExtra(IS_TITLE_FIXED, isTitleFixed)
putExtra(PARAM_MODE, mode)
putExtra(SonicJavaScriptInterface.PARAM_CLICK_TIME, System.currentTimeMillis())
}
context.startActivity(intent)
}

View File

@@ -1,80 +0,0 @@
/*
* Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.eyepetizer.android.ui.common.ui.vassonic
import android.content.Context
import android.content.Intent
import com.tencent.sonic.sdk.SonicConstants
import com.tencent.sonic.sdk.SonicSession
import com.tencent.sonic.sdk.SonicSessionConnection
import java.io.BufferedInputStream
import java.io.IOException
import java.lang.ref.WeakReference
import java.util.*
class OfflinePkgSessionConnection(context: Context, session: SonicSession?, intent: Intent?) : SonicSessionConnection(session, intent) {
private val context: WeakReference<Context>
override fun internalConnect(): Int {
val ctx = context.get()
if (null != ctx) {
try {
val offlineHtmlInputStream = ctx.assets.open("sonic-demo-index.html")
responseStream = BufferedInputStream(offlineHtmlInputStream)
return SonicConstants.ERROR_CODE_SUCCESS
} catch (e: Throwable) {
e.printStackTrace()
}
}
return SonicConstants.ERROR_CODE_UNKNOWN
}
override fun internalGetResponseStream(): BufferedInputStream {
return responseStream
}
override fun internalGetCustomHeadFieldEtag(): String {
return CUSTOM_HEAD_FILED_ETAG
}
override fun disconnect() {
if (null != responseStream) {
try {
responseStream.close()
} catch (e: IOException) {
e.printStackTrace()
}
}
}
override fun getResponseCode(): Int {
return 200
}
override fun getResponseHeaderFields(): Map<String, List<String>> {
return HashMap(0)
}
override fun getResponseHeaderField(key: String?): String {
return ""
}
init {
this.context = WeakReference(context)
}
}

View File

@@ -1,104 +0,0 @@
/*
* Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.eyepetizer.android.ui.common.ui.vassonic
import android.content.Intent
import android.os.Handler
import android.os.Looper
import android.webkit.JavascriptInterface
import org.json.JSONObject
/**
* Sonic javaScript Interface (Android API Level >= 17)
*/
class SonicJavaScriptInterface(private val sessionClient: SonicSessionClientImpl?, private val intent: Intent) {
// the callback function of demo page is hardcode as 'getDiffDataCallback'
@get:JavascriptInterface
val diffData: Unit
get() {
// the callback function of demo page is hardcode as 'getDiffDataCallback'
getDiffData2("getDiffDataCallback")
}
@JavascriptInterface
fun getDiffData2(jsCallbackFunc: String) {
sessionClient?.getDiffData { resultData ->
val callbackRunnable = Runnable {
val jsCode = "javascript:" + jsCallbackFunc + "('" + toJsString(resultData) + "')"
sessionClient.webView?.loadUrl(jsCode)
}
if (Looper.getMainLooper() == Looper.myLooper()) {
callbackRunnable.run()
} else {
Handler(Looper.getMainLooper()).post(callbackRunnable)
}
}
}
@get:JavascriptInterface
val performance: String
get() {
val clickTime = intent.getLongExtra(PARAM_CLICK_TIME, -1)
val loadUrlTime = intent.getLongExtra(PARAM_LOAD_URL_TIME, -1)
try {
val result = JSONObject()
result.put(PARAM_CLICK_TIME, clickTime)
result.put(PARAM_LOAD_URL_TIME, loadUrlTime)
return result.toString()
} catch (e: Exception) {
}
return ""
}
companion object {
const val PARAM_CLICK_TIME = "clickTime"
const val PARAM_LOAD_URL_TIME = "loadUrlTime"
/**
* From RFC 4627, "All Unicode characters may be placed within the quotation marks except
* for the characters that must be escaped: quotation mark,
* reverse solidus, and the control characters (U+0000 through U+001F)."
*/
private fun toJsString(value: String?): String {
if (value == null) {
return "null"
}
val out = StringBuilder(1024)
var i = 0
val length = value.length
while (i < length) {
val c = value[i]
when (c) {
'"', '\\', '/' -> out.append('\\').append(c)
'\t' -> out.append("\\t")
'\b' -> out.append("\\b")
'\n' -> out.append("\\n")
'\r' -> out.append("\\r")
'\u000C' -> out.append("\\f") //Kotlin 转义字符 - 换页符 "\f" 提示错误 Illegal escape: '\f' 解决方案:https://www.jianshu.com/p/a59a24f76c4b,使用 Kotlin "\u000C",使用 Java "\f"
else -> if (c.toInt() <= 0x1F) {
out.append(String.format("\\u%04x", c.toInt()))
} else {
out.append(c)
}
}
i++
}
return out.toString()
}
}
}

View File

@@ -1,115 +0,0 @@
/*
* Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.eyepetizer.android.ui.common.ui.vassonic
import android.content.Context
import android.os.Build
import android.os.Environment
import android.text.TextUtils
import android.util.Log
import android.webkit.CookieManager
import android.webkit.WebResourceResponse
import com.eyepetizer.android.BuildConfig
import com.tencent.sonic.sdk.SonicRuntime
import com.tencent.sonic.sdk.SonicSessionClient
import java.io.File
import java.io.InputStream
/**
* the sonic host application must implement SonicRuntime to do right things.
*/
class SonicRuntimeImpl(context: Context?) : SonicRuntime(context) {
/**
* 获取用户UA信息
* @return
*/
override fun getUserAgent(): String {
return System.getProperty("http.agent") ?: "unknown"
}
/**
* 获取用户ID信息
* @return
*/
override fun getCurrentUserAccount(): String {
return ""
}
override fun getCookie(url: String?): String? {
val cookieManager = CookieManager.getInstance()
return cookieManager.getCookie(url)
}
override fun log(tag: String, level: Int, message: String) {
when (level) {
Log.ERROR -> Log.e(tag, message)
Log.INFO -> Log.i(tag, message)
else -> Log.d(tag, message)
}
}
override fun createWebResourceResponse(mimeType: String, encoding: String, data: InputStream, headers: Map<String, String>): Any {
val resourceResponse = WebResourceResponse(mimeType, encoding, data)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
resourceResponse.responseHeaders = headers
}
return resourceResponse
}
override fun showToast(text: CharSequence, duration: Int) {}
override fun notifyError(client: SonicSessionClient?, url: String?, errorCode: Int) {}
override fun isSonicUrl(url: String): Boolean {
return true
}
override fun setCookie(url: String?, cookies: List<String>?): Boolean {
if (!TextUtils.isEmpty(url) && cookies != null && cookies.size > 0) {
val cookieManager = CookieManager.getInstance()
for (cookie in cookies) {
cookieManager.setCookie(url, cookie)
}
return true
}
return false
}
override fun isNetworkValid(): Boolean {
return true
}
override fun postTaskToThread(task: Runnable, delayMillis: Long) {
val thread = Thread(task, "SonicThread")
thread.start()
}
override fun getSonicCacheDir(): File {
if (BuildConfig.DEBUG) {
val path = Environment.getExternalStorageDirectory().absolutePath + File.separator + "sonic/"
val file = File(path.trim { it <= ' ' })
if (!file.exists()) {
file.mkdir()
}
return file
}
return super.getSonicCacheDir()
}
override fun getHostDirectAddress(url: String): String? {
return null
}
}

View File

@@ -1,51 +0,0 @@
/*
* Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.eyepetizer.android.ui.common.ui.vassonic
import android.os.Bundle
import android.webkit.WebView
import com.tencent.sonic.sdk.SonicSessionClient
import java.util.*
/**
* a implement of SonicSessionClient which need to connect webview and content data.
*/
class SonicSessionClientImpl : SonicSessionClient() {
var webView: WebView? = null
private set
fun bindWebView(webView: WebView?) {
this.webView = webView
}
override fun loadUrl(url: String, extraData: Bundle?) {
webView?.loadUrl(url)
}
override fun loadDataWithBaseUrl(baseUrl: String, data: String, mimeType: String, encoding: String, historyUrl: String) {
webView?.loadDataWithBaseURL(baseUrl, data, mimeType, encoding, historyUrl)
}
override fun loadDataWithBaseUrlAndHeader(baseUrl: String, data: String, mimeType: String, encoding: String, historyUrl: String, headers: HashMap<String, String>) {
loadDataWithBaseUrl(baseUrl, data, mimeType, encoding, historyUrl)
}
fun destroy() {
webView?.destroy()
webView = null
}
}

View File

@@ -34,6 +34,8 @@ import com.eyepetizer.android.extension.*
import com.eyepetizer.android.logic.model.Author
import com.eyepetizer.android.logic.model.Consumption
import com.eyepetizer.android.logic.model.Cover
import com.eyepetizer.android.logic.model.VideoDetail
import com.eyepetizer.android.logic.model.VideoReplies
import com.eyepetizer.android.logic.model.WebUrl
import com.eyepetizer.android.ui.common.ui.BaseActivity
import com.eyepetizer.android.ui.common.view.NoStatusFooter
@@ -200,7 +202,7 @@ class NewDetailActivity : BaseActivity() {
private fun observe() {
//刷新,视频信息+相关推荐+评论
if (!viewModel.videoDetailLiveData.hasObservers()) {
viewModel.videoDetailLiveData.observe(this, Observer { result ->
viewModel.videoDetailLiveData.observe(this, Observer<Result<VideoDetail>> { result ->
val response = result.getOrNull()
if (response == null) {
ResponseHandler.getFailureTips(result.exceptionOrNull()).showToast()
@@ -211,7 +213,9 @@ class NewDetailActivity : BaseActivity() {
return@Observer
}
response.videoBeanForClient?.run {
viewModel.videoInfoData = VideoInfo(id, playUrl, title, description, category, library, consumption, cover, author, webUrl)
viewModel.videoInfoData = VideoInfo(videoId = id, playUrl = playUrl, title = title, description = description,
category = category, library = library, consumption = consumption,
cover = cover, author = author, webUrl = webUrl)
startVideoPlayer()
relatedAdapter.bindVideoInfo(viewModel.videoInfoData)
}
@@ -230,7 +234,7 @@ class NewDetailActivity : BaseActivity() {
}
//刷新,相关推荐+评论
if (!viewModel.repliesAndRepliesLiveData.hasObservers()) {
viewModel.repliesAndRepliesLiveData.observe(this, Observer { result ->
viewModel.repliesAndRepliesLiveData.observe(this, Observer<Result<VideoDetail>> { result ->
val response = result.getOrNull()
if (response == null) {
ResponseHandler.getFailureTips(result.exceptionOrNull()).showToast()
@@ -256,7 +260,7 @@ class NewDetailActivity : BaseActivity() {
}
//上拉加载,评论
if (!viewModel.repliesLiveData.hasObservers()) {
viewModel.repliesLiveData.observe(this, Observer { result ->
viewModel.repliesLiveData.observe(this, Observer<Result<VideoReplies>> { result ->
val response = result.getOrNull()
if (response == null) {
ResponseHandler.getFailureTips(result.exceptionOrNull()).showToast()

View File

@@ -17,9 +17,9 @@
package com.eyepetizer.android.ui.newdetail
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Transformations
import androidx.lifecycle.ViewModel
import androidx.lifecycle.liveData
import androidx.lifecycle.switchMap
import com.eyepetizer.android.logic.VideoRepository
import com.eyepetizer.android.logic.model.VideoDetail
import com.eyepetizer.android.logic.model.VideoRelated
@@ -48,7 +48,7 @@ class NewDetailViewModel(repository: VideoRepository) : ViewModel() {
var nextPageUrl: String? = null
val videoDetailLiveData = Transformations.switchMap(videoDetailLiveData_) {
val videoDetailLiveData = videoDetailLiveData_.switchMap {
liveData {
val resutlt = try {
val videoDetail = repository.refreshVideoDetail(it.videoId, it.repliesUrl) //视频信息+相关推荐+评论
@@ -60,7 +60,7 @@ class NewDetailViewModel(repository: VideoRepository) : ViewModel() {
}
}
val repliesAndRepliesLiveData = Transformations.switchMap(repliesAndRepliesLiveData_) {
val repliesAndRepliesLiveData = repliesAndRepliesLiveData_.switchMap {
liveData {
val resutlt = try {
val videoDetail = repository.refreshVideoRelatedAndVideoReplies(it.videoId, it.repliesUrl) //相关推荐+评论
@@ -72,7 +72,7 @@ class NewDetailViewModel(repository: VideoRepository) : ViewModel() {
}
}
val repliesLiveData = Transformations.switchMap(repliesLiveData_) {
val repliesLiveData = repliesLiveData_.switchMap {
liveData {
val resutlt = try {
val videoDetail = repository.refreshVideoReplies(it) //评论

View File

@@ -17,9 +17,9 @@
package com.eyepetizer.android.ui.search
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Transformations
import androidx.lifecycle.ViewModel
import androidx.lifecycle.liveData
import androidx.lifecycle.switchMap
import com.eyepetizer.android.logic.MainPageRepository
class SearchViewModel(val repository: MainPageRepository) : ViewModel() {
@@ -28,7 +28,7 @@ class SearchViewModel(val repository: MainPageRepository) : ViewModel() {
private var requestParamLiveData = MutableLiveData<Any>()
val dataListLiveData = Transformations.switchMap(requestParamLiveData) {
val dataListLiveData = requestParamLiveData.switchMap{
liveData {
val resutlt = try {
val hotSearch = repository.refreshHotSearch()

View File

@@ -84,7 +84,6 @@ class OpenSourceProjectsActivity : BaseActivity() {
add(OpenSourceProject("PhotoView", "https://github.com/chrisbanes/PhotoView"))
add(OpenSourceProject("Circleimageview", "https://github.com/hdodenhof/CircleImageView"))
add(OpenSourceProject("GSYVideoPlayer", "https://github.com/CarGuo/GSYVideoPlayer"))
add(OpenSourceProject("VasSonic", "https://github.com/Tencent/VasSonic"))
add(OpenSourceProject("Leakcanary", "https://github.com/square/leakcanary"))
add(OpenSourceProject("Kotlinx Coroutines", "https://github.com/Kotlin/kotlinx.coroutines"))
}

View File

@@ -29,7 +29,6 @@ import com.eyepetizer.android.ui.common.ui.WebViewActivity.Companion.MODE_SONIC_
import com.eyepetizer.android.ui.login.LoginActivity
import com.eyepetizer.android.util.DataStoreUtils
import com.shuyu.gsyvideoplayer.GSYVideoManager
import com.tencent.sonic.sdk.SonicEngine
import com.umeng.analytics.MobclickAgent
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@@ -86,9 +85,6 @@ class SettingViewModel : ViewModel() {
Glide.get(context).clearMemory()
withContext(Dispatchers.IO) {
Glide.get(context).clearDiskCache()
if (SonicEngine.isGetInstanceAllowed()) {
SonicEngine.getInstance().cleanCache()
}
}
R.string.clear_cache_succeed.showToast()
}

View File

@@ -4,11 +4,10 @@ buildscript {
ext.kotlin_version = '1.7.10'
repositories {
google()
jcenter()
maven { url 'https://repo1.maven.org/maven2/' }
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:7.2.2'
classpath 'com.android.tools.build:gradle:7.4.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
@@ -19,9 +18,10 @@ buildscript {
allprojects {
repositories {
google()
jcenter()
maven { url 'https://repo1.maven.org/maven2/' }
mavenCentral()
maven { url 'https://jitpack.io' }
maven { url 'https://maven.tencent.com/repository/maven-public/' }
maven { url "https://maven.aliyun.com/repository/public" }
}
}