mirror of
https://github.com/HighCapable/YukiHookAPI.git
synced 2025-09-04 09:45:19 +08:00
...
This commit is contained in:
22
app/proguard-rules.pro
vendored
22
app/proguard-rules.pro
vendored
@@ -18,4 +18,24 @@
|
|||||||
|
|
||||||
# If you keep the line number information, uncomment this to
|
# If you keep the line number information, uncomment this to
|
||||||
# hide the original source file name.
|
# hide the original source file name.
|
||||||
#-renamesourcefileattribute SourceFile
|
#-renamesourcefileattribute SourceFile
|
||||||
|
|
||||||
|
-dontwarn
|
||||||
|
-ignorewarnings
|
||||||
|
|
||||||
|
-optimizationpasses 10
|
||||||
|
-dontusemixedcaseclassnames
|
||||||
|
|
||||||
|
-dontoptimize
|
||||||
|
-verbose
|
||||||
|
-overloadaggressively
|
||||||
|
-repackageclasses i
|
||||||
|
-allowaccessmodification
|
||||||
|
|
||||||
|
-adaptclassstrings
|
||||||
|
-adaptresourcefilenames
|
||||||
|
-adaptresourcefilecontents
|
||||||
|
|
||||||
|
# -optimizations !code/simplification/arithmetic,!code/simplification/cast,!field/*,!class/merging/*
|
||||||
|
-renamesourcefileattribute P
|
||||||
|
-keepattributes SourceFile,LineNumberTable
|
52
app/src/main/java/com/highcapable/yukihookapi/demo/App.kt
Normal file
52
app/src/main/java/com/highcapable/yukihookapi/demo/App.kt
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
/**
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022 HighCapable
|
||||||
|
*
|
||||||
|
* This file is part of YukiHookAPI.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
* This file is Created by fankes on 2022/2/7.
|
||||||
|
*/
|
||||||
|
@file:Suppress("unused")
|
||||||
|
|
||||||
|
package com.highcapable.yukihookapi.demo
|
||||||
|
|
||||||
|
import android.app.Application
|
||||||
|
import android.content.Context
|
||||||
|
import com.highcapable.yukihookapi.YukiHookAPI
|
||||||
|
import com.highcapable.yukihookapi.demo.hook.MainHooker
|
||||||
|
import com.highcapable.yukihookapi.demo.hook.SecondHooker
|
||||||
|
|
||||||
|
class App : Application() {
|
||||||
|
|
||||||
|
override fun attachBaseContext(base: Context?) {
|
||||||
|
////
|
||||||
|
// 装载你的 Hook 框架的代码
|
||||||
|
////
|
||||||
|
// 方式 1
|
||||||
|
YukiHookAPI.encase(base) {
|
||||||
|
// Your code here.
|
||||||
|
}
|
||||||
|
// 方式 2
|
||||||
|
YukiHookAPI.encase(base, MainHooker(), SecondHooker())
|
||||||
|
super.attachBaseContext(base)
|
||||||
|
}
|
||||||
|
}
|
@@ -29,12 +29,14 @@
|
|||||||
|
|
||||||
package com.highcapable.yukihookapi
|
package com.highcapable.yukihookapi
|
||||||
|
|
||||||
import android.content.pm.ApplicationInfo
|
import android.app.Application
|
||||||
|
import android.content.Context
|
||||||
import com.highcapable.yukihookapi.YukiHookAPI.configs
|
import com.highcapable.yukihookapi.YukiHookAPI.configs
|
||||||
import com.highcapable.yukihookapi.YukiHookAPI.encase
|
import com.highcapable.yukihookapi.YukiHookAPI.encase
|
||||||
import com.highcapable.yukihookapi.annotation.DoNotUseMethod
|
import com.highcapable.yukihookapi.annotation.DoNotUseMethod
|
||||||
import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker
|
import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker
|
||||||
import com.highcapable.yukihookapi.hook.param.CustomParam
|
import com.highcapable.yukihookapi.hook.factory.processName
|
||||||
|
import com.highcapable.yukihookapi.hook.param.EnvironmentParam
|
||||||
import com.highcapable.yukihookapi.hook.param.PackageParam
|
import com.highcapable.yukihookapi.hook.param.PackageParam
|
||||||
import com.highcapable.yukihookapi.hook.xposed.YukiHookModuleStatus
|
import com.highcapable.yukihookapi.hook.xposed.YukiHookModuleStatus
|
||||||
import de.robv.android.xposed.callbacks.XC_LoadPackage
|
import de.robv.android.xposed.callbacks.XC_LoadPackage
|
||||||
@@ -54,7 +56,7 @@ object YukiHookAPI {
|
|||||||
private var packageParamCallback: (PackageParam.() -> Unit)? = null
|
private var packageParamCallback: (PackageParam.() -> Unit)? = null
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 配置 YukiHook
|
* 配置 YukiHookAPI
|
||||||
*/
|
*/
|
||||||
object Configs {
|
object Configs {
|
||||||
|
|
||||||
@@ -102,7 +104,17 @@ object YukiHookAPI {
|
|||||||
* @param lpparam Xposed [XC_LoadPackage.LoadPackageParam]
|
* @param lpparam Xposed [XC_LoadPackage.LoadPackageParam]
|
||||||
*/
|
*/
|
||||||
@DoNotUseMethod
|
@DoNotUseMethod
|
||||||
fun onXposedLoaded(lpparam: XC_LoadPackage.LoadPackageParam) = packageParamCallback?.invoke(PackageParam(lpparam))
|
fun onXposedLoaded(lpparam: XC_LoadPackage.LoadPackageParam) =
|
||||||
|
packageParamCallback?.invoke(
|
||||||
|
PackageParam(
|
||||||
|
EnvironmentParam(
|
||||||
|
packageName = lpparam.packageName,
|
||||||
|
processName = lpparam.processName,
|
||||||
|
appClassLoader = lpparam.classLoader,
|
||||||
|
appInfo = lpparam.appInfo
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 作为模块装载调用入口方法 - Xposed API
|
* 作为模块装载调用入口方法 - Xposed API
|
||||||
@@ -126,16 +138,87 @@ object YukiHookAPI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 自定义 Hook 方法装载入口
|
* 作为 [Application] 装载调用入口方法
|
||||||
* @param classLoader [ClassLoader]
|
*
|
||||||
* @param packageName 包名
|
* 请在 [Application.attachBaseContext] 中写入如下代码:
|
||||||
* @param appInfo [ApplicationInfo]
|
*
|
||||||
|
* ....
|
||||||
|
*
|
||||||
|
* override fun attachBaseContext(base: Context?) {
|
||||||
|
*
|
||||||
|
* ....////
|
||||||
|
*
|
||||||
|
* ....// 装载你使用的 Hook 框架的代码
|
||||||
|
*
|
||||||
|
* ....// 你的 Hook 框架需要支持 Xposed API
|
||||||
|
*
|
||||||
|
* ....////
|
||||||
|
*
|
||||||
|
* ....// 装载 YukiHookAPI
|
||||||
|
*
|
||||||
|
* ....YukiHookAPI.encase(base) {
|
||||||
|
*
|
||||||
|
* ........// Your code here.
|
||||||
|
*
|
||||||
|
* ....}
|
||||||
|
*
|
||||||
|
* ....super.attachBaseContext(base)
|
||||||
|
*
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* ....
|
||||||
|
*
|
||||||
|
* 详情请参考 [YukiHookAPI Wiki](https://github.com/fankes/YukiHookAPI/wiki)
|
||||||
|
* @param baseContext attachBaseContext
|
||||||
* @param initiate Hook 方法体
|
* @param initiate Hook 方法体
|
||||||
*/
|
*/
|
||||||
fun encase(
|
fun encase(baseContext: Context?, initiate: PackageParam.() -> Unit) {
|
||||||
classLoader: ClassLoader,
|
if (baseContext != null) initiate.invoke(baseContext.packagePararm)
|
||||||
packageName: String,
|
}
|
||||||
appInfo: ApplicationInfo,
|
|
||||||
initiate: PackageParam.() -> Unit
|
/**
|
||||||
) = initiate.invoke(PackageParam(customParam = CustomParam(classLoader, appInfo, packageName)))
|
* 作为 [Application] 装载调用入口方法
|
||||||
|
*
|
||||||
|
* 请在 [Application.attachBaseContext] 中写入如下代码:
|
||||||
|
*
|
||||||
|
* ....
|
||||||
|
*
|
||||||
|
* override fun attachBaseContext(base: Context?) {
|
||||||
|
*
|
||||||
|
* ....////
|
||||||
|
*
|
||||||
|
* ....// 装载你使用的 Hook 框架的代码
|
||||||
|
*
|
||||||
|
* ....// 你的 Hook 框架需要支持 Xposed API
|
||||||
|
*
|
||||||
|
* ....////
|
||||||
|
*
|
||||||
|
* ....// 装载 YukiHookAPI
|
||||||
|
*
|
||||||
|
* ....YukiHookAPI.encase(base, MainHooker(), SecondHooker() ...)
|
||||||
|
*
|
||||||
|
* ....super.attachBaseContext(base)
|
||||||
|
*
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* ....
|
||||||
|
*
|
||||||
|
* 详情请参考 [YukiHookAPI Wiki](https://github.com/fankes/YukiHookAPI/wiki)
|
||||||
|
* @param baseContext attachBaseContext
|
||||||
|
* @param hooker Hook 子类数组 - 必填不能为空
|
||||||
|
* @throws IllegalStateException 如果 [hooker] 是空的
|
||||||
|
*/
|
||||||
|
fun encase(baseContext: Context?, vararg hooker: YukiBaseHooker) {
|
||||||
|
if (baseContext != null)
|
||||||
|
if (hooker.isNotEmpty())
|
||||||
|
hooker.forEach { it.assignInstance(packageParam = baseContext.packagePararm) }
|
||||||
|
else error("Hooker is empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过 baseContext 创建 Hook 入口类
|
||||||
|
* @return [PackageParam]
|
||||||
|
*/
|
||||||
|
private val Context.packagePararm
|
||||||
|
get() = PackageParam(EnvironmentParam(packageName, processName, classLoader, applicationInfo))
|
||||||
}
|
}
|
@@ -46,17 +46,18 @@ import java.lang.reflect.Constructor
|
|||||||
*/
|
*/
|
||||||
class ConstructorFinder(private val hookInstance: YukiHookCreater.MemberHookCreater, private val hookClass: Class<*>) {
|
class ConstructorFinder(private val hookInstance: YukiHookCreater.MemberHookCreater, private val hookClass: Class<*>) {
|
||||||
|
|
||||||
/** 失败尝试次数数组 */
|
/** [Constructor] 参数数组 */
|
||||||
private val remedyPlan = HashMap<Long, ConstructorFinder>()
|
|
||||||
|
|
||||||
/** 构造方法参数 */
|
|
||||||
private var params: Array<out Class<*>>? = null
|
private var params: Array<out Class<*>>? = null
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构造方法参数
|
* [Constructor] 参数
|
||||||
|
* - 无参 [Constructor] 不要使用此方法
|
||||||
|
*
|
||||||
|
* - 有参 [Constructor] 必须使用此方法设定参数
|
||||||
* @param param 参数数组
|
* @param param 参数数组
|
||||||
*/
|
*/
|
||||||
fun param(vararg param: Class<*>) {
|
fun param(vararg param: Class<*>) {
|
||||||
|
if (param.isEmpty()) error("param is empty, please delete param() method")
|
||||||
params = param
|
params = param
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -48,10 +48,16 @@ class FieldFinder(private val hookInstance: YukiHookCreater.MemberHookCreater, p
|
|||||||
/** 当前找到的 [Field] */
|
/** 当前找到的 [Field] */
|
||||||
private var fieldInstance: Field? = null
|
private var fieldInstance: Field? = null
|
||||||
|
|
||||||
/** 变量名 */
|
/**
|
||||||
|
* [Field] 名称
|
||||||
|
* - 必须设置
|
||||||
|
*/
|
||||||
var name = ""
|
var name = ""
|
||||||
|
|
||||||
/** 变量类型 */
|
/**
|
||||||
|
* [Field] 类型
|
||||||
|
* - 必须设置
|
||||||
|
*/
|
||||||
var type: Class<*>? = null
|
var type: Class<*>? = null
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -46,20 +46,32 @@ import java.lang.reflect.Method
|
|||||||
*/
|
*/
|
||||||
class MethodFinder(private val hookInstance: YukiHookCreater.MemberHookCreater, private val hookClass: Class<*>) {
|
class MethodFinder(private val hookInstance: YukiHookCreater.MemberHookCreater, private val hookClass: Class<*>) {
|
||||||
|
|
||||||
/** 方法参数 */
|
/** [Method] 参数数组 */
|
||||||
private var params: Array<out Class<*>>? = null
|
private var params: Array<out Class<*>>? = null
|
||||||
|
|
||||||
/** 方法名 */
|
/**
|
||||||
|
* [Method] 名称
|
||||||
|
*
|
||||||
|
* - 必须设置
|
||||||
|
*/
|
||||||
var name = ""
|
var name = ""
|
||||||
|
|
||||||
/** 方法返回值 */
|
/**
|
||||||
|
* [Method] 返回值
|
||||||
|
*
|
||||||
|
* 可不填写返回值 - 默认模糊查找并取第一个匹配的 [Method]
|
||||||
|
*/
|
||||||
var returnType: Class<*>? = null
|
var returnType: Class<*>? = null
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 方法参数
|
* [Method] 参数
|
||||||
|
* - 无参 [Method] 不要使用此方法
|
||||||
|
*
|
||||||
|
* - 有参 [Method] 必须使用此方法设定参数
|
||||||
* @param param 参数数组
|
* @param param 参数数组
|
||||||
*/
|
*/
|
||||||
fun param(vararg param: Class<*>) {
|
fun param(vararg param: Class<*>) {
|
||||||
|
if (param.isEmpty()) error("param is empty, please delete param() method")
|
||||||
params = param
|
params = param
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -33,10 +33,14 @@ import android.content.Context
|
|||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.os.Process
|
||||||
import com.highcapable.yukihookapi.YukiHookAPI
|
import com.highcapable.yukihookapi.YukiHookAPI
|
||||||
import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker
|
import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker
|
||||||
import com.highcapable.yukihookapi.hook.param.PackageParam
|
import com.highcapable.yukihookapi.hook.param.PackageParam
|
||||||
import com.highcapable.yukihookapi.hook.xposed.proxy.YukiHookXposedInitProxy
|
import com.highcapable.yukihookapi.hook.xposed.proxy.YukiHookXposedInitProxy
|
||||||
|
import java.io.BufferedReader
|
||||||
|
import java.io.File
|
||||||
|
import java.io.FileReader
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 在 [YukiHookXposedInitProxy] 中装载 [YukiHookAPI]
|
* 在 [YukiHookXposedInitProxy] 中装载 [YukiHookAPI]
|
||||||
@@ -51,6 +55,22 @@ fun YukiHookXposedInitProxy.encase(initiate: PackageParam.() -> Unit) = YukiHook
|
|||||||
*/
|
*/
|
||||||
fun YukiHookXposedInitProxy.encase(vararg hooker: YukiBaseHooker) = YukiHookAPI.encase(hooker = hooker)
|
fun YukiHookXposedInitProxy.encase(vararg hooker: YukiBaseHooker) = YukiHookAPI.encase(hooker = hooker)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前进程名称
|
||||||
|
* @return [String]
|
||||||
|
*/
|
||||||
|
val Context.processName
|
||||||
|
get() = try {
|
||||||
|
BufferedReader(FileReader(File("/proc/${Process.myPid()}/cmdline"))).let { buff ->
|
||||||
|
buff.readLine().trim { it <= ' ' }.let {
|
||||||
|
buff.close()
|
||||||
|
it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (_: Throwable) {
|
||||||
|
packageName ?: ""
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断模块是否在太极、无极中激活
|
* 判断模块是否在太极、无极中激活
|
||||||
* @return [Boolean] 是否激活
|
* @return [Boolean] 是否激活
|
||||||
|
@@ -23,20 +23,24 @@
|
|||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*
|
*
|
||||||
* This file is Created by fankes on 2022/2/2.
|
* This file is Created by fankes on 2022/2/7.
|
||||||
*/
|
*/
|
||||||
|
@file:Suppress("unused", "MemberVisibilityCanBePrivate", "EXPERIMENTAL_API_USAGE")
|
||||||
|
|
||||||
package com.highcapable.yukihookapi.hook.param
|
package com.highcapable.yukihookapi.hook.param
|
||||||
|
|
||||||
import android.content.pm.ApplicationInfo
|
import android.content.pm.ApplicationInfo
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 自定义 [PackageParam] 的装载入口置换类
|
* Hook 环境装载实现类
|
||||||
|
* @param packageName 包名
|
||||||
|
* @param processName 当前进程名
|
||||||
* @param appClassLoader APP [ClassLoader]
|
* @param appClassLoader APP [ClassLoader]
|
||||||
* @param appInfo APP [ApplicationInfo]
|
* @param appInfo APP [ApplicationInfo]
|
||||||
* @param packageName 包名
|
|
||||||
*/
|
*/
|
||||||
class CustomParam(
|
class EnvironmentParam(
|
||||||
|
var packageName: String,
|
||||||
|
var processName: String,
|
||||||
var appClassLoader: ClassLoader,
|
var appClassLoader: ClassLoader,
|
||||||
var appInfo: ApplicationInfo,
|
var appInfo: ApplicationInfo
|
||||||
var packageName: String
|
|
||||||
)
|
)
|
@@ -33,21 +33,12 @@ import android.content.pm.ApplicationInfo
|
|||||||
import com.highcapable.yukihookapi.annotation.DoNotUseMethod
|
import com.highcapable.yukihookapi.annotation.DoNotUseMethod
|
||||||
import com.highcapable.yukihookapi.hook.core.YukiHookCreater
|
import com.highcapable.yukihookapi.hook.core.YukiHookCreater
|
||||||
import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker
|
import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker
|
||||||
import de.robv.android.xposed.callbacks.XC_LoadPackage
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 装载 Hook 的目标 APP 入口对象实现类
|
* 装载 Hook 的目标 APP 入口对象实现类
|
||||||
*
|
* @param baseParam 对接环境装载类的实现 - 默认是空的
|
||||||
* 如果你想将 YukiHook 作为 Hook API 使用 - 你可自定义 [customParam]
|
|
||||||
*
|
|
||||||
* - 特别注意如果 [baseParam] 和 [customParam] 都为空将发生问题
|
|
||||||
* @param baseParam 对接 Xposed API 的 [XC_LoadPackage.LoadPackageParam] - 默认空
|
|
||||||
* @param customParam 自定义装载类 - 默认空
|
|
||||||
*/
|
*/
|
||||||
open class PackageParam(
|
open class PackageParam(private var baseParam: EnvironmentParam? = null) {
|
||||||
private var baseParam: XC_LoadPackage.LoadPackageParam? = null,
|
|
||||||
private var customParam: CustomParam? = null
|
|
||||||
) {
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取当前 APP 的 [ClassLoader]
|
* 获取当前 APP 的 [ClassLoader]
|
||||||
@@ -55,36 +46,33 @@ open class PackageParam(
|
|||||||
* @throws IllegalStateException 如果 [ClassLoader] 是空的
|
* @throws IllegalStateException 如果 [ClassLoader] 是空的
|
||||||
*/
|
*/
|
||||||
val appClassLoader
|
val appClassLoader
|
||||||
get() = baseParam?.classLoader ?: customParam?.appClassLoader ?: javaClass.classLoader
|
get() = baseParam?.appClassLoader ?: javaClass.classLoader ?: error("PackageParam got null ClassLoader")
|
||||||
?: error("PackageParam ClassLoader is null")
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取当前 APP 的 [ApplicationInfo]
|
* 获取当前 APP 的 [ApplicationInfo]
|
||||||
* @return [ApplicationInfo]
|
* @return [ApplicationInfo]
|
||||||
*/
|
*/
|
||||||
val appInfo get() = baseParam?.appInfo ?: customParam?.appInfo ?: ApplicationInfo()
|
val appInfo get() = baseParam?.appInfo ?: ApplicationInfo()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取当前 APP 的进程名称
|
* 获取当前 APP 的进程名称
|
||||||
*
|
*
|
||||||
* 默认的进程名称是 [packageName] 如果自定义了 [customParam] 将返回包名
|
* 默认的进程名称是 [packageName]
|
||||||
* @return [String]
|
* @return [String]
|
||||||
*/
|
*/
|
||||||
val processName get() = baseParam?.processName ?: customParam?.packageName ?: ""
|
val processName get() = baseParam?.processName ?: packageName
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取当前 APP 的包名
|
* 获取当前 APP 的包名
|
||||||
* @return [String]
|
* @return [String]
|
||||||
*/
|
*/
|
||||||
val packageName get() = baseParam?.packageName ?: customParam?.packageName ?: ""
|
val packageName get() = baseParam?.packageName ?: ""
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取当前 APP 是否为第一个 Application
|
* 获取当前 APP 是否为第一个 Application
|
||||||
*
|
|
||||||
* 若自定义了 [customParam] 将永远返回 true
|
|
||||||
* @return [Boolean]
|
* @return [Boolean]
|
||||||
*/
|
*/
|
||||||
val isFirstApplication get() = baseParam?.isFirstApplication ?: true
|
val isFirstApplication get() = packageName == processName
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 赋值并克隆另一个 [PackageParam]
|
* 赋值并克隆另一个 [PackageParam]
|
||||||
@@ -94,7 +82,6 @@ open class PackageParam(
|
|||||||
@DoNotUseMethod
|
@DoNotUseMethod
|
||||||
internal fun baseAssignInstance(another: PackageParam) {
|
internal fun baseAssignInstance(another: PackageParam) {
|
||||||
this.baseParam = another.baseParam
|
this.baseParam = another.baseParam
|
||||||
this.customParam = another.customParam
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user