found memory leak that is not fixed but fixes search

This commit is contained in:
LagradOst 2021-07-28 03:04:32 +02:00
parent a6c96c9647
commit 8ff87e5108
12 changed files with 100 additions and 88 deletions

View file

@ -7,29 +7,23 @@ import android.content.pm.PackageManager
import android.content.res.ColorStateList
import android.os.Build
import android.os.Bundle
import android.widget.Toast
import android.view.WindowManager
import androidx.appcompat.app.AppCompatActivity
import androidx.navigation.NavOptions
import androidx.navigation.findNavController
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.setupWithNavController
import com.google.android.gms.cast.framework.CastButtonFactory
import com.google.android.material.bottomnavigation.BottomNavigationView
import com.lagradost.cloudstream3.UIHelper.checkWrite
import com.lagradost.cloudstream3.UIHelper.getResourceColor
import com.lagradost.cloudstream3.UIHelper.hasPIPPermission
import com.lagradost.cloudstream3.UIHelper.isUsingMobileData
import com.lagradost.cloudstream3.UIHelper.requestRW
import com.lagradost.cloudstream3.UIHelper.shouldShowPIPMode
import com.lagradost.cloudstream3.receivers.VideoDownloadRestartReceiver
import com.lagradost.cloudstream3.ui.download.DownloadChildFragment
import com.lagradost.cloudstream3.utils.DataStore.getKey
import com.lagradost.cloudstream3.utils.DataStore.getKeys
import com.lagradost.cloudstream3.utils.DataStore.removeKey
import com.lagradost.cloudstream3.utils.DataStore.removeKeys
import com.lagradost.cloudstream3.utils.DataStoreHelper.setViewPos
import com.lagradost.cloudstream3.utils.VideoDownloadManager
import kotlinx.android.synthetic.main.fragment_result.*
const val VLC_PACKAGE = "org.videolan.vlc"
@ -57,14 +51,7 @@ class MainActivity : AppCompatActivity() {
var isInPlayer: Boolean = false
var canShowPipMode: Boolean = false
var isInPIPMode: Boolean = false
lateinit var mainContext: MainActivity
lateinit var navOptions: NavOptions
//https://github.com/anggrayudi/SimpleStorage/blob/4eb6306efb6cdfae4e34f170c8b9d4e135b04d51/sample/src/main/java/com/anggrayudi/storage/sample/activity/MainActivity.kt#L624
const val REQUEST_CODE_STORAGE_ACCESS = 1
const val REQUEST_CODE_PICK_FOLDER = 2
const val REQUEST_CODE_PICK_FILE = 3
const val REQUEST_CODE_ASK_PERMISSIONS = 4
}
private fun enterPIPMode() {
@ -149,7 +136,7 @@ class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mainContext = this
window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN)
setContentView(R.layout.activity_main)
val navView: BottomNavigationView = findViewById(R.id.nav_view)
@ -174,9 +161,9 @@ class MainActivity : AppCompatActivity() {
navView.setOnNavigationItemSelectedListener { item ->
when (item.itemId) {
// R.id.navigation_home -> {
// navController.navigate(R.id.navigation_home, null, navOptions)
//}
R.id.navigation_home -> {
navController.navigate(R.id.navigation_home, null, navOptions)
}
R.id.navigation_search -> {
navController.navigate(R.id.navigation_search, null, navOptions)
}
@ -232,7 +219,6 @@ class MainActivity : AppCompatActivity() {
}*/
/*
val castContext = CastContext.getSharedInstance(applicationContext)
fun buildMediaQueueItem(video: String): MediaQueueItem {

View file

@ -31,6 +31,7 @@ import androidx.core.graphics.alpha
import androidx.core.graphics.blue
import androidx.core.graphics.green
import androidx.core.graphics.red
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.preference.PreferenceManager
import com.google.android.gms.cast.framework.CastContext
@ -68,6 +69,14 @@ object UIHelper {
)
}
fun Fragment.hideKeyboard() {
view.let {
if (it != null) {
activity?.hideKeyboard(it)
}
}
}
@ColorInt
fun Context.getResourceColor(@AttrRes resource: Int, alphaFactor: Float = 1f): Int {
val typedArray = obtainStyledAttributes(intArrayOf(resource))

View file

@ -105,7 +105,7 @@ object DownloadButtonSetup {
downloadView: View,
downloadImageChangeCallback: (Pair<Int, String>) -> Unit,
clickCallback: (DownloadClickEvent) -> Unit,
) {
): () -> Unit {
var lastState: VideoDownloadManager.DownloadType? = null
var currentBytes = setupCurrentBytes ?: 0
var totalBytes = setupTotalBytes ?: 0
@ -174,7 +174,7 @@ object DownloadButtonSetup {
fixDownloadedBytes(currentBytes, totalBytes, false)
changeDownloadImage(VideoDownloadManager.getDownloadState(data.id))
VideoDownloadManager.downloadProgressEvent += { downloadData ->
val downloadProgressEventListener = { downloadData: Triple<Int, Long, Long> ->
if (data.id == downloadData.first) {
if (downloadData.second != currentBytes || downloadData.third != totalBytes) { // TO PREVENT WASTING UI TIME
Coroutines.runOnMainThread {
@ -184,7 +184,7 @@ object DownloadButtonSetup {
}
}
VideoDownloadManager.downloadStatusEvent += { downloadData ->
val downloadStatusEventListener = { downloadData: Pair<Int, VideoDownloadManager.DownloadType> ->
if (data.id == downloadData.first) {
if (lastState != downloadData.second || needImageUpdate) { // TO PREVENT WASTING UI TIME
Coroutines.runOnMainThread {
@ -194,6 +194,9 @@ object DownloadButtonSetup {
}
}
VideoDownloadManager.downloadProgressEvent += downloadProgressEventListener
VideoDownloadManager.downloadStatusEvent += downloadStatusEventListener
downloadView.setOnClickListener {
if (currentBytes <= 0) {
clickCallback.invoke(DownloadClickEvent(DOWNLOAD_ACTION_DOWNLOAD, data))
@ -220,6 +223,11 @@ object DownloadButtonSetup {
}
}
}
return {
VideoDownloadManager.downloadProgressEvent -= downloadProgressEventListener
VideoDownloadManager.downloadStatusEvent -= downloadStatusEventListener
}
}
fun setUpMaterialButton(
@ -230,8 +238,8 @@ object DownloadButtonSetup {
textView: TextView?,
data: VideoDownloadHelper.DownloadEpisodeCached,
clickCallback: (DownloadClickEvent) -> Unit,
) {
setUpDownloadButton(setupCurrentBytes, setupTotalBytes, progressBar, textView, data, downloadButton, {
): () -> Unit {
return setUpDownloadButton(setupCurrentBytes, setupTotalBytes, progressBar, textView, data, downloadButton, {
downloadButton?.setIconResource(it.first)
downloadButton?.text = it.second
}, clickCallback)
@ -245,8 +253,8 @@ object DownloadButtonSetup {
textView: TextView?,
data: VideoDownloadHelper.DownloadEpisodeCached,
clickCallback: (DownloadClickEvent) -> Unit,
) {
setUpDownloadButton(setupCurrentBytes, setupTotalBytes, progressBar, textView, data, downloadImage, {
): () -> Unit {
return setUpDownloadButton(setupCurrentBytes, setupTotalBytes, progressBar, textView, data, downloadImage, {
downloadImage?.setImageResource(it.first)
}, clickCallback)
}

View file

@ -16,6 +16,7 @@ import com.lagradost.cloudstream3.ui.download.DOWNLOAD_ACTION_DOWNLOAD
import com.lagradost.cloudstream3.ui.download.DownloadButtonSetup
import com.lagradost.cloudstream3.ui.download.DownloadButtonSetup.handleDownloadClick
import com.lagradost.cloudstream3.ui.download.DownloadClickEvent
import com.lagradost.cloudstream3.utils.Event
import com.lagradost.cloudstream3.utils.VideoDownloadHelper
import com.lagradost.cloudstream3.utils.VideoDownloadManager
import kotlinx.android.synthetic.main.result_episode.view.episode_holder
@ -46,8 +47,8 @@ class EpisodeAdapter(
private val hasDownloadSupport: Boolean,
private val clickCallback: (EpisodeClickEvent) -> Unit,
private val downloadClickCallback: (DownloadClickEvent) -> Unit,
) :
RecyclerView.Adapter<RecyclerView.ViewHolder>() {
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
@LayoutRes
private var layout: Int = 0
fun updateLayout() {

View file

@ -38,6 +38,7 @@ import com.lagradost.cloudstream3.UIHelper.checkWrite
import com.lagradost.cloudstream3.UIHelper.colorFromAttribute
import com.lagradost.cloudstream3.UIHelper.fixPaddingStatusbar
import com.lagradost.cloudstream3.UIHelper.getStatusBarHeight
import com.lagradost.cloudstream3.UIHelper.hideKeyboard
import com.lagradost.cloudstream3.UIHelper.isAppInstalled
import com.lagradost.cloudstream3.UIHelper.isCastApiAvailable
import com.lagradost.cloudstream3.UIHelper.isConnectedToChromecast
@ -65,6 +66,9 @@ import jp.wasabeef.glide.transformations.BlurTransformation
import kotlinx.android.synthetic.main.fragment_result.*
import kotlinx.coroutines.Job
import java.io.File
import java.util.*
import kotlin.collections.ArrayList
import kotlin.collections.HashMap
const val MAX_SYNO_LENGH = 300
@ -220,6 +224,9 @@ class ResultFragment : Fragment() {
@SuppressLint("SetTextI18n")
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
activity?.window?.decorView?.clearFocus()
hideKeyboard()
activity?.fixPaddingStatusbar(result_scroll)
activity?.fixPaddingStatusbar(result_barstatus)

View file

@ -8,6 +8,7 @@ import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.cardview.widget.CardView
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.bumptech.glide.load.model.GlideUrl
@ -56,17 +57,17 @@ class SearchAdapter(
constructor(itemView: View, _activity: Activity, resView: AutofitRecyclerView) : RecyclerView.ViewHolder(itemView) {
val activity = _activity
val cardView: ImageView = itemView.imageView
val cardText: TextView = itemView.imageText
val text_type: TextView? = itemView.text_type
private val cardText: TextView = itemView.imageText
private val textType: TextView? = itemView.text_type
// val search_result_lang: ImageView? = itemView.search_result_lang
val text_is_dub: View? = itemView.text_is_dub
val text_is_sub: View? = itemView.text_is_sub
private val textIsDub: View? = itemView.text_is_dub
private val textIsSub: View? = itemView.text_is_sub
//val cardTextExtra: TextView? = itemView.imageTextExtra
//val imageTextProvider: TextView? = itemView.imageTextProvider
val bg = itemView.backgroundCard
val compactView = itemView.context.getGridIsCompact()
private val bg: CardView = itemView.backgroundCard
private val compactView = itemView.context.getGridIsCompact()
private val coverHeight: Int = if (compactView) 80.toPx else (resView.itemWidth / 0.68).roundToInt()
fun bind(card: Any) {
@ -80,7 +81,7 @@ class SearchAdapter(
}
}
text_type?.text = when (card.type) {
textType?.text = when (card.type) {
TvType.Anime -> "Anime"
TvType.Movie -> "Movie"
TvType.ONA -> "ONA"
@ -88,8 +89,8 @@ class SearchAdapter(
}
// search_result_lang?.visibility = View.GONE
text_is_dub?.visibility = View.GONE
text_is_sub?.visibility = View.GONE
textIsDub?.visibility = View.GONE
textIsSub?.visibility = View.GONE
cardText.text = card.name
@ -114,11 +115,11 @@ class SearchAdapter(
if (card.dubStatus?.size == 1) {
//search_result_lang?.visibility = View.VISIBLE
if (card.dubStatus.contains(DubStatus.Dubbed)) {
text_is_dub?.visibility = View.VISIBLE
textIsDub?.visibility = View.VISIBLE
//search_result_lang?.setColorFilter(ContextCompat.getColor(activity, R.color.dubColor))
} else if (card.dubStatus.contains(DubStatus.Subbed)) {
//search_result_lang?.setColorFilter(ContextCompat.getColor(activity, R.color.subColor))
text_is_sub?.visibility = View.VISIBLE
textIsSub?.visibility = View.VISIBLE
}
}
}

View file

@ -1,10 +1,13 @@
package com.lagradost.cloudstream3.ui.search
import android.content.Context
import android.content.res.Configuration
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import android.view.inputmethod.InputMethodManager
import android.widget.ImageView
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
@ -36,7 +39,9 @@ class SearchFragment : Fragment() {
): View? {
searchViewModel =
ViewModelProvider(this).get(SearchViewModel::class.java)
activity?.window?.setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE
)
return inflater.inflate(R.layout.fragment_search, container, false)
}
@ -125,9 +130,9 @@ class SearchFragment : Fragment() {
observe(searchViewModel.searchResponse) {
when (it) {
is Resource.Success -> {
it?.value?.let { data ->
(cardSpace.adapter as SearchAdapter).cardList = data
(cardSpace.adapter as SearchAdapter).notifyDataSetChanged()
it.value.let { data ->
(cardSpace?.adapter as SearchAdapter?)?.cardList = data
cardSpace?.adapter?.notifyDataSetChanged()
}
searchExitIcon.alpha = 1f
search_loading_bar.alpha = 0f
@ -144,6 +149,18 @@ class SearchFragment : Fragment() {
}
}
allApi.providersActive = requireActivity().getApiSettings()
main_search.setOnQueryTextFocusChangeListener { searchView, b ->
if (b) {
// https://stackoverflow.com/questions/12022715/unable-to-show-keyboard-automatically-in-the-searchview
searchView?.postDelayed({
val imm: InputMethodManager? =
requireActivity().getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager?
imm?.showSoftInput(view.findFocus(), 0)
}, 200)
}
}
main_search.onActionViewExpanded()
//searchViewModel.search("iron man")
//(activity as AppCompatActivity).loadResult("https://shiro.is/overlord-dubbed", "overlord-dubbed", "Shiro")
/*

View file

@ -14,8 +14,16 @@ class SearchViewModel : ViewModel() {
val searchResponse: LiveData<Resource<ArrayList<Any>>> get() = _searchResponse
var searchCounter = 0
private fun clearSearch() {
_searchResponse.postValue(Resource.Success(ArrayList()))
}
fun search(query: String) = viewModelScope.launch {
searchCounter++
if(query.length <= 1) {
clearSearch()
return@launch
}
val localSearchCounter = searchCounter
_searchResponse.postValue(Resource.Loading())
val data = safeApiCall {
@ -27,6 +35,10 @@ class SearchViewModel : ViewModel() {
fun quickSearch(query: String) = viewModelScope.launch {
searchCounter++
if(query.length <= 1) {
clearSearch()
return@launch
}
val localSearchCounter = searchCounter
_searchResponse.postValue(Resource.Loading())
val data = safeApiCall {

View file

@ -1,33 +0,0 @@
package com.lagradost.cloudstream3.utils
import com.google.android.exoplayer2.database.ExoDatabaseProvider
import com.google.android.exoplayer2.offline.DownloadManager
import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory
import com.google.android.exoplayer2.upstream.cache.LeastRecentlyUsedCacheEvictor
import com.google.android.exoplayer2.upstream.cache.SimpleCache
import com.lagradost.cloudstream3.MainActivity
import java.util.concurrent.Executor
object ExoPlayerHelper {
private val context = MainActivity.mainContext
val databaseProvider = ExoDatabaseProvider(context)
val downloadExecutor = Executor { obj: Runnable -> obj.run() }
val dataSourceFactory = DefaultHttpDataSourceFactory()
val downloadCache: SimpleCache by lazy {
SimpleCache(
context.cacheDir,
LeastRecentlyUsedCacheEvictor(20 * 1024 * 1024),
databaseProvider
)
}
val downloadManager: DownloadManager by lazy {
DownloadManager(context,
databaseProvider,
downloadCache,
dataSourceFactory,
downloadExecutor)
}
}

View file

@ -526,7 +526,6 @@ object VideoDownloadManager {
var count: Int
var bytesDownloaded = resumeLength
var isPaused = false
var isStopped = false
var isDone = false
@ -561,7 +560,8 @@ object VideoDownloadManager {
)
}
downloadEvent += { event ->
val downloadEventListener = { event: Pair<Int, DownloadActionType> ->
if (event.first == ep.id) {
when (event.second) {
DownloadActionType.Pause -> {
@ -579,6 +579,8 @@ object VideoDownloadManager {
}
}
downloadEvent += downloadEventListener
// UPDATE DOWNLOAD NOTIFICATION
val notificationCoroutine = main {
while (true) {
@ -620,6 +622,12 @@ object VideoDownloadManager {
connectionInputStream.close()
notificationCoroutine.cancel()
try {
downloadEvent -= downloadEventListener
} catch (e: Exception) {
e.printStackTrace()
}
try {
downloadStatus.remove(ep.id)
} catch (e: Exception) {

View file

@ -1,16 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<!--
<item
android:id="@+id/navigation_home"
android:icon="@drawable/ic_home_black_24dp"
android:title="@string/title_home"/>
-->
<item
android:id="@+id/navigation_search"
android:icon="@drawable/search_icon"
android:title="@string/title_search"/>
<item
android:id="@+id/navigation_downloads"
android:icon="@drawable/netflix_download"

View file

@ -3,14 +3,14 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/mobile_navigation"
app:startDestination="@+id/navigation_search">
app:startDestination="@+id/navigation_home">
<!-- <fragment
<fragment
android:id="@+id/navigation_home"
android:name="com.lagradost.cloudstream3.ui.home.HomeFragment"
android:label="@string/title_home"
tools:layout="@layout/fragment_home"/>
-->
<fragment
android:id="@+id/navigation_search"
android:name="com.lagradost.cloudstream3.ui.search.SearchFragment"
@ -26,13 +26,11 @@
android:id="@+id/navigation_settings"
android:layout_height="match_parent"
android:name="com.lagradost.cloudstream3.ui.settings.SettingsFragment"
android:label="@string/title_settings"
/>
android:label="@string/title_settings"/>
<fragment
android:id="@+id/navigation_download_child"
android:layout_height="match_parent"
android:name="com.lagradost.cloudstream3.ui.download.DownloadChildFragment"
android:label="@string/title_settings"
/>
android:label="@string/title_settings"/>
</navigation>