Fix some StrictMode warnings

This commit is contained in:
Koitharu
2020-11-09 20:33:53 +02:00
parent 908baebb62
commit 03dbd86363
10 changed files with 72 additions and 49 deletions

View File

@@ -3,6 +3,7 @@ package org.koitharu.kotatsu.core.network
import okhttp3.CookieJar
import okhttp3.OkHttpClient
import org.koin.android.ext.koin.androidContext
import org.koin.core.qualifier.named
import org.koin.dsl.module
import org.koitharu.kotatsu.core.network.cookies.PersistentCookieJar
import org.koitharu.kotatsu.core.network.cookies.cache.SetCookieCache
@@ -18,13 +19,14 @@ val networkModule
SharedPrefsCookiePersistor(androidContext())
)
}
single(named(CacheUtils.QUALIFIER_HTTP)) { CacheUtils.createHttpCache(androidContext()) }
single {
OkHttpClient.Builder().apply {
connectTimeout(20, TimeUnit.SECONDS)
readTimeout(60, TimeUnit.SECONDS)
writeTimeout(20, TimeUnit.SECONDS)
cookieJar(get())
cache(CacheUtils.createHttpCache(androidContext()))
cache(get(named(CacheUtils.QUALIFIER_HTTP)))
addInterceptor(UserAgentInterceptor())
addInterceptor(CloudFlareInterceptor())
}.build()

View File

@@ -20,24 +20,29 @@ import okhttp3.HttpUrl
import org.koitharu.kotatsu.core.network.cookies.cache.CookieCache
import org.koitharu.kotatsu.core.network.cookies.persistence.CookiePersistor
import java.util.*
import java.util.concurrent.atomic.AtomicBoolean
class PersistentCookieJar(
private val cache: CookieCache,
private val persistor: CookiePersistor
) : ClearableCookieJar {
init {
cache.addAll(persistor.loadAll())
}
private var isLoaded = AtomicBoolean(false)
@Synchronized
override fun saveFromResponse(url: HttpUrl, cookies: List<Cookie>) {
if (isLoaded.compareAndSet(false, true)) {
cache.addAll(persistor.loadAll())
}
cache.addAll(cookies)
persistor.saveAll(filterPersistentCookies(cookies))
}
@Synchronized
override fun loadForRequest(url: HttpUrl): List<Cookie> {
if (isLoaded.compareAndSet(false, true)) {
cache.addAll(persistor.loadAll())
}
val cookiesToRemove: MutableList<Cookie> = ArrayList()
val validCookies: MutableList<Cookie> = ArrayList()
val it = cache.iterator()

View File

@@ -15,22 +15,15 @@
*/
package org.koitharu.kotatsu.core.network.cookies.persistence
import android.annotation.SuppressLint
import android.content.Context
import android.content.SharedPreferences
import okhttp3.Cookie
import java.util.*
@SuppressLint("CommitPrefEdits")
class SharedPrefsCookiePersistor(private val sharedPreferences: SharedPreferences) :
CookiePersistor {
class SharedPrefsCookiePersistor(context: Context) : CookiePersistor {
constructor(context: Context) : this(
context.getSharedPreferences(
"cookies",
Context.MODE_PRIVATE
)
)
private val sharedPreferences by lazy {
context.getSharedPreferences("cookies", Context.MODE_PRIVATE)
}
override fun loadAll(): List<Cookie> {
val cookies: MutableList<Cookie> = ArrayList(sharedPreferences.all.size)

View File

@@ -16,6 +16,7 @@ import okhttp3.Request
import okio.IOException
import org.koin.android.ext.android.get
import org.koin.android.ext.android.inject
import org.koin.core.context.GlobalContext
import org.koitharu.kotatsu.BuildConfig
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.local.PagesCache
@@ -231,7 +232,7 @@ class DownloadService : BaseService() {
private fun confirmDataTransfer(context: Context, callback: () -> Unit) {
val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val settings = AppSettings(context)
val settings = GlobalContext.get().get<AppSettings>()
if (cm.isActiveNetworkMetered && settings.isTrafficWarningEnabled) {
CheckBoxAlertDialog.Builder(context)
.setTitle(R.string.warning)

View File

@@ -12,6 +12,10 @@ import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.cursoradapter.widget.CursorAdapter
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.koitharu.kotatsu.BuildConfig
import org.koitharu.kotatsu.R
@@ -50,27 +54,35 @@ class MangaSuggestionsProvider : SearchRecentSuggestionsProvider() {
private const val AUTHORITY = "${BuildConfig.APPLICATION_ID}.MangaSuggestionsProvider"
private const val MODE = DATABASE_MODE_QUERIES
@JvmStatic
private val uri = Uri.Builder()
.scheme(ContentResolver.SCHEME_CONTENT)
.authority(AUTHORITY)
.appendPath(SearchManager.SUGGEST_URI_PATH_QUERY)
.build()
@JvmStatic
private val projection = arrayOf("_id", SearchManager.SUGGEST_COLUMN_QUERY)
@JvmStatic
fun saveQuery(context: Context, query: String) {
SearchRecentSuggestions(
context,
AUTHORITY,
MODE
).saveRecentQuery(query, null)
fun saveQueryAsync(context: Context, query: String) {
GlobalScope.launch(Dispatchers.IO) {
saveQuery(context, query)
}
}
@JvmStatic
fun clearHistory(context: Context) {
fun saveQuery(context: Context, query: String) {
runCatching {
SearchRecentSuggestions(
context,
AUTHORITY,
MODE
).saveRecentQuery(query, null)
}.onFailure {
if (BuildConfig.DEBUG) {
it.printStackTrace()
}
}
}
suspend fun clearHistory(context: Context) = withContext(Dispatchers.IO) {
SearchRecentSuggestions(
context,
AUTHORITY,
@@ -78,15 +90,15 @@ class MangaSuggestionsProvider : SearchRecentSuggestionsProvider() {
).clearHistory()
}
@JvmStatic
fun getItemsCount(context: Context) = getCursor(context)?.use { it.count } ?: 0
suspend fun getItemsCount(context: Context) = withContext(Dispatchers.IO) {
getCursor(context)?.use { it.count } ?: 0
}
@JvmStatic
private fun getCursor(context: Context): Cursor? {
return context.contentResolver?.query(uri, projection, null, arrayOf(""), null)
}
@JvmStatic
@Deprecated("Need async implementation")
fun getSuggestionAdapter(context: Context): CursorAdapter? = getCursor(
context
)?.let { cursor ->
@@ -102,6 +114,5 @@ class MangaSuggestionsProvider : SearchRecentSuggestionsProvider() {
}
}
}
}
}

View File

@@ -50,7 +50,7 @@ class SearchActivity : BaseActivity(), SearchView.OnQueryTextListener {
.replace(R.id.container, SearchFragment.newInstance(source, query))
.commit()
searchView.clearFocus()
MangaSuggestionsProvider.saveQuery(this, query)
MangaSuggestionsProvider.saveQueryAsync(applicationContext, query)
true
} else false
}

View File

@@ -30,7 +30,7 @@ object SearchHelper {
override fun onQueryTextSubmit(query: String?): Boolean {
return if (!query.isNullOrBlank()) {
context.startActivity(GlobalSearchActivity.newIntent(context, query.trim()))
MangaSuggestionsProvider.saveQuery(context, query)
MangaSuggestionsProvider.saveQueryAsync(context.applicationContext, query)
true
} else false
}

View File

@@ -45,14 +45,18 @@ class HistorySettingsFragment : BasePreferenceFragment(R.string.history_and_cach
pref.summary = FileSizeUtils.formatBytes(pref.context, size)
}
}
findPreference<Preference>(AppSettings.KEY_SEARCH_HISTORY_CLEAR)?.let { p ->
val items = MangaSuggestionsProvider.getItemsCount(p.context)
p.summary = p.context.resources.getQuantityString(R.plurals.items, items, items)
findPreference<Preference>(AppSettings.KEY_SEARCH_HISTORY_CLEAR)?.let { pref ->
viewLifecycleScope.launchWhenResumed {
val items = MangaSuggestionsProvider.getItemsCount(pref.context)
pref.summary =
pref.context.resources.getQuantityString(R.plurals.items, items, items)
}
}
findPreference<Preference>(AppSettings.KEY_UPDATES_FEED_CLEAR)?.let { p ->
findPreference<Preference>(AppSettings.KEY_UPDATES_FEED_CLEAR)?.let { pref ->
viewLifecycleScope.launchWhenResumed {
val items = trackerRepo.count()
p.summary = p.context.resources.getQuantityString(R.plurals.items, items, items)
pref.summary =
pref.context.resources.getQuantityString(R.plurals.items, items, items)
}
}
}
@@ -68,14 +72,16 @@ class HistorySettingsFragment : BasePreferenceFragment(R.string.history_and_cach
true
}
AppSettings.KEY_SEARCH_HISTORY_CLEAR -> {
MangaSuggestionsProvider.clearHistory(preference.context)
preference.summary = preference.context.resources
.getQuantityString(R.plurals.items, 0, 0)
Snackbar.make(
view ?: return true,
R.string.search_history_cleared,
Snackbar.LENGTH_SHORT
).show()
viewLifecycleScope.launch {
MangaSuggestionsProvider.clearHistory(preference.context)
preference.summary = preference.context.resources
.getQuantityString(R.plurals.items, 0, 0)
Snackbar.make(
view ?: return@launch,
R.string.search_history_cleared,
Snackbar.LENGTH_SHORT
).show()
}
true
}
AppSettings.KEY_UPDATES_FEED_CLEAR -> {

View File

@@ -12,6 +12,8 @@ import java.io.File
object CacheUtils {
const val QUALIFIER_HTTP = "cache_http"
val CONTROL_DISABLED = CacheControl.Builder()
.noStore()
.build()
@@ -30,6 +32,7 @@ object CacheUtils {
.map { it.sub(name) }
.forEach { it.deleteRecursively() }
// FIXME need async implementation
fun createHttpCache(context: Context): Cache {
val directory = (context.externalCacheDir ?: context.cacheDir).sub("http")
directory.mkdirs()

View File

@@ -4,16 +4,18 @@ import android.content.Context
import android.view.View
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import org.koin.core.component.KoinComponent
import org.koin.core.component.get
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.prefs.AppSettings
import org.koitharu.kotatsu.utils.ext.measureWidth
import kotlin.math.abs
import kotlin.math.roundToInt
object UiUtils {
object UiUtils : KoinComponent {
fun resolveGridSpanCount(context: Context, width: Int = 0): Int {
val scaleFactor = AppSettings(context).gridSize / 100f
val scaleFactor = get<AppSettings>().gridSize / 100f
val cellWidth = context.resources.getDimension(R.dimen.preferred_grid_width) * scaleFactor
val screenWidth = (if (width <= 0) {
context.resources.displayMetrics.widthPixels