Skip to content

Commit

Permalink
[feature|optimize] Support select dark mode strategy; support buildin…
Browse files Browse the repository at this point in the history
…g multiple APKs per ABI; optimize code
  • Loading branch information
SkyD666 committed Apr 6, 2024
1 parent cb0a441 commit 2979eca
Show file tree
Hide file tree
Showing 18 changed files with 540 additions and 95 deletions.
58 changes: 45 additions & 13 deletions .github/workflows/pre_release.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: Pre-Release

# 触发器
# Trigger
on:
workflow_dispatch:
push:
Expand All @@ -26,29 +26,53 @@ jobs:
uses: actions/checkout@v3
with:
repository: ${{ secrets.SECRET_REPO }}
token: ${{ secrets.TOKEN }} # 连接仓库的Token
token: ${{ secrets.TOKEN }} # Repo token
path: secret
# 准备 secret 文件
# Prepare secret files
- name: Copy Secret Files
run: |
cd secret/AniVu
cp key.jks ../..
cp secret.gradle.kts ../..
# 清理 secret 文件
# Clean secret files
- name: Clean Temp Secret Files
run: |
rm -rf ./secret
# 构建
# Build
- name: Build with Gradle
run: |
bash ./gradlew assembleGitHubRelease
# 上传 apk
- name: Upload Pre-Release Apk
# Upload apk (arm64-v8a)
- name: Upload Pre-Release Apk (arm64-v8a)
uses: actions/upload-artifact@v3
with:
name: Pre-Release Apk
path: app/build/outputs/apk/GitHub/release/*.apk
# 上传 mapping
name: Pre-Release Apk (arm64-v8a)
path: app/build/outputs/apk/GitHub/release/*arm64-v8a*.apk
# Upload apk (armeabi-v7a)
- name: Upload Pre-Release Apk (armeabi-v7a)
uses: actions/upload-artifact@v3
with:
name: Pre-Release Apk (armeabi-v7a)
path: app/build/outputs/apk/GitHub/release/*armeabi-v7a*.apk
# Upload apk (x86_64)
- name: Upload Pre-Release Apk (x86_64)
uses: actions/upload-artifact@v3
with:
name: Pre-Release Apk (x86_64)
path: app/build/outputs/apk/GitHub/release/*x86_64*.apk
# Upload apk (x86)
- name: Upload Pre-Release Apk (x86)
uses: actions/upload-artifact@v3
with:
name: Pre-Release Apk (x86)
path: app/build/outputs/apk/GitHub/release/*x86*.apk
# Upload apk (universal)
- name: Upload Pre-Release Apk (universal)
uses: actions/upload-artifact@v3
with:
name: Pre-Release Apk (universal)
path: app/build/outputs/apk/GitHub/release/*universal*.apk
# Upload mapping
- name: Upload Pre-Release Mapping
uses: actions/upload-artifact@v3
with:
Expand All @@ -57,14 +81,22 @@ jobs:
# 获取 apk 路径
- name: Get Pre-Release Apk File Path
run: |
echo "PRE_RELEASE_APK=$(find app/build/outputs/apk/GitHub/release -name '*.apk' -type f | head -1)" >> $GITHUB_ENV
echo "PRE_RELEASE_APK_ARM64_V8=$(find app/build/outputs/apk/GitHub/release -name '*arm64-v8a*.apk' -type f | head -1)" >> $GITHUB_ENV
echo "PRE_RELEASE_APK_ARM_V7=$(find app/build/outputs/apk/GitHub/release -name '*armeabi-v7a*.apk' -type f | head -1)" >> $GITHUB_ENV
echo "PRE_RELEASE_APK_X86_64=$(find app/build/outputs/apk/GitHub/release -name '*x86_64*.apk' -type f | head -1)" >> $GITHUB_ENV
echo "PRE_RELEASE_APK_X86=$(find app/build/outputs/apk/GitHub/release -name '*x86*.apk' -type f | head -1)" >> $GITHUB_ENV
echo "PRE_RELEASE_APK_UNIVERSAL=$(find app/build/outputs/apk/GitHub/release -name '*universal*.apk' -type f | head -1)" >> $GITHUB_ENV
# 发送至 Telegram 频道
- name: Post to Telegram Channel
if: github.ref == 'refs/heads/master' && contains(github.event.head_commit.message, '[skip_post]') == false
env:
CHANNEL_ID: ${{ secrets.TELEGRAM_TO }}
BOT_TOKEN: ${{ secrets.TELEGRAM_TOKEN }}
PRE_RELEASE: ${{ env.PRE_RELEASE_APK }}
PRE_RELEASE_ARM64_V8: ${{ env.PRE_RELEASE_APK_ARM64_V8 }}
PRE_RELEASE_ARM_V7: ${{ env.PRE_RELEASE_APK_ARM_V7 }}
PRE_RELEASE_X86_64: ${{ env.PRE_RELEASE_APK_X86_64 }}
PRE_RELEASE_X86: ${{ env.PRE_RELEASE_APK_X86 }}
PRE_RELEASE_UNIVERSAL: ${{ env.PRE_RELEASE_APK_UNIVERSAL }}
COMMIT_MESSAGE: |+
GitHub New CI: AniVu\
Expand All @@ -75,4 +107,4 @@ jobs:
Commit details [here](${{ github.event.head_commit.url }})
run: |
ESCAPED=`python3 -c 'import json,os,urllib.parse; print(urllib.parse.quote(json.dumps(os.environ["COMMIT_MESSAGE"])))'`
curl -v "https://api.telegram.org/bot${BOT_TOKEN}/sendMediaGroup?chat_id=${CHANNEL_ID}&media=%5B%7B%22type%22%3A%22document%22%2C%20%22media%22%3A%22attach%3A%2F%2Fpre_release%22%2C%22parse_mode%22%3A%22MarkdownV2%22%2C%22caption%22%3A${ESCAPED}%7D%5D" -F pre_release="@$PRE_RELEASE"
curl -v "https://api.telegram.org/bot${BOT_TOKEN}/sendMediaGroup?chat_id=${CHANNEL_ID}&media=%5B%7B%22type%22%3A%22document%22%2C%20%22media%22%3A%22attach%3A%2F%2Fpre_release_arm64_v8%22%7D%2C%7B%22type%22%3A%22document%22%2C%20%22media%22%3A%22attach%3A%2F%2Fpre_release_arm_v7%22%2C%22parse_mode%22%3A%22MarkdownV2%22%2C%22caption%22%3A${ESCAPED}%7D%5D" -F pre_release_arm64_v8="@$PRE_RELEASE_ARM64_V8" -F pre_release_arm_v7="@$PRE_RELEASE_ARM_V7"
35 changes: 25 additions & 10 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import com.android.build.api.variant.FilterConfiguration
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
Expand All @@ -20,7 +21,7 @@ android {
minSdk = 24
targetSdk = 34
versionCode = 10
versionName = "1.1-beta02"
versionName = "1.1-beta03"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"

Expand Down Expand Up @@ -49,11 +50,27 @@ android {
}
}

splits {
abi {
// Enables building multiple APKs per ABI.
isEnable = true
// By default all ABIs are included, so use reset() and include().
// Resets the list of ABIs for Gradle to create APKs for to none.
reset()
// A list of ABIs for Gradle to create APKs for.
include("arm64-v8a", "armeabi-v7a", "x86", "x86_64")
// We want to also generate a universal APK that includes all ABIs.
isUniversalApk = true
}
}

applicationVariants.all {
outputs
.map { it as com.android.build.gradle.internal.api.BaseVariantOutputImpl }
.forEach {
it.outputFileName = "AniVu_${versionName}_${buildType.name}_${flavorName}.apk"
.forEach { output ->
val abi = output.getFilter(FilterConfiguration.FilterType.ABI.name) ?: "universal"
output.outputFileName =
"AniVu_${versionName}_${buildType.name}_${abi}_${flavorName}.apk"
}
}

Expand All @@ -66,9 +83,6 @@ android {
"proguard-rules.pro"
)
applicationIdSuffix = ".debug"
ndk {
abiFilters += mutableSetOf("armeabi-v7a", "x86", "x86_64", "arm64-v8a")
}
}
release {
signingConfig = signingConfigs.getByName("release") // signing
Expand All @@ -78,10 +92,6 @@ android {
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
ndk {
//noinspection ChromeOsAbiSupport
abiFilters += "arm64-v8a"
}
}
}
compileOptions {
Expand Down Expand Up @@ -155,8 +165,13 @@ dependencies {
implementation("io.coil-kt:coil:2.6.0")
implementation("com.rometools:rome:2.1.0")
implementation("net.dankito.readability4j:readability4j:1.0.8")

implementation("org.libtorrent4j:libtorrent4j-android-arm64:2.1.0-31")
implementation("org.libtorrent4j:libtorrent4j-android-arm:2.1.0-31")
implementation("org.libtorrent4j:libtorrent4j-android-x86:2.1.0-31")
implementation("org.libtorrent4j:libtorrent4j-android-x86_64:2.1.0-31")

// debugImplementation("com.squareup.leakcanary:leakcanary-android:2.13")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
Expand Down
9 changes: 5 additions & 4 deletions app/src/main/java/com/skyd/anivu/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ package com.skyd.anivu

import android.app.Application
import android.content.Context
import com.google.android.material.color.DynamicColors
import com.skyd.anivu.model.preference.appearance.ThemePreference
import androidx.appcompat.app.AppCompatDelegate
import com.skyd.anivu.ext.dataStore
import com.skyd.anivu.ext.getOrDefault
import com.skyd.anivu.model.preference.appearance.DarkModePreference
import com.skyd.anivu.model.worker.deletearticle.listenerDeleteArticleFrequency
import com.skyd.anivu.model.worker.rsssync.listenerRssSyncFrequency
import com.skyd.anivu.util.CrashHandler
Expand All @@ -16,11 +18,10 @@ class App : Application() {
override fun onCreate() {
super.onCreate()
appContext = this
AppCompatDelegate.setDefaultNightMode(dataStore.getOrDefault(DarkModePreference))

CrashHandler.init(this)

// DynamicColors.applyToActivitiesIfAvailable(this)
// setTheme(ThemePreference.toResId(this))
listenerRssSyncFrequency(this)
listenerDeleteArticleFrequency(this)
}
Expand Down
5 changes: 5 additions & 0 deletions app/src/main/java/com/skyd/anivu/ext/ContextExt.kt
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,9 @@ fun Context.getAppName(): String? {
e.printStackTrace()
null
}
}

fun Context.inDarkMode(): Boolean {
return (resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) ==
Configuration.UI_MODE_NIGHT_YES
}
23 changes: 6 additions & 17 deletions app/src/main/java/com/skyd/anivu/ext/ViewExt.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package com.skyd.anivu.ext

import android.annotation.TargetApi
import android.app.Activity
import android.content.Context
import android.graphics.Rect
import android.view.DisplayCutout
import android.view.View
Expand Down Expand Up @@ -30,7 +29,6 @@ import com.google.android.material.badge.BadgeDrawable
import com.google.android.material.badge.BadgeUtils
import com.google.android.material.badge.ExperimentalBadgeUtils
import com.skyd.anivu.R
import com.skyd.anivu.appContext


fun View.enable() {
Expand Down Expand Up @@ -74,21 +72,6 @@ val View.activity: Activity
val View.tryActivity: Activity?
get() = context.tryActivity

fun View.showKeyboard() {
isFocusable = true
isFocusableInTouchMode = true
requestFocus()
val inputManager =
appContext.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
inputManager.showSoftInput(this, 0)
}

fun View.hideKeyboard() {
val inputManager =
appContext.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
inputManager.hideSoftInputFromWindow(this.windowToken, 0)
}

/**
* 判断View和给定的Rect是否重叠(边和点不计入)
* @return true if overlap
Expand Down Expand Up @@ -238,6 +221,12 @@ fun View.showSoftKeyboard(window: Window) {
}
}

fun View.hideSoftKeyboard(window: Window) {
if (requestFocus()) {
WindowCompat.getInsetsController(window, this).hide(WindowInsetsCompat.Type.ime())
}
}

@TargetApi(28)
fun View.updateSafeInset(displayCutout: DisplayCutout) {
val location = IntArray(2)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.skyd.anivu.model.preference.appearance

import android.content.Context
import android.os.Build
import androidx.appcompat.app.AppCompatDelegate
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.intPreferencesKey
import com.skyd.anivu.R
import com.skyd.anivu.base.BasePreference
import com.skyd.anivu.ext.dataStore
import com.skyd.anivu.ext.put
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

object DarkModePreference : BasePreference<Int> {
private const val DARK_MODE = "darkMode"

val values: List<Int> = mutableListOf(
AppCompatDelegate.MODE_NIGHT_NO,
AppCompatDelegate.MODE_NIGHT_YES,
).apply {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
add(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
}
}

override val default = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
} else {
AppCompatDelegate.MODE_NIGHT_NO
}

val key = intPreferencesKey(DARK_MODE)

fun toDisplayName(context: Context, value: Int): String = context.getString(
when (value) {
AppCompatDelegate.MODE_NIGHT_NO -> R.string.dark_mode_light
AppCompatDelegate.MODE_NIGHT_YES -> R.string.dark_mode_dark
AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM -> R.string.dark_mode_follow_system
else -> R.string.unknown
}
)

fun put(context: Context, scope: CoroutineScope, value: Int) {
if (value != AppCompatDelegate.MODE_NIGHT_YES &&
value != AppCompatDelegate.MODE_NIGHT_NO &&
value != AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
) {
throw IllegalArgumentException("darkMode value invalid!!!")
}
scope.launch(Dispatchers.IO) {
context.dataStore.put(key, value)
withContext(Dispatchers.Main) {
AppCompatDelegate.setDefaultNightMode(value)
}
}
}

override fun fromPreferences(preferences: Preferences): Int {
val scope = CoroutineScope(context = Dispatchers.Main)
val value = preferences[key] ?: default
scope.launch(Dispatchers.Main) {
AppCompatDelegate.setDefaultNightMode(value)
}
return value
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package com.skyd.anivu.model.preference.appearance

import android.content.Context
import android.os.Build
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.stringPreferencesKey
import com.google.android.material.color.DynamicColors
import com.skyd.anivu.R
import com.skyd.anivu.base.BasePreference
import com.skyd.anivu.ext.dataStore
Expand All @@ -24,13 +24,15 @@ object ThemePreference : BasePreference<String> {
const val YELLOW = "Yellow"
const val PURPLE = "Purple"

val basicValues = arrayOf(PINK, GREEN, BLUE, YELLOW, PURPLE)

val values: Array<String>
get() {
val v = arrayOf(PINK, GREEN, BLUE, YELLOW, PURPLE)
return if (supportDynamicTheme()) arrayOf(DYNAMIC, *v) else v
return if (DynamicColors.isDynamicColorAvailable()) arrayOf(DYNAMIC, *basicValues)
else basicValues
}

override val default = if (supportDynamicTheme()) DYNAMIC else PINK
override val default = if (DynamicColors.isDynamicColorAvailable()) DYNAMIC else PINK

val key = stringPreferencesKey(THEME)

Expand All @@ -50,8 +52,6 @@ object ThemePreference : BasePreference<String> {

override fun fromPreferences(preferences: Preferences): String = preferences[key] ?: default

private fun supportDynamicTheme(): Boolean = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S

fun toDisplayName(
context: Context,
value: String = context.dataStore.getOrDefault(this),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ class CrashActivity : AppCompatActivity() {
append("VersionName: ").append(getAppVersionName()).append("\n")
append("Brand: ").append(Build.BRAND).append("\n")
append("Model: ").append(Build.MODEL).append("\n")
append("SDK Version: ").append(Build.VERSION.SDK_INT).append("\n\n")
append("SDK Version: ").append(Build.VERSION.SDK_INT).append("\n")
append("ABI: ").append(Build.SUPPORTED_ABIS.firstOrNull().orEmpty()).append("\n\n")
append("Crash Info: \n")
append(crashInfo)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class ColorPalette1Proxy(
ItemColorPalette1Binding
.inflate(LayoutInflater.from(parent.context), parent, false),
)
holder.itemView.setOnClickListener {
holder.binding.root.setOnClickListener {
onClick(holder.bindingAdapterPosition)
}
return holder
Expand Down
Loading

0 comments on commit 2979eca

Please sign in to comment.