parent
0fdd3b6fbd
commit
87217696dd
@ -1,26 +0,0 @@ |
||||
package top.niunaijun.blackdex |
||||
|
||||
import android.app.Application |
||||
import android.content.Context |
||||
import top.niunaijun.blackbox.BlackDexCore |
||||
import top.niunaijun.blackbox.app.configuration.ClientConfiguration |
||||
import top.niunaijun.blackdex.data.BlackDexConfiguration |
||||
|
||||
/** |
||||
* |
||||
* @Description: |
||||
* @Author: wukaicheng |
||||
* @CreateDate: 2021/5/23 14:00 |
||||
*/ |
||||
class App : Application() { |
||||
|
||||
override fun attachBaseContext(base: Context?) { |
||||
super.attachBaseContext(base) |
||||
BlackDexCore.get().doAttachBaseContext(base,BlackDexConfiguration(base!!)) |
||||
} |
||||
|
||||
override fun onCreate() { |
||||
super.onCreate() |
||||
BlackDexCore.get().doCreate() |
||||
} |
||||
} |
@ -0,0 +1,38 @@ |
||||
package top.niunaijun.blackboxa.app |
||||
|
||||
import android.annotation.SuppressLint |
||||
import android.app.Application |
||||
import android.content.Context |
||||
import top.niunaijun.blackdex.app.AppManager |
||||
|
||||
/** |
||||
* |
||||
* @Description: |
||||
* @Author: wukaicheng |
||||
* @CreateDate: 2021/4/29 21:21 |
||||
*/ |
||||
class App : Application() { |
||||
|
||||
companion object { |
||||
|
||||
@SuppressLint("StaticFieldLeak") |
||||
@Volatile |
||||
private lateinit var mContext: Context |
||||
|
||||
@JvmStatic |
||||
fun getContext(): Context { |
||||
return mContext |
||||
} |
||||
} |
||||
|
||||
override fun attachBaseContext(base: Context?) { |
||||
super.attachBaseContext(base) |
||||
mContext = base!! |
||||
AppManager.doAttachBaseContext(base) |
||||
} |
||||
|
||||
override fun onCreate() { |
||||
super.onCreate() |
||||
AppManager.doOnCreate(mContext) |
||||
} |
||||
} |
@ -0,0 +1,26 @@ |
||||
package top.niunaijun.blackdex.app |
||||
|
||||
import android.content.Context |
||||
|
||||
object AppManager { |
||||
@JvmStatic |
||||
val mBlackBoxLoader by lazy { |
||||
BlackDexLoader() |
||||
} |
||||
|
||||
fun doAttachBaseContext(context: Context) { |
||||
try { |
||||
mBlackBoxLoader.attachBaseContext(context) |
||||
mBlackBoxLoader.addLifecycleCallback() |
||||
} catch (e: Exception) { |
||||
e.printStackTrace() |
||||
} |
||||
} |
||||
|
||||
fun doOnCreate(context: Context) { |
||||
mBlackBoxLoader.doOnCreate(context) |
||||
initThirdService(context) |
||||
} |
||||
|
||||
private fun initThirdService(context: Context) {} |
||||
} |
@ -0,0 +1,87 @@ |
||||
package top.niunaijun.blackdex.app |
||||
|
||||
import android.content.Context |
||||
import top.niunaijun.blackbox.BlackDexCore |
||||
import top.niunaijun.blackbox.app.configuration.ClientConfiguration |
||||
import top.niunaijun.blackbox.utils.FileUtils |
||||
import top.niunaijun.blackbox.utils.compat.BuildCompat |
||||
import top.niunaijun.blackboxa.app.App |
||||
import top.niunaijun.blackdex.biz.cache.AppSharedPreferenceDelegate |
||||
import java.io.File |
||||
|
||||
/** |
||||
* |
||||
* @Description: |
||||
* @Author: wukaicheng |
||||
* @CreateDate: 2021/5/6 23:38 |
||||
*/ |
||||
class BlackDexLoader { |
||||
|
||||
|
||||
private var mSavePath by AppSharedPreferenceDelegate(App.getContext(), "") |
||||
|
||||
private var mSaveEnable by AppSharedPreferenceDelegate(App.getContext(), false) |
||||
|
||||
private var mDir = if (mSaveEnable) { |
||||
getDexDumpDir(App.getContext()) |
||||
} else { |
||||
mSavePath |
||||
} |
||||
|
||||
fun addLifecycleCallback() { |
||||
|
||||
} |
||||
|
||||
fun attachBaseContext(context: Context) { |
||||
BlackDexCore.get().doAttachBaseContext(context, object : ClientConfiguration() { |
||||
override fun getHostPackageName(): String { |
||||
return context.packageName |
||||
} |
||||
|
||||
override fun getDexDumpDir(): String { |
||||
return mDir |
||||
} |
||||
}) |
||||
} |
||||
|
||||
fun doOnCreate(context: Context) { |
||||
BlackDexCore.get().doCreate() |
||||
} |
||||
|
||||
fun saveEnable(): Boolean { |
||||
return mSaveEnable |
||||
} |
||||
|
||||
fun saveEnable(state: Boolean) { |
||||
this.mSaveEnable = state |
||||
} |
||||
|
||||
fun getSavePath(): String { |
||||
return mSavePath |
||||
} |
||||
|
||||
fun setSavePath(path: String) { |
||||
this.mSavePath = path |
||||
} |
||||
|
||||
|
||||
companion object { |
||||
|
||||
val TAG: String = BlackDexLoader::class.java.simpleName |
||||
|
||||
fun getDexDumpDir(context: Context): String { |
||||
return if (BuildCompat.isR()) { |
||||
val dump = File( |
||||
context.externalCacheDir?.parentFile?.parentFile?.parentFile?.parentFile, |
||||
"hupu/dexDump" |
||||
) |
||||
FileUtils.mkdirs(dump) |
||||
dump.absolutePath |
||||
} else { |
||||
val dump = File(context.externalCacheDir?.parentFile, "dump") |
||||
FileUtils.mkdirs(dump) |
||||
dump.absolutePath |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,67 @@ |
||||
package top.niunaijun.blackdex.biz.cache |
||||
|
||||
|
||||
import android.content.Context |
||||
import android.text.TextUtils |
||||
import androidx.core.content.edit |
||||
import kotlin.properties.ReadWriteProperty |
||||
import kotlin.reflect.KProperty |
||||
|
||||
|
||||
/** |
||||
* |
||||
* @desc:目前只支持 5种基本数据类型,如果要支持obj,请继承该类并重写他的相关方法 findData/putData |
||||
* |
||||
* @author: mini |
||||
* @created by 2021/5/10 |
||||
*/ |
||||
open class AppSharedPreferenceDelegate<Data>(context: Context, private val default: Data, spName: String? = null) : ReadWriteProperty<Any, Data?> { |
||||
|
||||
private val mSharedPreferences by lazy { |
||||
val tmpCacheName = if (TextUtils.isEmpty(spName)) { |
||||
AppSharedPreferenceDelegate::class.java.simpleName |
||||
} else { |
||||
spName |
||||
} |
||||
return@lazy context.getSharedPreferences(tmpCacheName, Context.MODE_PRIVATE) |
||||
} |
||||
|
||||
override fun getValue(thisRef: Any, property: KProperty<*>): Data { |
||||
return findData(property.name, default) |
||||
} |
||||
|
||||
override fun setValue(thisRef: Any, property: KProperty<*>, value: Data?) { |
||||
putData(property.name, value) |
||||
} |
||||
|
||||
protected fun findData(key: String, default: Data): Data { |
||||
with(mSharedPreferences) { |
||||
val result: Any? = when (default) { |
||||
is Int -> getInt(key, default) |
||||
is Long -> getLong(key, default) |
||||
is Float -> getFloat(key, default) |
||||
is String -> getString(key, default) |
||||
is Boolean -> getBoolean(key, default) |
||||
else -> throw IllegalArgumentException("This type $default can not be saved into sharedPreferences") |
||||
} |
||||
return result as? Data ?: default |
||||
} |
||||
} |
||||
|
||||
protected fun putData(key: String, value: Data?) { |
||||
mSharedPreferences.edit { |
||||
if (value == null) { |
||||
remove(key) |
||||
} else { |
||||
when (value) { |
||||
is Int -> putInt(key, value) |
||||
is Long -> putLong(key, value) |
||||
is Float -> putFloat(key, value) |
||||
is String -> putString(key, value) |
||||
is Boolean -> putBoolean(key, value) |
||||
else -> throw IllegalArgumentException("This type $default can not be saved into Preferences") |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
@ -1,41 +0,0 @@ |
||||
package top.niunaijun.blackdex.data |
||||
|
||||
import android.content.Context |
||||
import top.niunaijun.blackbox.app.configuration.ClientConfiguration |
||||
import top.niunaijun.blackbox.utils.FileUtils |
||||
import top.niunaijun.blackbox.utils.compat.BuildCompat |
||||
import java.io.File |
||||
|
||||
/** |
||||
* |
||||
* @Description: 启动配置文件 |
||||
* @Author: wukaicheng |
||||
* @CreateDate: 2021/5/23 14:04 |
||||
*/ |
||||
class BlackDexConfiguration(private val context: Context) : ClientConfiguration() { |
||||
|
||||
companion object { |
||||
fun getDexDumpDir(context: Context): String { |
||||
return if (BuildCompat.isR()) { |
||||
val dump = File(context.externalCacheDir?.parentFile?.parentFile?.parentFile?.parentFile, "Download/dexDump") |
||||
FileUtils.mkdirs(dump) |
||||
dump.absolutePath |
||||
} else { |
||||
val dump = File(context.externalCacheDir?.parentFile, "dump") |
||||
FileUtils.mkdirs(dump) |
||||
dump.absolutePath |
||||
} |
||||
} |
||||
} |
||||
|
||||
private val dir = getDexDumpDir(context) |
||||
|
||||
override fun getHostPackageName(): String { |
||||
return context.packageName |
||||
} |
||||
|
||||
override fun getDexDumpDir(): String { |
||||
return dir |
||||
} |
||||
|
||||
} |
@ -0,0 +1,19 @@ |
||||
package top.niunaijun.blackdex.view.setting |
||||
|
||||
import android.os.Bundle |
||||
import top.niunaijun.blackdex.R |
||||
import top.niunaijun.blackdex.databinding.ActivitySettingBinding |
||||
import top.niunaijun.blackdex.util.inflate |
||||
import top.niunaijun.blackdex.view.base.BaseActivity |
||||
|
||||
class SettingActivity : BaseActivity() { |
||||
|
||||
private val viewBinding: ActivitySettingBinding by inflate() |
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) { |
||||
super.onCreate(savedInstanceState) |
||||
setContentView(viewBinding.root) |
||||
initToolbar(viewBinding.toolbarLayout.toolbar, R.string.app_setting,true) |
||||
supportFragmentManager.beginTransaction().replace(R.id.fragment,SettingFragment()).commit() |
||||
} |
||||
} |
@ -0,0 +1,61 @@ |
||||
package top.niunaijun.blackdex.view.setting |
||||
|
||||
import android.os.Bundle |
||||
import android.os.Environment |
||||
import androidx.preference.Preference |
||||
import androidx.preference.PreferenceFragmentCompat |
||||
import androidx.preference.SwitchPreferenceCompat |
||||
import com.afollestad.materialdialogs.MaterialDialog |
||||
import com.afollestad.materialdialogs.files.folderChooser |
||||
import top.niunaijun.blackdex.R |
||||
import top.niunaijun.blackdex.app.AppManager |
||||
import java.io.File |
||||
|
||||
/** |
||||
* |
||||
* @Description: |
||||
* @Author: wukaicheng |
||||
* @CreateDate: 2021/5/28 19:55 |
||||
*/ |
||||
class SettingFragment : PreferenceFragmentCompat() { |
||||
|
||||
private lateinit var savePathPreference: Preference |
||||
|
||||
private lateinit var saveEnablePreference: SwitchPreferenceCompat |
||||
|
||||
private val initialDirectory = AppManager.mBlackBoxLoader.getSavePath() |
||||
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { |
||||
addPreferencesFromResource(R.xml.setting) |
||||
savePathPreference = findPreference("save_path")!! |
||||
savePathPreference.onPreferenceClickListener = mSavedPathClick |
||||
savePathPreference.summary = initialDirectory |
||||
|
||||
saveEnablePreference = findPreference("save_enable")!! |
||||
saveEnablePreference.onPreferenceChangeListener = mSaveEnableChange |
||||
|
||||
} |
||||
|
||||
private val mSavedPathClick = Preference.OnPreferenceClickListener { |
||||
val initialFile = with(initialDirectory) { |
||||
if (initialDirectory.isEmpty()) { |
||||
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) |
||||
} else { |
||||
File(this) |
||||
} |
||||
} |
||||
|
||||
MaterialDialog(requireContext()).show { |
||||
folderChooser(requireContext(), initialDirectory = initialFile,allowFolderCreation = true) { _, file -> |
||||
AppManager.mBlackBoxLoader.setSavePath(file.absolutePath) |
||||
savePathPreference.summary = file.absolutePath |
||||
} |
||||
} |
||||
return@OnPreferenceClickListener true |
||||
} |
||||
|
||||
private val mSaveEnableChange = Preference.OnPreferenceChangeListener { _, newValue -> |
||||
AppManager.mBlackBoxLoader.saveEnable(newValue as Boolean) |
||||
return@OnPreferenceChangeListener true |
||||
} |
||||
} |
@ -0,0 +1,22 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||
xmlns:app="http://schemas.android.com/apk/res-auto" |
||||
xmlns:tools="http://schemas.android.com/tools" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent" |
||||
android:orientation="vertical" |
||||
tools:context=".view.setting.SettingActivity"> |
||||
|
||||
<include |
||||
android:id="@+id/toolbar_layout" |
||||
layout="@layout/view_toolbar" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
app:layout_constraintTop_toTopOf="parent" /> |
||||
|
||||
<androidx.fragment.app.FragmentContainerView |
||||
android:id="@+id/fragment" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent" /> |
||||
|
||||
</LinearLayout> |
@ -0,0 +1,15 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> |
||||
|
||||
<PreferenceCategory android:title="文件储存"> |
||||
<SwitchPreferenceCompat |
||||
android:disableDependentsState="true" |
||||
android:key="save_enable" |
||||
android:title="使用默认储存路径" /> |
||||
|
||||
<Preference |
||||
android:dependency="save_enable" |
||||
android:key="save_path" |
||||
android:title="自定义储存路径" /> |
||||
</PreferenceCategory> |
||||
</PreferenceScreen> |
Loading…
Reference in new issue