Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xiaoxuan_i809
AndroidUtilCode
提交
f6367ba8
A
AndroidUtilCode
项目概览
xiaoxuan_i809
/
AndroidUtilCode
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
A
AndroidUtilCode
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
f6367ba8
编写于
5月 03, 2020
作者:
B
Blankj
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
see 05/03 log
上级
93315a67
变更
42
隐藏空白更改
内联
并排
Showing
42 changed file
with
728 addition
and
1126 deletion
+728
-1126
CHANGELOG.md
CHANGELOG.md
+5
-0
buildSrc/src/main/groovy/Config.groovy
buildSrc/src/main/groovy/Config.groovy
+10
-9
buildSrc/src/main/groovy/ConfigUtils.groovy
buildSrc/src/main/groovy/ConfigUtils.groovy
+1
-1
buildSrc/src/main/groovy/TaskDurationUtils.groovy
buildSrc/src/main/groovy/TaskDurationUtils.groovy
+1
-1
config.json
config.json
+3
-2
feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/helper/DialogHelper.kt
.../main/java/com/blankj/utilcode/pkg/helper/DialogHelper.kt
+1
-0
gradle/publish.gradle
gradle/publish.gradle
+1
-0
lib/base/src/main/java/com/blankj/base/rv/BaseItem.java
lib/base/src/main/java/com/blankj/base/rv/BaseItem.java
+3
-0
lib/base/src/main/java/com/blankj/base/rv/BaseItemAdapter.java
...ase/src/main/java/com/blankj/base/rv/BaseItemAdapter.java
+39
-3
lib/utilcode/README-CN.md
lib/utilcode/README-CN.md
+2
-2
lib/utilcode/README.md
lib/utilcode/README.md
+2
-2
lib/utilcode/src/main/java/com/blankj/utilcode/util/BarUtils.java
...code/src/main/java/com/blankj/utilcode/util/BarUtils.java
+10
-2
lib/utilcode/src/main/java/com/blankj/utilcode/util/KeyboardUtils.java
...src/main/java/com/blankj/utilcode/util/KeyboardUtils.java
+13
-4
lib/utilcode/src/main/java/com/blankj/utilcode/util/LanguageUtils.java
...src/main/java/com/blankj/utilcode/util/LanguageUtils.java
+43
-15
lib/utilcode/src/main/java/com/blankj/utilcode/util/PermissionUtils.java
...c/main/java/com/blankj/utilcode/util/PermissionUtils.java
+6
-12
plugin/api-gradle-plugin/CHANGELOG.md
plugin/api-gradle-plugin/CHANGELOG.md
+4
-1
plugin/api-gradle-plugin/build.gradle
plugin/api-gradle-plugin/build.gradle
+3
-21
plugin/api-gradle-plugin/src/main/java/com/blankj/api/ApiInject.groovy
...adle-plugin/src/main/java/com/blankj/api/ApiInject.groovy
+1
-1
plugin/api-gradle-plugin/src/main/java/com/blankj/api/ApiPlugin.groovy
...adle-plugin/src/main/java/com/blankj/api/ApiPlugin.groovy
+106
-13
plugin/api-gradle-plugin/src/main/java/com/blankj/api/ApiScan.groovy
...gradle-plugin/src/main/java/com/blankj/api/ApiScan.groovy
+0
-72
plugin/api-gradle-plugin/src/main/java/com/blankj/api/ApiTransform.groovy
...e-plugin/src/main/java/com/blankj/api/ApiTransform.groovy
+0
-163
plugin/api-gradle-plugin/src/main/java/com/blankj/api/Config.groovy
...-gradle-plugin/src/main/java/com/blankj/api/Config.groovy
+3
-1
plugin/api-gradle-plugin/src/main/java/com/blankj/api/util/JsonUtils.groovy
...plugin/src/main/java/com/blankj/api/util/JsonUtils.groovy
+0
-21
plugin/api-gradle-plugin/src/main/java/com/blankj/api/util/LogUtils.groovy
...-plugin/src/main/java/com/blankj/api/util/LogUtils.groovy
+0
-34
plugin/bus-gradle-plugin/CHANGELOG.md
plugin/bus-gradle-plugin/CHANGELOG.md
+3
-0
plugin/bus-gradle-plugin/build.gradle
plugin/bus-gradle-plugin/build.gradle
+3
-21
plugin/bus-gradle-plugin/src/main/java/com/blankj/bus/BusInject.groovy
...adle-plugin/src/main/java/com/blankj/bus/BusInject.groovy
+6
-6
plugin/bus-gradle-plugin/src/main/java/com/blankj/bus/BusPlugin.groovy
...adle-plugin/src/main/java/com/blankj/bus/BusPlugin.groovy
+125
-13
plugin/bus-gradle-plugin/src/main/java/com/blankj/bus/BusScan.groovy
...gradle-plugin/src/main/java/com/blankj/bus/BusScan.groovy
+0
-70
plugin/bus-gradle-plugin/src/main/java/com/blankj/bus/BusTransform.groovy
...e-plugin/src/main/java/com/blankj/bus/BusTransform.groovy
+0
-180
plugin/bus-gradle-plugin/src/main/java/com/blankj/bus/Config.groovy
...-gradle-plugin/src/main/java/com/blankj/bus/Config.groovy
+3
-1
plugin/bus-gradle-plugin/src/main/java/com/blankj/bus/util/ZipUtils.java
...le-plugin/src/main/java/com/blankj/bus/util/ZipUtils.java
+0
-453
plugin/lib/base-transform/.gitignore
plugin/lib/base-transform/.gitignore
+2
-0
plugin/lib/base-transform/CHANGELOG.md
plugin/lib/base-transform/CHANGELOG.md
+4
-0
plugin/lib/base-transform/README.md
plugin/lib/base-transform/README.md
+50
-0
plugin/lib/base-transform/build.gradle
plugin/lib/base-transform/build.gradle
+31
-0
plugin/lib/base-transform/src/main/java/com/blankj/base_transform/BaseTransformCallback.groovy
...va/com/blankj/base_transform/BaseTransformCallback.groovy
+15
-0
plugin/lib/base-transform/src/main/java/com/blankj/base_transform/BaseTransformConfig.groovy
...java/com/blankj/base_transform/BaseTransformConfig.groovy
+5
-0
plugin/lib/base-transform/src/main/java/com/blankj/base_transform/BaseTransformPlugin.groovy
...java/com/blankj/base_transform/BaseTransformPlugin.groovy
+162
-0
plugin/lib/base-transform/src/main/java/com/blankj/base_transform/util/JsonUtils.groovy
...main/java/com/blankj/base_transform/util/JsonUtils.groovy
+1
-1
plugin/lib/base-transform/src/main/java/com/blankj/base_transform/util/LogUtils.groovy
.../main/java/com/blankj/base_transform/util/LogUtils.groovy
+60
-0
plugin/lib/base-transform/src/main/java/com/blankj/base_transform/util/ZipUtils.java
...rc/main/java/com/blankj/base_transform/util/ZipUtils.java
+1
-1
未找到文件。
CHANGELOG.md
浏览文件 @
f6367ba8
*
`20/05/03`
[add] Publish bus plugin v2.5. Publish api plugin v1.3. Publish. Publish 1.28.4.
*
`20/04/30`
[add] BaseItem support partialUpdate.
*
`20/04/29`
[add] Publish plugin lib com.blankj:base-transform:1.0.
*
`20/04/28`
[fix] LanguageUtils#applyLanguage.
*
`20/04/27`
[fix] BarUtils#isNavBarVisible.
*
`20/04/26`
[fix] Utils#init fit tinker. Publish 1.28.3.
*
`20/04/25`
[fix] UriUtils#uri2File Unknown URI. Publish 1.28.2.
*
`20/04/24`
[add] SnackbarUtils support show on the top; UriUtils#uri2InputStream.
...
...
buildSrc/src/main/groovy/Config.groovy
浏览文件 @
f6367ba8
...
...
@@ -15,7 +15,7 @@ class Config {
static
minSdkVersion
=
14
static
targetSdkVersion
=
29
static
versionCode
=
1
_028_002
static
versionName
=
'1.28.
3
'
// E.g. 1.9.72 => 1,009,072
static
versionName
=
'1.28.
4
'
// E.g. 1.9.72 => 1,009,072
// lib version
static
gradlePluginVersion
=
'3.5.0'
...
...
@@ -25,8 +25,9 @@ class Config {
static
depConfig
=
[
/*Never delete this line*/
/*Generated by "config.json"*/
plugin_api_gradle_plugin
:
new
DepConfig
(
true
,
true
,
":plugin:api-gradle-plugin"
),
plugin_bus_gradle_plugin
:
new
DepConfig
(
true
,
true
,
":plugin:bus-gradle-plugin"
),
plugin_api_gradle_plugin
:
new
DepConfig
(
false
,
true
,
":plugin:api-gradle-plugin"
),
plugin_bus_gradle_plugin
:
new
DepConfig
(
false
,
true
,
":plugin:bus-gradle-plugin"
),
plugin_lib_base_transform
:
new
DepConfig
(
false
,
true
,
":plugin:lib:base-transform"
,
"com.blankj:base-transform:1.0"
),
feature_mock
:
new
DepConfig
(
false
,
true
,
":feature:mock"
),
feature_launcher_app
:
new
DepConfig
(
true
,
true
,
":feature:launcher:app"
),
feature_main_app
:
new
DepConfig
(
false
,
true
,
":feature:main:app"
),
...
...
@@ -52,12 +53,12 @@ class Config {
// 上传新版本插件更新 pluginPath 中的版本号,并设置 isApply = false
// 通过 mavenLocal 上传本地版本,设置 isApply = true 即可应用插件来调试,最后通过 bintrayUpload 来发布插件
plugin_api
:
new
DepConfig
(
isApply:
true
,
useLocal:
false
,
pluginPath:
"com.blankj:api-gradle-plugin:1.
2
"
,
pluginId:
"com.blankj.api"
),
//./gradlew plugin:plugin_api-gradle-plugin:mavenLocal // 上传到本地 mavenLocal
//./gradlew plugin:plugin_api-gradle-plugin:bintrayUpload // 上传到 jcenter
plugin_bus
:
new
DepConfig
(
isApply:
true
,
useLocal:
false
,
pluginPath:
"com.blankj:bus-gradle-plugin:2.
4
"
,
pluginId:
"com.blankj.bus"
),
//./gradlew plugin:plugin_bus-gradle-plugin:mavenLocal // 上传到本地 mavenLocal
//./gradlew plugin:plugin_bus-gradle-plugin:bintrayUpload // 上传到 jcenter
plugin_api
:
new
DepConfig
(
isApply:
true
,
useLocal:
false
,
pluginPath:
"com.blankj:api-gradle-plugin:1.
3
"
,
pluginId:
"com.blankj.api"
),
//./gradlew
clean
plugin:plugin_api-gradle-plugin:mavenLocal // 上传到本地 mavenLocal
//./gradlew
clean
plugin:plugin_api-gradle-plugin:bintrayUpload // 上传到 jcenter
plugin_bus
:
new
DepConfig
(
isApply:
true
,
useLocal:
false
,
pluginPath:
"com.blankj:bus-gradle-plugin:2.
5
"
,
pluginId:
"com.blankj.bus"
),
//./gradlew
clean
plugin:plugin_bus-gradle-plugin:mavenLocal // 上传到本地 mavenLocal
//./gradlew
clean
plugin:plugin_bus-gradle-plugin:bintrayUpload // 上传到 jcenter
support_appcompat_v7
:
new
DepConfig
(
"com.android.support:appcompat-v7:$supportVersion"
),
support_design
:
new
DepConfig
(
"com.android.support:design:$supportVersion"
),
...
...
buildSrc/src/main/groovy/ConfigUtils.groovy
浏览文件 @
f6367ba8
...
...
@@ -47,7 +47,7 @@ class ConfigUtils {
void
beforeEvaluate
(
Project
project
)
{
// 在 project 的 build.gradle 前 do sth.
if
(
project
.
subprojects
.
isEmpty
())
{
if
(
project
.
name
.
startsWith
(
"
plugin"
))
{
if
(
project
.
path
.
startsWith
(
":
plugin"
))
{
return
}
if
(
project
.
name
.
endsWith
(
"_app"
))
{
...
...
buildSrc/src/main/groovy/TaskDurationUtils.groovy
浏览文件 @
f6367ba8
...
...
@@ -32,7 +32,7 @@ class TaskDurationUtils {
@Override
void
afterExecute
(
Task
task
,
TaskState
state
)
{
def
exeDuration
=
System
.
currentTimeMillis
()
-
task
.
ext
.
startTime
if
(
exeDuration
>=
1
00
)
{
if
(
exeDuration
>=
5
00
)
{
taskInfoList
.
add
(
new
TaskInfo
(
task:
task
,
exeDuration:
exeDuration
))
}
}
...
...
config.json
浏览文件 @
f6367ba8
...
...
@@ -5,8 +5,9 @@
"pkgConfig"
:
[],
"proConfigDesc"
:
"proConfig 配置的是使用本地还是仓库,优先级低于 appConfig 和 pkgConfig"
,
"proConfig"
:
[
{
"isApply"
:
true
,
"useLocal"
:
true
,
"localPath"
:
":plugin:api-gradle-plugin"
},
{
"isApply"
:
true
,
"useLocal"
:
true
,
"localPath"
:
":plugin:bus-gradle-plugin"
},
{
"isApply"
:
false
,
"useLocal"
:
true
,
"localPath"
:
":plugin:api-gradle-plugin"
},
{
"isApply"
:
false
,
"useLocal"
:
true
,
"localPath"
:
":plugin:bus-gradle-plugin"
},
{
"isApply"
:
false
,
"useLocal"
:
true
,
"localPath"
:
":plugin:lib:base-transform"
,
"remotePath"
:
"com.blankj:base-transform:1.0"
},
{
"isApply"
:
true
,
"useLocal"
:
true
,
"localPath"
:
":feature:mock"
},
{
"isApply"
:
true
,
"useLocal"
:
true
,
"localPath"
:
":feature:launcher:app"
},
{
"isApply"
:
true
,
"useLocal"
:
true
,
"localPath"
:
":feature:main:app"
},
...
...
feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/helper/DialogHelper.kt
浏览文件 @
f6367ba8
...
...
@@ -86,6 +86,7 @@ object DialogHelper {
dialog
.
dialog
.
setOnShowListener
(
DialogInterface
.
OnShowListener
{
KeyboardUtils
.
fixAndroidBug5497
(
dialog
.
dialog
.
window
!!
)
KeyboardUtils
.
showSoftInput
()
})
}
...
...
gradle/publish.gradle
浏览文件 @
f6367ba8
...
...
@@ -54,6 +54,7 @@ def configMaven(Project project, PublishExtension ext) {
}
project
.
tasks
.
create
(
"mavenLocal"
,
Upload
)
{
group
(
"publishing"
)
configuration
=
project
.
configurations
.
archives
repositories
.
mavenDeployer
{
...
...
lib/base/src/main/java/com/blankj/base/rv/BaseItem.java
浏览文件 @
f6367ba8
...
...
@@ -38,6 +38,9 @@ public abstract class BaseItem<T extends BaseItem> {
public
abstract
void
bind
(
@NonNull
final
ItemViewHolder
holder
,
final
int
position
);
public
void
partialUpdate
(
List
<
Object
>
payloads
)
{
}
void
bindViewHolder
(
@NonNull
final
ItemViewHolder
holder
,
final
int
position
)
{
if
(
mOnItemClickListener
!=
null
)
{
holder
.
itemView
.
setOnClickListener
(
new
View
.
OnClickListener
()
{
...
...
lib/base/src/main/java/com/blankj/base/rv/BaseItemAdapter.java
浏览文件 @
f6367ba8
...
...
@@ -53,6 +53,15 @@ public class BaseItemAdapter<Item extends BaseItem> extends RecyclerView.Adapter
mItems
.
get
(
position
).
bindViewHolder
(
holder
,
position
);
}
@Override
public
void
onBindViewHolder
(
@NonNull
ItemViewHolder
holder
,
int
position
,
@NonNull
List
<
Object
>
payloads
)
{
if
(
payloads
.
isEmpty
())
{
super
.
onBindViewHolder
(
holder
,
position
,
payloads
);
return
;
}
mItems
.
get
(
position
).
partialUpdate
(
payloads
);
}
@Override
public
int
getItemCount
()
{
return
mItems
.
size
();
...
...
@@ -151,14 +160,41 @@ public class BaseItemAdapter<Item extends BaseItem> extends RecyclerView.Adapter
///////////////////////////////////////////////////////////////////////////
public
void
updateItem
(
@NonNull
final
Item
item
)
{
updateItems
(
item
,
1
,
null
);
}
public
void
updateItem
(
@IntRange
(
from
=
0
)
final
int
index
)
{
updateItems
(
index
,
1
,
null
);
}
public
void
updateItem
(
@NonNull
final
Item
item
,
Object
payload
)
{
updateItems
(
item
,
1
,
payload
);
}
public
void
updateItem
(
@IntRange
(
from
=
0
)
final
int
index
,
Object
payload
)
{
updateItems
(
index
,
1
,
payload
);
}
public
void
updateItems
(
@NonNull
final
Item
item
,
int
itemCount
)
{
int
itemIndex
=
mItems
.
indexOf
(
item
);
if
(
itemIndex
!=
-
1
)
{
notifyItemChanged
(
itemIndex
);
updateItems
(
itemIndex
,
itemCount
);
}
}
public
void
updateItem
(
@IntRange
(
from
=
0
)
final
int
index
)
{
notifyItemChanged
(
index
);
public
void
updateItems
(
@IntRange
(
from
=
0
)
final
int
index
,
int
itemCount
)
{
updateItems
(
index
,
itemCount
,
null
);
}
public
void
updateItems
(
@NonNull
final
Item
item
,
int
itemCount
,
Object
payload
)
{
int
itemIndex
=
mItems
.
indexOf
(
item
);
if
(
itemIndex
!=
-
1
)
{
updateItems
(
itemIndex
,
itemCount
,
payload
);
}
}
public
void
updateItems
(
@IntRange
(
from
=
0
)
final
int
index
,
int
itemCount
,
Object
payload
)
{
notifyItemRangeChanged
(
index
,
itemCount
,
payload
);
}
public
void
addItem
(
@NonNull
final
Item
item
)
{
...
...
lib/utilcode/README-CN.md
浏览文件 @
f6367ba8
...
...
@@ -2,10 +2,10 @@
Gradle:
```
groovy
implementation
'com.blankj:utilcode:1.28.
3
'
implementation
'com.blankj:utilcode:1.28.
4
'
// if u use AndroidX, use the following
implementation
'com.blankj:utilcodex:1.28.
3
'
implementation
'com.blankj:utilcodex:1.28.
4
'
```
...
...
lib/utilcode/README.md
浏览文件 @
f6367ba8
...
...
@@ -2,10 +2,10 @@
Gradle:
```
groovy
implementation
'com.blankj:utilcode:1.28.
3
'
implementation
'com.blankj:utilcode:1.28.
4
'
// if u use AndroidX, use the following
implementation
'com.blankj:utilcodex:1.28.
3
'
implementation
'com.blankj:utilcodex:1.28.
4
'
```
...
...
lib/utilcode/src/main/java/com/blankj/utilcode/util/BarUtils.java
浏览文件 @
f6367ba8
...
...
@@ -515,7 +515,7 @@ public final class BarUtils {
final
View
child
=
decorView
.
getChildAt
(
i
);
final
int
id
=
child
.
getId
();
if
(
id
!=
View
.
NO_ID
)
{
String
resourceEntryName
=
Resources
.
getSystem
().
getResourceEntryName
(
id
);
String
resourceEntryName
=
getResNameById
(
id
);
if
(
"navigationBarBackground"
.
equals
(
resourceEntryName
))
{
child
.
setVisibility
(
isVisible
?
View
.
VISIBLE
:
View
.
INVISIBLE
);
}
...
...
@@ -556,7 +556,7 @@ public final class BarUtils {
final
View
child
=
decorView
.
getChildAt
(
i
);
final
int
id
=
child
.
getId
();
if
(
id
!=
View
.
NO_ID
)
{
String
resourceEntryName
=
Resources
.
getSystem
().
getResourceEntryName
(
id
);
String
resourceEntryName
=
getResNameById
(
id
);
if
(
"navigationBarBackground"
.
equals
(
resourceEntryName
)
&&
child
.
getVisibility
()
==
View
.
VISIBLE
)
{
isVisible
=
true
;
...
...
@@ -571,6 +571,14 @@ public final class BarUtils {
return
isVisible
;
}
private
static
String
getResNameById
(
int
id
)
{
try
{
return
Utils
.
getApp
().
getResources
().
getResourceEntryName
(
id
);
}
catch
(
Exception
ignore
)
{
return
""
;
}
}
/**
* Set the navigation bar's color.
*
...
...
lib/utilcode/src/main/java/com/blankj/utilcode/util/KeyboardUtils.java
浏览文件 @
f6367ba8
...
...
@@ -97,14 +97,23 @@ public final class KeyboardUtils {
* @param activity The activity.
*/
public
static
void
hideSoftInput
(
@NonNull
final
Activity
activity
)
{
View
view
=
activity
.
getCurrentFocus
();
hideSoftInput
(
activity
.
getWindow
());
}
/**
* Hide the soft input.
*
* @param window The window.
*/
public
static
void
hideSoftInput
(
@NonNull
final
Window
window
)
{
View
view
=
window
.
getCurrentFocus
();
if
(
view
==
null
)
{
View
decorView
=
activity
.
getWindow
()
.
getDecorView
();
View
decorView
=
window
.
getDecorView
();
View
focusView
=
decorView
.
findViewWithTag
(
"keyboardTagView"
);
if
(
focusView
==
null
)
{
view
=
new
EditText
(
activity
);
view
=
new
EditText
(
window
.
getContext
()
);
view
.
setTag
(
"keyboardTagView"
);
((
ViewGroup
)
decorView
).
addView
(
view
,
1
,
1
);
((
ViewGroup
)
decorView
).
addView
(
view
,
0
,
0
);
}
else
{
view
=
focusView
;
}
...
...
lib/utilcode/src/main/java/com/blankj/utilcode/util/LanguageUtils.java
浏览文件 @
f6367ba8
...
...
@@ -69,7 +69,7 @@ public class LanguageUtils {
* @param locale The language of locale.
*/
public
static
void
applyLanguage
(
@NonNull
final
Locale
locale
)
{
if
(
isAppliedLanguage
())
return
;
if
(
isAppliedLanguage
(
locale
))
return
;
applyLanguage
(
locale
,
""
,
false
,
false
);
}
...
...
@@ -115,9 +115,7 @@ public class LanguageUtils {
if
(
isFollowSystem
)
{
UtilsBridge
.
getSpUtils4Utils
().
put
(
KEY_LOCALE
,
VALUE_FOLLOW_SYSTEM
);
}
else
{
String
localLanguage
=
locale
.
getLanguage
();
String
localCountry
=
locale
.
getCountry
();
UtilsBridge
.
getSpUtils4Utils
().
put
(
KEY_LOCALE
,
localLanguage
+
"$"
+
localCountry
);
UtilsBridge
.
getSpUtils4Utils
().
put
(
KEY_LOCALE
,
locale2String
(
locale
));
}
updateLanguage
(
Utils
.
getApp
(),
locale
);
...
...
@@ -149,6 +147,25 @@ public class LanguageUtils {
return
!
TextUtils
.
isEmpty
(
UtilsBridge
.
getSpUtils4Utils
().
getString
(
KEY_LOCALE
));
}
/**
* Return whether applied the language by {@link LanguageUtils}.
*
* @param locale The locale.
* @return {@code true}: yes<br>{@code false}: no
*/
public
static
boolean
isAppliedLanguage
(
Locale
locale
)
{
final
String
spLocale
=
UtilsBridge
.
getSpUtils4Utils
().
getString
(
KEY_LOCALE
);
if
(
TextUtils
.
isEmpty
(
spLocale
))
{
return
false
;
}
if
(
VALUE_FOLLOW_SYSTEM
.
equals
(
spLocale
))
{
return
false
;
}
Locale
settingLocale
=
string2Locale
(
spLocale
);
if
(
settingLocale
==
null
)
return
false
;
return
isSameLocale
(
settingLocale
,
locale
);
}
/**
* Return the locale.
*
...
...
@@ -159,7 +176,7 @@ public class LanguageUtils {
}
static
void
applyLanguage
(
@NonNull
final
Activity
activity
)
{
final
String
spLocale
=
UtilsBridge
.
getSpUtils4Utils
().
getString
(
KEY_LOCALE
);
String
spLocale
=
UtilsBridge
.
getSpUtils4Utils
().
getString
(
KEY_LOCALE
);
if
(
TextUtils
.
isEmpty
(
spLocale
))
{
return
;
}
...
...
@@ -171,17 +188,28 @@ public class LanguageUtils {
return
;
}
String
[]
language_country
=
spLocale
.
split
(
"\\$"
);
if
(
language_country
.
length
!=
2
)
{
Log
.
e
(
"LanguageUtils"
,
"The string of "
+
spLocale
+
" is not in the correct format."
);
return
;
}
Locale
settingLocale
=
new
Locale
(
language_country
[
0
],
language_country
[
1
]);
Locale
settingLocale
=
string2Locale
(
spLocale
);
if
(
settingLocale
==
null
)
return
;
updateLanguage
(
Utils
.
getApp
(),
settingLocale
);
updateLanguage
(
activity
,
settingLocale
);
}
private
static
String
locale2String
(
Locale
locale
)
{
String
localLanguage
=
locale
.
getLanguage
();
String
localCountry
=
locale
.
getCountry
();
return
localLanguage
+
"$"
+
localCountry
;
}
private
static
Locale
string2Locale
(
String
str
)
{
String
[]
language_country
=
str
.
split
(
"\\$"
);
if
(
language_country
.
length
!=
2
)
{
Log
.
e
(
"LanguageUtils"
,
"The string of "
+
str
+
" is not in the correct format."
);
return
null
;
}
return
new
Locale
(
language_country
[
0
],
language_country
[
1
]);
}
private
static
void
updateLanguage
(
final
Context
context
,
Locale
locale
)
{
Resources
resources
=
context
.
getResources
();
Configuration
config
=
resources
.
getConfiguration
();
...
...
@@ -207,8 +235,8 @@ public class LanguageUtils {
resources
.
updateConfiguration
(
config
,
dm
);
}
private
static
boolean
isSameLocale
(
Locale
l
ocale
,
Locale
contextLocale
)
{
return
UtilsBridge
.
equals
(
contextLocale
.
getLanguage
(),
locale
.
getLanguage
())
&&
UtilsBridge
.
equals
(
contextLocale
.
getCountry
(),
locale
.
getCountry
());
private
static
boolean
isSameLocale
(
Locale
l
0
,
Locale
l1
)
{
return
UtilsBridge
.
equals
(
l1
.
getLanguage
(),
l0
.
getLanguage
())
&&
UtilsBridge
.
equals
(
l1
.
getCountry
(),
l0
.
getCountry
());
}
}
lib/utilcode/src/main/java/com/blankj/utilcode/util/PermissionUtils.java
浏览文件 @
f6367ba8
...
...
@@ -447,7 +447,6 @@ public final class PermissionUtils {
@Override
public
void
onDestroy
(
final
UtilsTransActivity
activity
)
{
//如果是unity调用,app从后台切回,当前activity会被强制关闭,此时正常流程不会触发,所以在这里检测
if
(
currentRequestCode
!=
-
1
)
{
checkRequestCallback
(
currentRequestCode
);
currentRequestCode
=
-
1
;
...
...
@@ -471,17 +470,12 @@ public final class PermissionUtils {
sSimpleCallback4WriteSettings
=
null
;
}
else
if
(
requestCode
==
TYPE_DRAW_OVERLAYS
)
{
if
(
sSimpleCallback4DrawOverlays
==
null
)
return
;
UtilsBridge
.
runOnUiThreadDelayed
(
new
Runnable
()
{
@Override
public
void
run
()
{
if
(
isGrantedDrawOverlays
())
{
sSimpleCallback4DrawOverlays
.
onGranted
();
}
else
{
sSimpleCallback4DrawOverlays
.
onDenied
();
}
sSimpleCallback4DrawOverlays
=
null
;
}
},
100
);
if
(
isGrantedDrawOverlays
())
{
sSimpleCallback4DrawOverlays
.
onGranted
();
}
else
{
sSimpleCallback4DrawOverlays
.
onDenied
();
}
sSimpleCallback4DrawOverlays
=
null
;
}
}
}
...
...
plugin/api-gradle-plugin/CHANGELOG.md
浏览文件 @
f6367ba8
# Change Log
## v1.2(2020/11/30)
## v1.3(2020/04/29)
重构使用 base-transform
## v1.2(2019/11/30)
去除 gradle 版本依赖的问题
## v1.1(2019/10/30)
...
...
plugin/api-gradle-plugin/build.gradle
浏览文件 @
f6367ba8
plugins
{
id
'com.gradle.plugin-publish'
version
"0.10.0"
}
apply
{
plugin
"groovy"
plugin
"java-gradle-plugin"
...
...
@@ -19,6 +15,7 @@ gradlePlugin {
dependencies
{
compileOnly
Config
.
depConfig
.
plugin_gradle
.
dep
implementation
Config
.
depConfig
.
commons_io
.
dep
implementation
Config
.
depConfig
.
plugin_lib_base_transform
.
dep
implementation
gradleApi
()
implementation
localGroovy
()
...
...
@@ -34,20 +31,6 @@ sourceSets {
}
}
pluginBundle
{
website
=
'https://github.com/Blankj/AndroidUtilCode'
vcsUrl
=
'https://github.com/Blankj/AndroidUtilCode.git'
description
=
'Plugin for ApiUtils.'
tags
=
[
'gradle'
,
'plugin'
,
'api'
,
'ApiUtils'
,
'asm'
]
plugins
{
apiPlugin
{
// id is captured from java-gradle-plugin configuration
displayName
=
'Plugin for ApiUtils.'
}
}
}
apply
from:
"${rootDir.path}/gradle/publish.gradle"
publish
{
name
=
"ApiPlugin"
...
...
@@ -57,6 +40,5 @@ publish {
website
=
"https://github.com/Blankj/AndroidUtilCode"
}
//./gradlew plugin:plugin_api-gradle-plugin:mavenLocal // 上传到本地 mavenLocal
//./gradlew plugin:plugin_api-gradle-plugin:bintrayUpload // 上传到 jcenter
//./gradlew plugin:plugin_api-gradle-plugin:publishPlugins // 上传到 gradle 插件库中
//./gradlew clean plugin:plugin_api-gradle-plugin:mavenLocal // 上传到本地 mavenLocal
//./gradlew clean plugin:plugin_api-gradle-plugin:bintrayUpload // 上传到 jcenter
plugin/api-gradle-plugin/src/main/java/com/blankj/api/ApiInject.groovy
浏览文件 @
f6367ba8
package
com.blankj.api
import
com.blankj.
api
.util.ZipUtils
import
com.blankj.
base_transform
.util.ZipUtils
import
org.apache.commons.io.FileUtils
import
org.objectweb.asm.ClassReader
import
org.objectweb.asm.ClassVisitor
...
...
plugin/api-gradle-plugin/src/main/java/com/blankj/api/ApiPlugin.groovy
浏览文件 @
f6367ba8
package
com.blankj.api
import
com.android.build.
gradle.AppExtension
import
com.
android.build.gradle.App
Plugin
import
com.blankj.
api.util.Log
Utils
import
com.android.build.
api.transform.JarInput
import
com.
blankj.base_transform.BaseTransform
Plugin
import
com.blankj.
base_transform.util.Json
Utils
import
org.apache.commons.io.FileUtils
import
org.gradle.api.Plugin
import
org.gradle.api.Project
import
org.objectweb.asm.ClassReader
import
org.objectweb.asm.ClassVisitor
import
org.objectweb.asm.ClassWriter
class
ApiPlugin
implements
Plugin
<
Project
>
{
import
java.util.regex.Pattern
class
ApiPlugin
extends
BaseTransformPlugin
<
ApiExtension
>
{
String
apiUtilsClass
File
jsonFile
File
apiUtilsTransformFile
Map
<
String
,
ApiInfo
>
apiImplMap
=
[:]
List
<
String
>
apiClasses
=
[]
@Override
String
getPluginName
()
{
return
Config
.
EXT_NAME
}
@Override
void
onScanStarted
()
{
apiUtilsClass
=
ext
.
apiUtilsClass
if
(
apiUtilsClass
.
trim
().
equals
(
""
))
{
throw
new
Exception
(
"ApiExtension's apiUtilsClass is empty."
)
}
jsonFile
=
new
File
(
mProject
.
projectDir
.
getAbsolutePath
(),
"__api__.json"
)
FileUtils
.
write
(
jsonFile
,
"{}"
)
}
@Override
void
apply
(
Project
project
)
{
if
(
project
.
plugins
.
hasPlugin
(
AppPlugin
))
{
LogUtils
.
init
(
project
)
LogUtils
.
l
(
'project('
+
project
.
toString
()
+
') apply api gradle plugin!'
)
project
.
extensions
.
create
(
Config
.
EXT_NAME
,
ApiExtension
)
def
android
=
project
.
extensions
.
getByType
(
AppExtension
)
android
.
registerTransform
(
new
ApiTransform
(
project
))
boolean
isIgnoreScan
(
JarInput
input
)
{
def
jarName
=
input
.
name
if
(
jarName
.
contains
(
"utilcode"
))
{
return
false
}
if
(
ext
.
onlyScanLibRegex
!=
null
&&
ext
.
onlyScanLibRegex
.
trim
().
length
()
>
0
)
{
return
!
Pattern
.
matches
(
ext
.
onlyScanLibRegex
,
jarName
)
}
if
(
ext
.
jumpScanLibRegex
!=
null
&&
ext
.
jumpScanLibRegex
.
trim
().
length
()
>
0
)
{
if
(
Pattern
.
matches
(
ext
.
jumpScanLibRegex
,
jarName
))
{
return
true
}
}
for
(
exclude
in
Config
.
EXCLUDE_LIBS_START_WITH
)
{
if
(
jarName
.
startsWith
(
exclude
))
{
return
true
}
}
return
false
}
@Override
void
scanClassFile
(
File
classFile
,
String
className
,
File
originScannedJarOrDir
)
{
if
(
apiUtilsClass
==
className
)
{
apiUtilsTransformFile
=
originScannedJarOrDir
log
(
"<ApiUtils transform file>: $originScannedJarOrDir"
)
}
ClassReader
cr
=
new
ClassReader
(
classFile
.
bytes
);
ClassWriter
cw
=
new
ClassWriter
(
cr
,
0
);
ClassVisitor
cv
=
new
ApiClassVisitor
(
cw
,
apiImplMap
,
apiClasses
,
apiUtilsClass
);
try
{
cr
.
accept
(
cv
,
ClassReader
.
SKIP_FRAMES
);
}
catch
(
Exception
ignore
)
{
ignore
.
printStackTrace
()
}
}
@Override
void
onScanFinished
()
{
if
(
apiUtilsTransformFile
!=
null
)
{
if
(
apiClasses
.
isEmpty
())
{
log
(
"no api."
)
}
else
{
Map
implApis
=
[:]
List
<
String
>
noImplApis
=
[]
apiImplMap
.
each
{
key
,
value
->
implApis
.
put
(
key
,
value
.
toString
())
}
apiClasses
.
each
{
if
(!
apiImplMap
.
containsKey
(
it
))
{
noImplApis
.
add
(
it
)
}
}
Map
apiDetails
=
[:]
apiDetails
.
put
(
"ApiUtilsClass"
,
apiUtilsClass
)
apiDetails
.
put
(
"implApis"
,
implApis
)
apiDetails
.
put
(
"noImplApis"
,
noImplApis
)
String
apiJson
=
JsonUtils
.
getFormatJson
(
apiDetails
)
log
(
jsonFile
.
toString
()
+
": "
+
apiJson
)
FileUtils
.
write
(
jsonFile
,
apiJson
)
if
(
noImplApis
.
size
()
>
0
)
{
if
(
ext
.
abortOnError
)
{
throw
new
Exception
(
"u should impl these apis: "
+
noImplApis
+
"\n u can check it in file: "
+
jsonFile
.
toString
())
}
}
ApiInject
.
start
(
apiImplMap
,
apiUtilsTransformFile
,
apiUtilsClass
)
}
}
else
{
throw
new
Exception
(
"No ApiUtils of ${apiUtilsClass} in $mProject."
)
}
}
}
\ No newline at end of file
plugin/api-gradle-plugin/src/main/java/com/blankj/api/ApiScan.groovy
已删除
100755 → 0
浏览文件 @
93315a67
package
com.blankj.api
import
com.blankj.api.util.LogUtils
import
com.blankj.api.util.ZipUtils
import
groovy.io.FileType
import
org.apache.commons.io.FileUtils
import
org.objectweb.asm.ClassReader
import
org.objectweb.asm.ClassVisitor
import
org.objectweb.asm.ClassWriter
class
ApiScan
{
Map
<
String
,
ApiInfo
>
apiImplMap
=
[:]
List
<
String
>
apiClasses
=
[]
File
apiUtilsTransformFile
String
apiUtilsClass
ApiScan
(
String
apiUtilsClass
)
{
this
.
apiUtilsClass
=
apiUtilsClass
}
void
scanJar
(
File
jar
)
{
File
tmp
=
new
File
(
jar
.
getParent
(),
"temp_"
+
jar
.
getName
())
List
<
File
>
unzipFile
=
ZipUtils
.
unzipFile
(
jar
,
tmp
)
if
(
unzipFile
!=
null
&&
unzipFile
.
size
()
>
0
)
{
scanDir
(
tmp
,
jar
)
FileUtils
.
forceDelete
(
tmp
)
}
}
void
scanDir
(
File
root
)
{
scanDir
(
root
,
root
)
}
void
scanDir
(
File
root
,
File
source
)
{
if
(!
root
.
isDirectory
())
return
String
rootPath
=
root
.
getAbsolutePath
()
if
(!
rootPath
.
endsWith
(
Config
.
FILE_SEP
))
{
rootPath
+=
Config
.
FILE_SEP
}
root
.
eachFileRecurse
(
FileType
.
FILES
)
{
File
file
->
def
fileName
=
file
.
name
if
(!
fileName
.
endsWith
(
'.class'
)
||
fileName
.
startsWith
(
'R$'
)
||
fileName
==
'R.class'
||
fileName
==
'BuildConfig.class'
)
{
return
}
def
filePath
=
file
.
absolutePath
def
packagePath
=
filePath
.
replace
(
rootPath
,
''
)
def
className
=
packagePath
.
replace
(
Config
.
FILE_SEP
,
"."
)
// delete .class
className
=
className
.
substring
(
0
,
className
.
length
()
-
6
)
if
(
apiUtilsClass
==
className
)
{
apiUtilsTransformFile
=
source
LogUtils
.
l
(
"<ApiUtils transform file>: $source"
)
}
ClassReader
cr
=
new
ClassReader
(
file
.
bytes
);
ClassWriter
cw
=
new
ClassWriter
(
cr
,
0
);
ClassVisitor
cv
=
new
ApiClassVisitor
(
cw
,
apiImplMap
,
apiClasses
,
apiUtilsClass
);
try
{
cr
.
accept
(
cv
,
ClassReader
.
SKIP_FRAMES
);
}
catch
(
Exception
ignore
)
{
ignore
.
printStackTrace
()
}
}
}
}
plugin/api-gradle-plugin/src/main/java/com/blankj/api/ApiTransform.groovy
已删除
100755 → 0
浏览文件 @
93315a67
package
com.blankj.api
import
com.android.build.api.transform.*
import
com.android.build.gradle.internal.pipeline.TransformManager
import
com.blankj.api.util.JsonUtils
import
com.blankj.api.util.LogUtils
import
org.apache.commons.io.FileUtils
import
org.gradle.api.Project
import
java.util.regex.Pattern
class
ApiTransform
extends
Transform
{
Project
mProject
;
ApiTransform
(
Project
project
)
{
mProject
=
project
}
@Override
String
getName
()
{
return
"apiTransform"
}
@Override
Set
<
QualifiedContent
.
ContentType
>
getInputTypes
()
{
return
TransformManager
.
CONTENT_CLASS
}
@Override
Set
<?
super
QualifiedContent
.
Scope
>
getScopes
()
{
return
TransformManager
.
SCOPE_FULL_PROJECT
}
@Override
boolean
isIncremental
()
{
return
false
}
@Override
void
transform
(
TransformInvocation
transformInvocation
)
throws
TransformException
,
InterruptedException
,
IOException
{
super
.
transform
(
transformInvocation
)
LogUtils
.
l
(
getName
()
+
" started"
)
long
stTime
=
System
.
currentTimeMillis
()
def
ext
=
mProject
[
Config
.
EXT_NAME
]
as
ApiExtension
LogUtils
.
l
(
"apiExtension: $ext"
)
if
(
ext
.
apiUtilsClass
.
trim
().
equals
(
""
))
{
throw
new
Exception
(
"ApiExtension's apiUtilsClass is empty."
)
}
File
jsonFile
=
new
File
(
mProject
.
projectDir
.
getAbsolutePath
(),
"__api__.json"
)
FileUtils
.
write
(
jsonFile
,
"{}"
)
def
inputs
=
transformInvocation
.
getInputs
()
def
referencedInputs
=
transformInvocation
.
getReferencedInputs
()
def
outputProvider
=
transformInvocation
.
getOutputProvider
()
def
isIncremental
=
transformInvocation
.
isIncremental
()
outputProvider
.
deleteAll
()
ApiScan
apiScan
=
new
ApiScan
(
ext
.
apiUtilsClass
)
inputs
.
each
{
TransformInput
input
->
input
.
directoryInputs
.
each
{
DirectoryInput
dirInput
->
// 遍历文件夹
File
dir
=
dirInput
.
file
def
dest
=
outputProvider
.
getContentLocation
(
dirInput
.
name
,
dirInput
.
contentTypes
,
dirInput
.
scopes
,
Format
.
DIRECTORY
)
FileUtils
.
copyDirectory
(
dir
,
dest
)
LogUtils
.
l
(
"scan dir: ${dirInput.file} -> $dest"
)
apiScan
.
scanDir
(
dest
)
}
input
.
jarInputs
.
each
{
JarInput
jarInput
->
// 遍历 jar 文件
File
jar
=
jarInput
.
file
def
jarName
=
jarInput
.
name
def
dest
=
outputProvider
.
getContentLocation
(
jarName
,
jarInput
.
contentTypes
,
jarInput
.
scopes
,
Format
.
JAR
)
FileUtils
.
copyFile
(
jar
,
dest
)
if
(
jumpScan
(
jarName
,
ext
))
{
LogUtils
.
l
(
"jump jar: $jarName -> $dest"
)
return
}
LogUtils
.
l
(
"scan jar: $jarName -> $dest"
)
apiScan
.
scanJar
(
dest
)
}
}
if
(
apiScan
.
apiUtilsTransformFile
!=
null
)
{
if
(
apiScan
.
apiClasses
.
isEmpty
())
{
LogUtils
.
l
(
"no api."
)
}
else
{
Map
implApis
=
[:]
List
<
String
>
noImplApis
=
[]
apiScan
.
apiImplMap
.
each
{
key
,
value
->
implApis
.
put
(
key
,
value
.
toString
())
}
apiScan
.
apiClasses
.
each
{
if
(!
apiScan
.
apiImplMap
.
containsKey
(
it
))
{
noImplApis
.
add
(
it
)
}
}
Map
apiDetails
=
[:]
apiDetails
.
put
(
"ApiUtilsClass"
,
ext
.
apiUtilsClass
)
apiDetails
.
put
(
"implApis"
,
implApis
)
apiDetails
.
put
(
"noImplApis"
,
noImplApis
)
String
apiJson
=
JsonUtils
.
getFormatJson
(
apiDetails
)
LogUtils
.
l
(
jsonFile
.
toString
()
+
": "
+
apiJson
)
FileUtils
.
write
(
jsonFile
,
apiJson
)
if
(
noImplApis
.
size
()
>
0
)
{
if
(
ext
.
abortOnError
)
{
throw
new
Exception
(
"u should impl these apis: "
+
noImplApis
+
"\n u can check it in file: "
+
jsonFile
.
toString
())
}
}
ApiInject
.
start
(
apiScan
.
apiImplMap
,
apiScan
.
apiUtilsTransformFile
,
ext
.
apiUtilsClass
)
}
}
else
{
throw
new
Exception
(
"No ApiUtils of ${ext.apiUtilsClass} in $mProject."
)
}
LogUtils
.
l
(
getName
()
+
" finished: "
+
(
System
.
currentTimeMillis
()
-
stTime
)
+
"ms"
)
}
private
static
jumpScan
(
String
jarName
,
ApiExtension
ext
)
{
if
(
jarName
.
contains
(
"utilcode"
))
{
return
false
}
if
(
ext
.
onlyScanLibRegex
!=
null
&&
ext
.
onlyScanLibRegex
.
trim
().
length
()
>
0
)
{
return
!
Pattern
.
matches
(
ext
.
onlyScanLibRegex
,
jarName
)
}
if
(
ext
.
jumpScanLibRegex
!=
null
&&
ext
.
jumpScanLibRegex
.
trim
().
length
()
>
0
)
{
if
(
Pattern
.
matches
(
ext
.
jumpScanLibRegex
,
jarName
))
{
return
true
}
}
for
(
exclude
in
Config
.
EXCLUDE_LIBS_START_WITH
)
{
if
(
jarName
.
startsWith
(
exclude
))
{
return
true
}
}
return
false
}
}
\ No newline at end of file
plugin/api-gradle-plugin/src/main/java/com/blankj/api/Config.groovy
浏览文件 @
f6367ba8
package
com.blankj.api
import
com.blankj.base_transform.BaseTransformConfig
class
Config
{
public
static
final
String
EXT_NAME
=
'api'
...
...
@@ -15,5 +17,5 @@ class Config {
'com.github.bumptech.glide'
]
public
static
final
String
FILE_SEP
=
System
.
getProperty
(
"file.separator"
)
public
static
final
String
FILE_SEP
=
BaseTransformConfig
.
FILE_SEP
}
plugin/api-gradle-plugin/src/main/java/com/blankj/api/util/JsonUtils.groovy
已删除
100755 → 0
浏览文件 @
93315a67
package
com.blankj.api.util
import
com.google.gson.Gson
import
com.google.gson.GsonBuilder
/**
* <pre>
* author: Blankj
* blog : http://blankj.com
* time : 2018/10/08
* desc :
* </pre>
*/
final
class
JsonUtils
{
static
final
Gson
GSON
=
new
GsonBuilder
().
setPrettyPrinting
().
create
()
static
String
getFormatJson
(
Object
object
)
{
return
GSON
.
toJson
(
object
)
}
}
plugin/api-gradle-plugin/src/main/java/com/blankj/api/util/LogUtils.groovy
已删除
100755 → 0
浏览文件 @
93315a67
package
com.blankj.api.util
import
org.gradle.api.Project
import
org.gradle.api.logging.Logger
final
class
LogUtils
{
private
static
Logger
sLogger
private
static
String
PREFIX
=
"PLUGIN-API >>> "
static
void
init
(
Project
project
)
{
sLogger
=
project
.
getLogger
()
}
static
void
l
(
Object
content
)
{
sLogger
.
lifecycle
(
PREFIX
+
content
)
}
static
void
d
(
Object
content
)
{
sLogger
.
debug
(
PREFIX
+
content
)
}
static
void
i
(
Object
content
)
{
sLogger
.
info
(
PREFIX
+
content
)
}
static
void
w
(
Object
content
)
{
sLogger
.
warn
(
PREFIX
+
content
)
}
static
void
e
(
Object
content
)
{
sLogger
.
error
(
PREFIX
+
content
)
}
}
\ No newline at end of file
plugin/bus-gradle-plugin/CHANGELOG.md
浏览文件 @
f6367ba8
# Change Log
## v2.5(2020/04/29)
重构使用 base-transform
## v2.4
去除 gradle 版本依赖的问题
...
...
plugin/bus-gradle-plugin/build.gradle
浏览文件 @
f6367ba8
plugins
{
id
'com.gradle.plugin-publish'
version
"0.10.0"
}
apply
{
plugin
"groovy"
plugin
"java-gradle-plugin"
...
...
@@ -19,6 +15,7 @@ gradlePlugin {
dependencies
{
compileOnly
Config
.
depConfig
.
plugin_gradle
.
dep
implementation
Config
.
depConfig
.
commons_io
.
dep
implementation
Config
.
depConfig
.
plugin_lib_base_transform
.
dep
implementation
gradleApi
()
implementation
localGroovy
()
...
...
@@ -34,20 +31,6 @@ sourceSets {
}
}
pluginBundle
{
website
=
'https://github.com/Blankj/AndroidUtilCode'
vcsUrl
=
'https://github.com/Blankj/AndroidUtilCode.git'
description
=
'Plugin for BusUtils used as EventBus.'
tags
=
[
'gradle'
,
'plugin'
,
'bus'
,
'eventbus'
,
'BusUtils'
,
'asm'
]
plugins
{
busPlugin
{
// id is captured from java-gradle-plugin configuration
displayName
=
'Plugin for BusUtils used as EventBus.'
}
}
}
apply
from:
"${rootDir.path}/gradle/publish.gradle"
publish
{
name
=
"BusPlugin"
...
...
@@ -57,6 +40,5 @@ publish {
website
=
"https://github.com/Blankj/AndroidUtilCode"
}
//./gradlew plugin:lib_bus-gradle-plugin:mavenLocal // 上传到本地 mavenLocal
//./gradlew plugin:lib_bus-gradle-plugin:bintrayUpload // 上传到 jcenter
//./gradlew plugin:lib_bus-gradle-plugin:publishPlugins // 上传到 gradle 插件库中
\ No newline at end of file
//./gradlew clean plugin:plugin_bus-gradle-plugin:mavenLocal // 上传到本地 mavenLocal
//./gradlew clean plugin:plugin_bus-gradle-plugin:bintrayUpload // 上传到 jcenter
\ No newline at end of file
plugin/bus-gradle-plugin/src/main/java/com/blankj/bus/BusInject.groovy
浏览文件 @
f6367ba8
package
com.blankj.bus
import
com.blankj.b
us
.util.ZipUtils
import
com.blankj.b
ase_transform
.util.ZipUtils
import
org.apache.commons.io.FileUtils
import
org.objectweb.asm.ClassReader
import
org.objectweb.asm.ClassVisitor
...
...
@@ -26,20 +26,20 @@ class BusInject {
ZipUtils
.
zipFiles
(
Arrays
.
asList
(
decompressedJar
.
listFiles
()),
busUtilsTransformFile
)
FileUtils
.
forceDelete
(
decompressedJar
)
}
else
{
File
api
UtilsFile
=
new
File
(
File
bus
UtilsFile
=
new
File
(
busUtilsTransformFile
.
getAbsolutePath
()
+
Config
.
FILE_SEP
+
busUtilsClass
.
replace
(
'.'
,
Config
.
FILE_SEP
)
+
'.class'
)
inject2BusUtils
(
api
UtilsFile
,
busMap
,
busUtilsClass
)
inject2BusUtils
(
bus
UtilsFile
,
busMap
,
busUtilsClass
)
}
}
private
static
void
inject2BusUtils
(
File
api
UtilsFile
,
Map
<
String
,
BusInfo
>
busMap
,
String
busUtilsClass
)
{
ClassReader
cr
=
new
ClassReader
(
api
UtilsFile
.
bytes
);
private
static
void
inject2BusUtils
(
File
bus
UtilsFile
,
Map
<
String
,
BusInfo
>
busMap
,
String
busUtilsClass
)
{
ClassReader
cr
=
new
ClassReader
(
bus
UtilsFile
.
bytes
);
ClassWriter
cw
=
new
ClassWriter
(
cr
,
0
);
ClassVisitor
cv
=
new
BusUtilsClassVisitor
(
cw
,
busMap
,
busUtilsClass
);
cr
.
accept
(
cv
,
ClassReader
.
SKIP_FRAMES
);
FileUtils
.
writeByteArrayToFile
(
api
UtilsFile
,
cw
.
toByteArray
())
FileUtils
.
writeByteArrayToFile
(
bus
UtilsFile
,
cw
.
toByteArray
())
}
}
\ No newline at end of file
plugin/bus-gradle-plugin/src/main/java/com/blankj/bus/BusPlugin.groovy
浏览文件 @
f6367ba8
package
com.blankj.bus
import
com.android.build.gradle.AppExtension
import
com.android.build.gradle.AppPlugin
import
com.blankj.bus.util.LogUtils
import
org.gradle.api.Plugin
import
org.gradle.api.Project
import
com.android.build.api.transform.JarInput
import
com.blankj.base_transform.BaseTransformPlugin
import
com.blankj.base_transform.util.JsonUtils
import
org.apache.commons.io.FileUtils
import
org.objectweb.asm.ClassReader
import
org.objectweb.asm.ClassVisitor
import
org.objectweb.asm.ClassWriter
class
BusPlugin
implements
Plugin
<
Project
>
{
import
java.util.regex.Pattern
class
BusPlugin
extends
BaseTransformPlugin
<
BusExtension
>
{
String
busUtilsClass
File
jsonFile
Map
<
String
,
List
<
BusInfo
>>
busMap
=
[:]
File
busUtilsTransformFile
@Override
String
getPluginName
()
{
return
Config
.
EXT_NAME
}
@Override
void
apply
(
Project
project
)
{
if
(
project
.
plugins
.
hasPlugin
(
AppPlugin
))
{
LogUtils
.
init
(
project
)
LogUtils
.
l
(
'project('
+
project
.
toString
()
+
') apply bus gradle plugin!'
)
project
.
extensions
.
create
(
Config
.
EXT_NAME
,
BusExtension
)
def
android
=
project
.
extensions
.
getByType
(
AppExtension
)
android
.
registerTransform
(
new
BusTransform
(
project
))
void
onScanStarted
()
{
busUtilsClass
=
ext
.
busUtilsClass
if
(
busUtilsClass
.
trim
().
equals
(
""
))
{
throw
new
Exception
(
"BusExtension's busUtilsClass is empty."
)
}
jsonFile
=
new
File
(
mProject
.
projectDir
.
getAbsolutePath
(),
"__bus__.json"
)
FileUtils
.
write
(
jsonFile
,
"{}"
)
}
@Override
boolean
isIgnoreScan
(
JarInput
input
)
{
def
jarName
=
input
.
name
if
(
jarName
.
contains
(
"utilcode"
))
{
return
false
}
if
(
ext
.
onlyScanLibRegex
!=
null
&&
ext
.
onlyScanLibRegex
.
trim
().
length
()
>
0
)
{
return
!
Pattern
.
matches
(
ext
.
onlyScanLibRegex
,
jarName
)
}
if
(
ext
.
jumpScanLibRegex
!=
null
&&
ext
.
jumpScanLibRegex
.
trim
().
length
()
>
0
)
{
if
(
Pattern
.
matches
(
ext
.
jumpScanLibRegex
,
jarName
))
{
return
true
}
}
for
(
exclude
in
Config
.
EXCLUDE_LIBS_START_WITH
)
{
if
(
jarName
.
startsWith
(
exclude
))
{
return
true
}
}
return
false
}
@Override
void
scanClassFile
(
File
classFile
,
String
className
,
File
originScannedJarOrDir
)
{
if
(
busUtilsClass
==
className
)
{
busUtilsTransformFile
=
originScannedJarOrDir
log
(
"<BusUtils transform file>: $originScannedJarOrDir"
)
}
ClassReader
cr
=
new
ClassReader
(
classFile
.
bytes
);
ClassWriter
cw
=
new
ClassWriter
(
cr
,
0
);
ClassVisitor
cv
=
new
BusClassVisitor
(
cw
,
busMap
,
busUtilsClass
);
try
{
cr
.
accept
(
cv
,
ClassReader
.
SKIP_FRAMES
);
}
catch
(
Exception
ignore
)
{
ignore
.
printStackTrace
()
}
}
@Override
void
onScanFinished
()
{
if
(
busUtilsTransformFile
!=
null
)
{
if
(
busMap
.
isEmpty
())
{
log
(
"no bus."
)
}
else
{
busMap
.
each
{
String
tag
,
List
<
BusInfo
>
infoList
->
infoList
.
sort
(
new
Comparator
<
BusInfo
>()
{
@Override
int
compare
(
BusInfo
t0
,
BusInfo
t1
)
{
return
t1
.
priority
-
t0
.
priority
}
})
}
Map
<
String
,
List
<
String
>>
rightBus
=
[:]
Map
<
String
,
List
<
String
>>
wrongBus
=
[:]
busMap
.
each
{
String
tag
,
List
<
BusInfo
>
infoList
->
List
<
String
>
rightInfoString
=
[]
List
<
String
>
wrongInfoString
=
[]
infoList
.
each
{
BusInfo
info
->
if
(
info
.
isParamSizeNoMoreThanOne
)
{
rightInfoString
.
add
(
info
.
toString
())
}
else
{
wrongInfoString
.
add
(
info
.
toString
())
}
}
if
(!
rightInfoString
.
isEmpty
())
{
rightBus
.
put
(
tag
,
rightInfoString
)
}
if
(!
wrongInfoString
.
isEmpty
())
{
wrongBus
.
put
(
tag
,
wrongInfoString
)
}
}
Map
busDetails
=
[:]
busDetails
.
put
(
"BusUtilsClass"
,
ext
.
busUtilsClass
)
busDetails
.
put
(
"rightBus"
,
rightBus
)
busDetails
.
put
(
"wrongBus"
,
wrongBus
)
String
busJson
=
JsonUtils
.
getFormatJson
(
busDetails
)
log
(
jsonFile
.
toString
()
+
": "
+
busJson
)
FileUtils
.
write
(
jsonFile
,
busJson
)
if
(
wrongBus
.
size
()
>
0
)
{
if
(
ext
.
abortOnError
)
{
throw
new
Exception
(
"These buses is not right: "
+
wrongBus
+
"\n u can check it in file: "
+
jsonFile
.
toString
())
}
}
BusInject
.
start
(
busMap
,
busUtilsTransformFile
,
ext
.
busUtilsClass
)
}
}
else
{
throw
new
Exception
(
"No BusUtils of ${ext.busUtilsClass} in $mProject."
)
}
}
}
\ No newline at end of file
plugin/bus-gradle-plugin/src/main/java/com/blankj/bus/BusScan.groovy
已删除
100755 → 0
浏览文件 @
93315a67
package
com.blankj.bus
import
com.blankj.bus.util.LogUtils
import
com.blankj.bus.util.ZipUtils
import
groovy.io.FileType
import
org.apache.commons.io.FileUtils
import
org.objectweb.asm.ClassReader
import
org.objectweb.asm.ClassVisitor
import
org.objectweb.asm.ClassWriter
class
BusScan
{
Map
<
String
,
List
<
BusInfo
>>
busMap
=
[:]
File
busUtilsTransformFile
String
busUtilsClass
BusScan
(
String
busUtilsClass
)
{
this
.
busUtilsClass
=
busUtilsClass
}
void
scanJar
(
File
jar
)
{
File
tmp
=
new
File
(
jar
.
getParent
(),
"temp_"
+
jar
.
getName
())
List
<
File
>
unzipFile
=
ZipUtils
.
unzipFile
(
jar
,
tmp
)
if
(
unzipFile
!=
null
&&
unzipFile
.
size
()
>
0
)
{
scanDir
(
tmp
,
jar
)
FileUtils
.
forceDelete
(
tmp
)
}
}
void
scanDir
(
File
root
)
{
scanDir
(
root
,
root
)
}
void
scanDir
(
File
root
,
File
source
)
{
if
(!
root
.
isDirectory
())
return
String
rootPath
=
root
.
getAbsolutePath
()
if
(!
rootPath
.
endsWith
(
Config
.
FILE_SEP
))
{
rootPath
+=
Config
.
FILE_SEP
}
root
.
eachFileRecurse
(
FileType
.
FILES
)
{
File
file
->
def
fileName
=
file
.
name
if
(!
fileName
.
endsWith
(
'.class'
)
||
fileName
.
startsWith
(
'R$'
)
||
fileName
==
'R.class'
||
fileName
==
'BuildConfig.class'
)
{
return
}
def
filePath
=
file
.
absolutePath
def
packagePath
=
filePath
.
replace
(
rootPath
,
''
)
def
className
=
packagePath
.
replace
(
Config
.
FILE_SEP
,
"."
)
// delete .class
className
=
className
.
substring
(
0
,
className
.
length
()
-
6
)
if
(
busUtilsClass
==
className
)
{
busUtilsTransformFile
=
source
LogUtils
.
l
(
"<BusUtils transform file>: $source"
)
}
ClassReader
cr
=
new
ClassReader
(
file
.
bytes
);
ClassWriter
cw
=
new
ClassWriter
(
cr
,
0
);
ClassVisitor
cv
=
new
BusClassVisitor
(
cw
,
busMap
,
busUtilsClass
);
try
{
cr
.
accept
(
cv
,
ClassReader
.
SKIP_FRAMES
);
}
catch
(
Exception
ignore
)
{
ignore
.
printStackTrace
()
}
}
}
}
plugin/bus-gradle-plugin/src/main/java/com/blankj/bus/BusTransform.groovy
已删除
100755 → 0
浏览文件 @
93315a67
package
com.blankj.bus
import
com.android.build.api.transform.*
import
com.android.build.gradle.internal.pipeline.TransformManager
import
com.blankj.bus.util.JsonUtils
import
com.blankj.bus.util.LogUtils
import
org.apache.commons.io.FileUtils
import
org.gradle.api.Project
import
java.util.regex.Pattern
class
BusTransform
extends
Transform
{
Project
mProject
;
BusTransform
(
Project
project
)
{
mProject
=
project
}
@Override
String
getName
()
{
return
"busTransform"
}
@Override
Set
<
QualifiedContent
.
ContentType
>
getInputTypes
()
{
return
TransformManager
.
CONTENT_CLASS
}
@Override
Set
<?
super
QualifiedContent
.
Scope
>
getScopes
()
{
return
TransformManager
.
SCOPE_FULL_PROJECT
}
@Override
boolean
isIncremental
()
{
return
false
}
@Override
void
transform
(
TransformInvocation
transformInvocation
)
throws
TransformException
,
InterruptedException
,
IOException
{
super
.
transform
(
transformInvocation
)
LogUtils
.
l
(
getName
()
+
" started"
)
long
stTime
=
System
.
currentTimeMillis
()
def
ext
=
mProject
[
Config
.
EXT_NAME
]
as
BusExtension
LogUtils
.
l
(
"busExtension: $ext"
)
if
(
ext
.
busUtilsClass
.
trim
().
equals
(
""
))
{
throw
new
Exception
(
"BusExtension's busUtilsClass is empty."
)
}
File
jsonFile
=
new
File
(
mProject
.
projectDir
.
getAbsolutePath
(),
"__bus__.json"
)
FileUtils
.
write
(
jsonFile
,
"{}"
)
def
inputs
=
transformInvocation
.
getInputs
()
def
referencedInputs
=
transformInvocation
.
getReferencedInputs
()
def
outputProvider
=
transformInvocation
.
getOutputProvider
()
def
isIncremental
=
transformInvocation
.
isIncremental
()
outputProvider
.
deleteAll
()
BusScan
busScan
=
new
BusScan
(
ext
.
busUtilsClass
)
inputs
.
each
{
TransformInput
input
->
input
.
directoryInputs
.
each
{
DirectoryInput
dirInput
->
// 遍历文件夹
File
dir
=
dirInput
.
file
def
dest
=
outputProvider
.
getContentLocation
(
dirInput
.
name
,
dirInput
.
contentTypes
,
dirInput
.
scopes
,
Format
.
DIRECTORY
)
FileUtils
.
copyDirectory
(
dir
,
dest
)
LogUtils
.
l
(
"scan dir: ${dirInput.file} -> $dest"
)
busScan
.
scanDir
(
dest
)
}
input
.
jarInputs
.
each
{
JarInput
jarInput
->
// 遍历 jar 文件
File
jar
=
jarInput
.
file
def
jarName
=
jarInput
.
name
def
dest
=
outputProvider
.
getContentLocation
(
jarName
,
jarInput
.
contentTypes
,
jarInput
.
scopes
,
Format
.
JAR
)
FileUtils
.
copyFile
(
jar
,
dest
)
if
(
jumpScan
(
jarName
,
ext
))
{
LogUtils
.
l
(
"jump jar: $jarName -> $dest"
)
return
}
LogUtils
.
l
(
"scan jar: $jarName -> $dest"
)
busScan
.
scanJar
(
dest
)
}
}
if
(
busScan
.
busUtilsTransformFile
!=
null
)
{
if
(
busScan
.
busMap
.
isEmpty
())
{
LogUtils
.
l
(
"no bus."
)
}
else
{
busScan
.
busMap
.
each
{
String
tag
,
List
<
BusInfo
>
infoList
->
infoList
.
sort
(
new
Comparator
<
BusInfo
>()
{
@Override
int
compare
(
BusInfo
t0
,
BusInfo
t1
)
{
return
t1
.
priority
-
t0
.
priority
}
})
}
Map
<
String
,
List
<
String
>>
rightBus
=
[:]
Map
<
String
,
List
<
String
>>
wrongBus
=
[:]
busScan
.
busMap
.
each
{
String
tag
,
List
<
BusInfo
>
infoList
->
List
<
String
>
rightInfoString
=
[]
List
<
String
>
wrongInfoString
=
[]
infoList
.
each
{
BusInfo
info
->
if
(
info
.
isParamSizeNoMoreThanOne
)
{
rightInfoString
.
add
(
info
.
toString
())
}
else
{
wrongInfoString
.
add
(
info
.
toString
())
}
}
if
(!
rightInfoString
.
isEmpty
())
{
rightBus
.
put
(
tag
,
rightInfoString
)
}
if
(!
wrongInfoString
.
isEmpty
())
{
wrongBus
.
put
(
tag
,
wrongInfoString
)
}
}
Map
busDetails
=
[:]
busDetails
.
put
(
"BusUtilsClass"
,
ext
.
busUtilsClass
)
busDetails
.
put
(
"rightBus"
,
rightBus
)
busDetails
.
put
(
"wrongBus"
,
wrongBus
)
String
busJson
=
JsonUtils
.
getFormatJson
(
busDetails
)
LogUtils
.
l
(
jsonFile
.
toString
()
+
": "
+
busJson
)
FileUtils
.
write
(
jsonFile
,
busJson
)
if
(
wrongBus
.
size
()
>
0
)
{
if
(
ext
.
abortOnError
)
{
throw
new
Exception
(
"These buses is not right: "
+
wrongBus
+
"\n u can check it in file: "
+
jsonFile
.
toString
())
}
}
BusInject
.
start
(
busScan
.
busMap
,
busScan
.
busUtilsTransformFile
,
ext
.
busUtilsClass
)
}
}
else
{
throw
new
Exception
(
"No BusUtils of ${ext.busUtilsClass} in $mProject."
)
}
LogUtils
.
l
(
getName
()
+
" finished: "
+
(
System
.
currentTimeMillis
()
-
stTime
)
+
"ms"
)
}
private
static
jumpScan
(
String
jarName
,
BusExtension
ext
)
{
if
(
jarName
.
contains
(
"utilcode"
))
{
return
false
}
if
(
ext
.
onlyScanLibRegex
!=
null
&&
ext
.
onlyScanLibRegex
.
trim
().
length
()
>
0
)
{
return
!
Pattern
.
matches
(
ext
.
onlyScanLibRegex
,
jarName
)
}
if
(
ext
.
jumpScanLibRegex
!=
null
&&
ext
.
jumpScanLibRegex
.
trim
().
length
()
>
0
)
{
if
(
Pattern
.
matches
(
ext
.
jumpScanLibRegex
,
jarName
))
{
return
true
}
}
for
(
exclude
in
Config
.
EXCLUDE_LIBS_START_WITH
)
{
if
(
jarName
.
startsWith
(
exclude
))
{
return
true
}
}
return
false
}
}
\ No newline at end of file
plugin/bus-gradle-plugin/src/main/java/com/blankj/bus/Config.groovy
浏览文件 @
f6367ba8
package
com.blankj.bus
import
com.blankj.base_transform.BaseTransformConfig
class
Config
{
public
static
final
String
EXT_NAME
=
'bus'
...
...
@@ -15,5 +17,5 @@ class Config {
'com.github.bumptech.glide'
]
public
static
final
String
FILE_SEP
=
System
.
getProperty
(
"file.separator"
)
public
static
final
String
FILE_SEP
=
BaseTransformConfig
.
FILE_SEP
}
plugin/bus-gradle-plugin/src/main/java/com/blankj/bus/util/ZipUtils.java
已删除
100755 → 0
浏览文件 @
93315a67
package
com.blankj.bus.util
;
import
java.io.BufferedInputStream
;
import
java.io.BufferedOutputStream
;
import
java.io.File
;
import
java.io.FileInputStream
;
import
java.io.FileOutputStream
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.OutputStream
;
import
java.util.ArrayList
;
import
java.util.Collection
;
import
java.util.Enumeration
;
import
java.util.List
;
import
java.util.zip.ZipEntry
;
import
java.util.zip.ZipFile
;
import
java.util.zip.ZipOutputStream
;
/**
* <pre>
* author: Blankj
* blog : http://blankj.com
* time : 2016/08/27
* desc : utils about zip or jar
* </pre>
*/
public
final
class
ZipUtils
{
private
static
final
int
BUFFER_LEN
=
8192
;
private
ZipUtils
()
{
throw
new
UnsupportedOperationException
(
"u can't instantiate me..."
);
}
/**
* Zip the files.
*
* @param srcFiles The source of files.
* @param zipFilePath The path of ZIP file.
* @return {@code true}: success<br>{@code false}: fail
* @throws IOException if an I/O error has occurred
*/
public
static
boolean
zipFiles
(
final
Collection
<
String
>
srcFiles
,
final
String
zipFilePath
)
throws
IOException
{
return
zipFiles
(
srcFiles
,
zipFilePath
,
null
);
}
/**
* Zip the files.
*
* @param srcFilePaths The paths of source files.
* @param zipFilePath The path of ZIP file.
* @param comment The comment.
* @return {@code true}: success<br>{@code false}: fail
* @throws IOException if an I/O error has occurred
*/
public
static
boolean
zipFiles
(
final
Collection
<
String
>
srcFilePaths
,
final
String
zipFilePath
,
final
String
comment
)
throws
IOException
{
if
(
srcFilePaths
==
null
||
zipFilePath
==
null
)
return
false
;
ZipOutputStream
zos
=
null
;
try
{
zos
=
new
ZipOutputStream
(
new
FileOutputStream
(
zipFilePath
));
for
(
String
srcFile
:
srcFilePaths
)
{
if
(!
zipFile
(
getFileByPath
(
srcFile
),
""
,
zos
,
comment
))
return
false
;
}
return
true
;
}
finally
{
if
(
zos
!=
null
)
{
zos
.
finish
();
zos
.
close
();
}
}
}
/**
* Zip the files.
*
* @param srcFiles The source of files.
* @param zipFile The ZIP file.
* @return {@code true}: success<br>{@code false}: fail
* @throws IOException if an I/O error has occurred
*/
public
static
boolean
zipFiles
(
final
Collection
<
File
>
srcFiles
,
final
File
zipFile
)
throws
IOException
{
return
zipFiles
(
srcFiles
,
zipFile
,
null
);
}
/**
* Zip the files.
*
* @param srcFiles The source of files.
* @param zipFile The ZIP file.
* @param comment The comment.
* @return {@code true}: success<br>{@code false}: fail
* @throws IOException if an I/O error has occurred
*/
public
static
boolean
zipFiles
(
final
Collection
<
File
>
srcFiles
,
final
File
zipFile
,
final
String
comment
)
throws
IOException
{
if
(
srcFiles
==
null
||
zipFile
==
null
)
return
false
;
ZipOutputStream
zos
=
null
;
try
{
zos
=
new
ZipOutputStream
(
new
FileOutputStream
(
zipFile
));
for
(
File
srcFile
:
srcFiles
)
{
if
(!
zipFile
(
srcFile
,
""
,
zos
,
comment
))
return
false
;
}
return
true
;
}
finally
{
if
(
zos
!=
null
)
{
zos
.
finish
();
zos
.
close
();
}
}
}
/**
* Zip the file.
*
* @param srcFilePath The path of source file.
* @param zipFilePath The path of ZIP file.
* @return {@code true}: success<br>{@code false}: fail
* @throws IOException if an I/O error has occurred
*/
public
static
boolean
zipFile
(
final
String
srcFilePath
,
final
String
zipFilePath
)
throws
IOException
{
return
zipFile
(
getFileByPath
(
srcFilePath
),
getFileByPath
(
zipFilePath
),
null
);
}
/**
* Zip the file.
*
* @param srcFilePath The path of source file.
* @param zipFilePath The path of ZIP file.
* @param comment The comment.
* @return {@code true}: success<br>{@code false}: fail
* @throws IOException if an I/O error has occurred
*/
public
static
boolean
zipFile
(
final
String
srcFilePath
,
final
String
zipFilePath
,
final
String
comment
)
throws
IOException
{
return
zipFile
(
getFileByPath
(
srcFilePath
),
getFileByPath
(
zipFilePath
),
comment
);
}
/**
* Zip the file.
*
* @param srcFile The source of file.
* @param zipFile The ZIP file.
* @return {@code true}: success<br>{@code false}: fail
* @throws IOException if an I/O error has occurred
*/
public
static
boolean
zipFile
(
final
File
srcFile
,
final
File
zipFile
)
throws
IOException
{
return
zipFile
(
srcFile
,
zipFile
,
null
);
}
/**
* Zip the file.
*
* @param srcFile The source of file.
* @param zipFile The ZIP file.
* @param comment The comment.
* @return {@code true}: success<br>{@code false}: fail
* @throws IOException if an I/O error has occurred
*/
public
static
boolean
zipFile
(
final
File
srcFile
,
final
File
zipFile
,
final
String
comment
)
throws
IOException
{
if
(
srcFile
==
null
||
zipFile
==
null
)
return
false
;
ZipOutputStream
zos
=
null
;
try
{
zos
=
new
ZipOutputStream
(
new
FileOutputStream
(
zipFile
));
return
zipFile
(
srcFile
,
""
,
zos
,
comment
);
}
finally
{
if
(
zos
!=
null
)
{
zos
.
close
();
}
}
}
private
static
boolean
zipFile
(
final
File
srcFile
,
String
rootPath
,
final
ZipOutputStream
zos
,
final
String
comment
)
throws
IOException
{
rootPath
=
rootPath
+
(
isSpace
(
rootPath
)
?
""
:
File
.
separator
)
+
srcFile
.
getName
();
if
(
srcFile
.
isDirectory
())
{
File
[]
fileList
=
srcFile
.
listFiles
();
if
(
fileList
==
null
||
fileList
.
length
<=
0
)
{
ZipEntry
entry
=
new
ZipEntry
(
rootPath
+
'/'
);
entry
.
setComment
(
comment
);
zos
.
putNextEntry
(
entry
);
zos
.
closeEntry
();
}
else
{
for
(
File
file
:
fileList
)
{
if
(!
zipFile
(
file
,
rootPath
,
zos
,
comment
))
return
false
;
}
}
}
else
{
InputStream
is
=
null
;
try
{
is
=
new
BufferedInputStream
(
new
FileInputStream
(
srcFile
));
ZipEntry
entry
=
new
ZipEntry
(
rootPath
);
entry
.
setComment
(
comment
);
zos
.
putNextEntry
(
entry
);
byte
buffer
[]
=
new
byte
[
BUFFER_LEN
];
int
len
;
while
((
len
=
is
.
read
(
buffer
,
0
,
BUFFER_LEN
))
!=
-
1
)
{
zos
.
write
(
buffer
,
0
,
len
);
}
zos
.
closeEntry
();
}
finally
{
if
(
is
!=
null
)
{
is
.
close
();
}
}
}
return
true
;
}
/**
* Unzip the file.
*
* @param zipFilePath The path of ZIP file.
* @param destDirPath The path of destination directory.
* @return the unzipped files
* @throws IOException if unzip unsuccessfully
*/
public
static
List
<
File
>
unzipFile
(
final
String
zipFilePath
,
final
String
destDirPath
)
throws
IOException
{
return
unzipFileByKeyword
(
zipFilePath
,
destDirPath
,
null
);
}
/**
* Unzip the file.
*
* @param zipFile The ZIP file.
* @param destDir The destination directory.
* @return the unzipped files
* @throws IOException if unzip unsuccessfully
*/
public
static
List
<
File
>
unzipFile
(
final
File
zipFile
,
final
File
destDir
)
throws
IOException
{
return
unzipFileByKeyword
(
zipFile
,
destDir
,
null
);
}
/**
* Unzip the file by keyword.
*
* @param zipFilePath The path of ZIP file.
* @param destDirPath The path of destination directory.
* @param keyword The keyboard.
* @return the unzipped files
* @throws IOException if unzip unsuccessfully
*/
public
static
List
<
File
>
unzipFileByKeyword
(
final
String
zipFilePath
,
final
String
destDirPath
,
final
String
keyword
)
throws
IOException
{
return
unzipFileByKeyword
(
getFileByPath
(
zipFilePath
),
getFileByPath
(
destDirPath
),
keyword
);
}
/**
* Unzip the file by keyword.
*
* @param zipFile The ZIP file.
* @param destDir The destination directory.
* @param keyword The keyboard.
* @return the unzipped files
* @throws IOException if unzip unsuccessfully
*/
public
static
List
<
File
>
unzipFileByKeyword
(
final
File
zipFile
,
final
File
destDir
,
final
String
keyword
)
throws
IOException
{
if
(
zipFile
==
null
||
destDir
==
null
)
return
null
;
List
<
File
>
files
=
new
ArrayList
<>();
ZipFile
zip
=
new
ZipFile
(
zipFile
);
Enumeration
<?>
entries
=
zip
.
entries
();
try
{
if
(
isSpace
(
keyword
))
{
while
(
entries
.
hasMoreElements
())
{
ZipEntry
entry
=
((
ZipEntry
)
entries
.
nextElement
());
String
entryName
=
entry
.
getName
();
if
(
entryName
.
contains
(
"../"
))
{
System
.
err
.
println
(
"entryName: "
+
entryName
+
" is dangerous!"
);
continue
;
}
if
(!
unzipChildFile
(
destDir
,
files
,
zip
,
entry
,
entryName
))
return
files
;
}
}
else
{
while
(
entries
.
hasMoreElements
())
{
ZipEntry
entry
=
((
ZipEntry
)
entries
.
nextElement
());
String
entryName
=
entry
.
getName
();
if
(
entryName
.
contains
(
"../"
))
{
System
.
out
.
println
(
"entryName: "
+
entryName
+
" is dangerous!"
);
continue
;
}
if
(
entryName
.
contains
(
keyword
))
{
if
(!
unzipChildFile
(
destDir
,
files
,
zip
,
entry
,
entryName
))
return
files
;
}
}
}
}
finally
{
zip
.
close
();
}
return
files
;
}
private
static
boolean
unzipChildFile
(
final
File
destDir
,
final
List
<
File
>
files
,
final
ZipFile
zip
,
final
ZipEntry
entry
,
final
String
name
)
throws
IOException
{
File
file
=
new
File
(
destDir
,
name
);
files
.
add
(
file
);
if
(
entry
.
isDirectory
())
{
return
createOrExistsDir
(
file
);
}
else
{
if
(!
createOrExistsFile
(
file
))
return
false
;
InputStream
in
=
null
;
OutputStream
out
=
null
;
try
{
in
=
new
BufferedInputStream
(
zip
.
getInputStream
(
entry
));
out
=
new
BufferedOutputStream
(
new
FileOutputStream
(
file
));
byte
buffer
[]
=
new
byte
[
BUFFER_LEN
];
int
len
;
while
((
len
=
in
.
read
(
buffer
))
!=
-
1
)
{
out
.
write
(
buffer
,
0
,
len
);
}
}
finally
{
if
(
in
!=
null
)
{
in
.
close
();
}
if
(
out
!=
null
)
{
out
.
close
();
}
}
}
return
true
;
}
/**
* Return the files' path in ZIP file.
*
* @param zipFilePath The path of ZIP file.
* @return the files' path in ZIP file
* @throws IOException if an I/O error has occurred
*/
public
static
List
<
String
>
getFilesPath
(
final
String
zipFilePath
)
throws
IOException
{
return
getFilesPath
(
getFileByPath
(
zipFilePath
));
}
/**
* Return the files' path in ZIP file.
*
* @param zipFile The ZIP file.
* @return the files' path in ZIP file
* @throws IOException if an I/O error has occurred
*/
public
static
List
<
String
>
getFilesPath
(
final
File
zipFile
)
throws
IOException
{
if
(
zipFile
==
null
)
return
null
;
List
<
String
>
paths
=
new
ArrayList
<>();
ZipFile
zip
=
new
ZipFile
(
zipFile
);
Enumeration
<?>
entries
=
zip
.
entries
();
while
(
entries
.
hasMoreElements
())
{
String
entryName
=
((
ZipEntry
)
entries
.
nextElement
()).
getName
();
if
(
entryName
.
contains
(
"../"
))
{
System
.
out
.
println
(
"entryName: "
+
entryName
+
" is dangerous!"
);
paths
.
add
(
entryName
);
}
else
{
paths
.
add
(
entryName
);
}
}
zip
.
close
();
return
paths
;
}
/**
* Return the files' comment in ZIP file.
*
* @param zipFilePath The path of ZIP file.
* @return the files' comment in ZIP file
* @throws IOException if an I/O error has occurred
*/
public
static
List
<
String
>
getComments
(
final
String
zipFilePath
)
throws
IOException
{
return
getComments
(
getFileByPath
(
zipFilePath
));
}
/**
* Return the files' comment in ZIP file.
*
* @param zipFile The ZIP file.
* @return the files' comment in ZIP file
* @throws IOException if an I/O error has occurred
*/
public
static
List
<
String
>
getComments
(
final
File
zipFile
)
throws
IOException
{
if
(
zipFile
==
null
)
return
null
;
List
<
String
>
comments
=
new
ArrayList
<>();
ZipFile
zip
=
new
ZipFile
(
zipFile
);
Enumeration
<?>
entries
=
zip
.
entries
();
while
(
entries
.
hasMoreElements
())
{
ZipEntry
entry
=
((
ZipEntry
)
entries
.
nextElement
());
comments
.
add
(
entry
.
getComment
());
}
zip
.
close
();
return
comments
;
}
private
static
boolean
createOrExistsDir
(
final
File
file
)
{
return
file
!=
null
&&
(
file
.
exists
()
?
file
.
isDirectory
()
:
file
.
mkdirs
());
}
private
static
boolean
createOrExistsFile
(
final
File
file
)
{
if
(
file
==
null
)
return
false
;
if
(
file
.
exists
())
return
file
.
isFile
();
if
(!
createOrExistsDir
(
file
.
getParentFile
()))
return
false
;
try
{
return
file
.
createNewFile
();
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
return
false
;
}
}
private
static
File
getFileByPath
(
final
String
filePath
)
{
return
isSpace
(
filePath
)
?
null
:
new
File
(
filePath
);
}
private
static
boolean
isSpace
(
final
String
s
)
{
if
(
s
==
null
)
return
true
;
for
(
int
i
=
0
,
len
=
s
.
length
();
i
<
len
;
++
i
)
{
if
(!
Character
.
isWhitespace
(
s
.
charAt
(
i
)))
{
return
false
;
}
}
return
true
;
}
}
plugin/lib/base-transform/.gitignore
0 → 100755
浏览文件 @
f6367ba8
/build
ApiUtils2333.class
\ No newline at end of file
plugin/lib/base-transform/CHANGELOG.md
0 → 100644
浏览文件 @
f6367ba8
# Change Log
## v1.0(2020/04/28)
发布初版本
\ No newline at end of file
plugin/lib/base-transform/README.md
0 → 100644
浏览文件 @
f6367ba8
# 基础 transform 库
## 背景
api 和 bus 插件存在大量重复代码,所以抽出这么一个基础 transform 库。
## 使用
```
groovy
implementation
com
.
blankj
:
base
-
transform:
1.0
```
写插件直接继承 BaseTransformPlugin 即可,比如 ApiPlugin:
```
groovy
class
ApiPlugin
extends
BaseTransformPlugin
<
ApiExtension
>
{
@Override
String
getPluginName
()
{
// 获取插件名
}
@Override
void
onScanStarted
()
{
// 扫描开始的处理
}
@Override
boolean
isIgnoreScan
(
JarInput
input
)
{
// 对 jar 包进行过滤扫描,
// 工程中的 module 就是以 : 开头的 jar 包
// 远端仓库也是 jar 包
}
@Override
void
scanClassFile
(
File
classFile
,
String
className
,
File
originScannedJarOrDir
)
{
// 扫描到类文件的处理
}
@Override
void
onScanFinished
()
{
// 扫描结束的处理
}
}
```
更具体可以参考 ApiPlugin 及 BusPlugin 的源码。
## [Change Log](https://github.com/Blankj/AndroidUtilCode/blob/master/plugin/lib/base-transform/CHANGELOG.md)
\ No newline at end of file
plugin/lib/base-transform/build.gradle
0 → 100755
浏览文件 @
f6367ba8
apply
{
plugin
"groovy"
plugin
"java-gradle-plugin"
}
dependencies
{
compileOnly
Config
.
depConfig
.
plugin_gradle
.
dep
implementation
Config
.
depConfig
.
commons_io
.
dep
implementation
gradleApi
()
implementation
localGroovy
()
}
sourceSets
{
main
{
groovy
{
srcDirs
+=
'src/main/java'
}
}
}
apply
from:
"${rootDir.path}/gradle/publish.gradle"
publish
{
name
=
"BaseTransform"
groupId
=
Config
.
depConfig
.
plugin_lib_base_transform
.
groupId
artifactId
=
Config
.
depConfig
.
plugin_lib_base_transform
.
artifactId
version
=
Config
.
depConfig
.
plugin_lib_base_transform
.
version
website
=
"https://github.com/Blankj/AndroidUtilCode"
}
//./gradlew clean plugin:lib:plugin_lib_base-transform:mavenLocal // 上传到本地 mavenLocal
//./gradlew clean plugin:lib:plugin_lib_base-transform:bintrayUpload // 上传到 gradle 插件库中
plugin/lib/base-transform/src/main/java/com/blankj/base_transform/BaseTransformCallback.groovy
0 → 100644
浏览文件 @
f6367ba8
package
com.blankj.base_transform
import
com.android.build.api.transform.JarInput
interface
BaseTransformCallback
<
T
>
{
String
getPluginName
();
void
onScanStarted
();
boolean
isIgnoreScan
(
JarInput
input
);
void
scanClassFile
(
File
classFile
,
String
className
,
File
originScannedJarOrDir
);
void
onScanFinished
();
}
\ No newline at end of file
plugin/lib/base-transform/src/main/java/com/blankj/base_transform/BaseTransformConfig.groovy
0 → 100755
浏览文件 @
f6367ba8
package
com.blankj.base_transform
class
BaseTransformConfig
{
public
static
final
String
FILE_SEP
=
System
.
getProperty
(
"file.separator"
)
}
\ No newline at end of file
plugin/lib/base-transform/src/main/java/com/blankj/base_transform/BaseTransformPlugin.groovy
0 → 100755
浏览文件 @
f6367ba8
package
com.blankj.base_transform
import
com.android.build.api.transform.*
import
com.android.build.gradle.AppExtension
import
com.android.build.gradle.AppPlugin
import
com.android.build.gradle.internal.pipeline.TransformManager
import
com.blankj.base_transform.util.LogUtils
import
com.blankj.base_transform.util.ZipUtils
import
groovy.io.FileType
import
org.apache.commons.io.FileUtils
import
org.gradle.api.Plugin
import
org.gradle.api.Project
import
java.lang.reflect.ParameterizedType
abstract
class
BaseTransformPlugin
<
T
>
implements
Plugin
<
Project
>,
BaseTransformCallback
<
T
>
{
Project
mProject
T
getExt
()
{
return
mProject
.
getExtensions
().
getByName
(
getPluginName
())
}
@Override
void
apply
(
Project
project
)
{
if
(
project
.
plugins
.
hasPlugin
(
AppPlugin
))
{
mProject
=
project
LogUtils
.
init
(
project
)
log
(
'project('
+
project
.
toString
()
+
') apply '
+
getPluginName
()
+
' gradle plugin!'
)
project
.
extensions
.
create
(
getPluginName
(),
getGenericClass
())
def
android
=
project
.
extensions
.
getByType
(
AppExtension
)
android
.
registerTransform
(
new
BaseTransform
())
}
}
Class
<
T
>
getGenericClass
()
{
return
((
ParameterizedType
)
getClass
().
getGenericSuperclass
()).
getActualTypeArguments
()[
0
]
}
class
BaseTransform
extends
Transform
{
@Override
String
getName
()
{
return
"${getPluginName()}Transform"
}
@Override
Set
<
QualifiedContent
.
ContentType
>
getInputTypes
()
{
return
TransformManager
.
CONTENT_CLASS
}
@Override
Set
<?
super
QualifiedContent
.
Scope
>
getScopes
()
{
return
TransformManager
.
SCOPE_FULL_PROJECT
}
@Override
boolean
isIncremental
()
{
return
false
}
@Override
void
transform
(
TransformInvocation
transformInvocation
)
throws
TransformException
,
InterruptedException
,
IOException
{
super
.
transform
(
transformInvocation
)
log
(
getName
()
+
" started"
)
long
stTime
=
System
.
currentTimeMillis
()
def
inputs
=
transformInvocation
.
getInputs
()
def
referencedInputs
=
transformInvocation
.
getReferencedInputs
()
def
outputProvider
=
transformInvocation
.
getOutputProvider
()
def
isIncremental
=
transformInvocation
.
isIncremental
()
outputProvider
.
deleteAll
()
log
(
"${getPluginName()}Extension: $ext"
)
onScanStarted
()
inputs
.
each
{
TransformInput
input
->
input
.
directoryInputs
.
each
{
DirectoryInput
dirInput
->
// 遍历文件夹
File
dir
=
dirInput
.
file
File
dest
=
outputProvider
.
getContentLocation
(
dirInput
.
name
,
dirInput
.
contentTypes
,
dirInput
.
scopes
,
Format
.
DIRECTORY
)
FileUtils
.
copyDirectory
(
dir
,
dest
)
log
(
"scan dir: ${dirInput.file} -> $dest"
)
scanDir
(
dest
)
}
input
.
jarInputs
.
each
{
JarInput
jarInput
->
// 遍历 jar 文件
File
jar
=
jarInput
.
file
def
jarName
=
jarInput
.
name
def
dest
=
outputProvider
.
getContentLocation
(
jarName
,
jarInput
.
contentTypes
,
jarInput
.
scopes
,
Format
.
JAR
)
FileUtils
.
copyFile
(
jar
,
dest
)
if
(
isIgnoreScan
(
jarInput
))
{
log
(
"jump jar: $jarName -> $dest"
)
return
}
log
(
"scan jar: $jarName -> $dest"
)
scanJar
(
dest
)
}
}
onScanFinished
()
log
(
getName
()
+
" finished: "
+
(
System
.
currentTimeMillis
()
-
stTime
)
+
"ms"
)
}
void
scanJar
(
File
jar
)
{
File
tmp
=
new
File
(
jar
.
getParent
(),
"temp_"
+
jar
.
getName
())
List
<
File
>
unzipFile
=
ZipUtils
.
unzipFile
(
jar
,
tmp
)
if
(
unzipFile
!=
null
&&
unzipFile
.
size
()
>
0
)
{
scanDir
(
tmp
,
jar
)
FileUtils
.
forceDelete
(
tmp
)
}
}
void
scanDir
(
File
root
)
{
scanDir
(
root
,
root
)
}
void
scanDir
(
File
dir
,
File
originScannedJarOrDir
)
{
if
(!
dir
.
isDirectory
())
return
String
rootPath
=
dir
.
getAbsolutePath
()
if
(!
rootPath
.
endsWith
(
BaseTransformConfig
.
FILE_SEP
))
{
rootPath
+=
BaseTransformConfig
.
FILE_SEP
}
dir
.
eachFileRecurse
(
FileType
.
FILES
)
{
File
file
->
def
fileName
=
file
.
name
if
(!
fileName
.
endsWith
(
'.class'
)
||
fileName
.
startsWith
(
'R$'
)
||
fileName
==
'R.class'
||
fileName
==
'BuildConfig.class'
)
{
return
}
def
filePath
=
file
.
absolutePath
def
packagePath
=
filePath
.
replace
(
rootPath
,
''
)
def
className
=
packagePath
.
replace
(
BaseTransformConfig
.
FILE_SEP
,
"."
)
// delete .class
className
=
className
.
substring
(
0
,
className
.
length
()
-
6
)
scanClassFile
(
file
,
className
,
originScannedJarOrDir
)
}
}
}
void
log
(
Object
obj
)
{
LogUtils
.
l
(
getPluginName
(),
obj
)
}
}
\ No newline at end of file
plugin/
bus-gradle-plugin/src/main/java/com/blankj/bus
/util/JsonUtils.groovy
→
plugin/
lib/base-transform/src/main/java/com/blankj/base_transform
/util/JsonUtils.groovy
浏览文件 @
f6367ba8
package
com.blankj.b
us
.util
package
com.blankj.b
ase_transform
.util
import
com.google.gson.Gson
import
com.google.gson.GsonBuilder
...
...
plugin/
bus-gradle-plugin/src/main/java/com/blankj/bus
/util/LogUtils.groovy
→
plugin/
lib/base-transform/src/main/java/com/blankj/base_transform
/util/LogUtils.groovy
浏览文件 @
f6367ba8
package
com.blankj.b
us
.util
package
com.blankj.b
ase_transform
.util
import
org.gradle.api.Project
import
org.gradle.api.logging.Logger
...
...
@@ -6,29 +6,55 @@ import org.gradle.api.logging.Logger
final
class
LogUtils
{
private
static
Logger
sLogger
private
static
String
PREFIX
=
"PLUGIN-BUS >>> "
static
void
init
(
Project
project
)
{
sLogger
=
project
.
getLogger
()
}
static
void
l
(
Object
content
)
{
sLogger
.
lifecycle
(
PREFIX
+
content
)
l
(
""
,
content
)
}
static
void
d
(
Object
content
)
{
sLogger
.
debug
(
PREFIX
+
content
)
d
(
""
,
content
)
}
static
void
i
(
Object
content
)
{
sLogger
.
info
(
PREFIX
+
content
)
i
(
""
,
content
)
}
static
void
w
(
Object
content
)
{
sLogger
.
warn
(
PREFIX
+
content
)
w
(
""
,
content
)
}
static
void
e
(
Object
content
)
{
sLogger
.
error
(
PREFIX
+
content
)
e
(
""
,
content
)
}
static
void
l
(
String
tag
,
Object
content
)
{
sLogger
.
lifecycle
(
getTag
(
tag
)
+
content
)
}
static
void
d
(
String
tag
,
Object
content
)
{
sLogger
.
debug
(
getTag
(
tag
)
+
content
)
}
static
void
i
(
String
tag
,
Object
content
)
{
sLogger
.
info
(
getTag
(
tag
)
+
content
)
}
static
void
w
(
String
tag
,
Object
content
)
{
sLogger
.
warn
(
getTag
(
tag
)
+
content
)
}
static
void
e
(
String
tag
,
Object
content
)
{
sLogger
.
error
(
getTag
(
tag
)
+
content
)
}
private
static
String
getTag
(
String
tag
)
{
if
(
tag
==
null
||
tag
.
isEmpty
())
{
return
"LogUtils >>> "
}
return
tag
+
" >>> "
}
}
\ No newline at end of file
plugin/
api-gradle-plugin/src/main/java/com/blankj/api
/util/ZipUtils.java
→
plugin/
lib/base-transform/src/main/java/com/blankj/base_transform
/util/ZipUtils.java
浏览文件 @
f6367ba8
package
com.blankj.
api
.util
;
package
com.blankj.
base_transform
.util
;
import
java.io.BufferedInputStream
;
import
java.io.BufferedOutputStream
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录