未验证 提交 a5462747 编写于 作者: foozuu's avatar foozuu 提交者: GitHub

Merge branch 'master' into develop

* `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.
* `20/04/23` [fix] UriUtils#uri2File not support HW; TransActivity crash below 21.
* `20/04/23` [fix] PhoneUtils#getSerial, PhoneUtils#getSerial crash on Android 10.
* `20/04/20` [fix] ImageUtils#isImage.
* `20/04/18` [fix] PermissionUtils#callback. Publish v1.28.1.
* `20/04/17` [fix] ImageUtils#view2Bitmap, ImageUtils.getBitmap(InputStream).
* `20/04/16` [add] ConvertUtils#int2HexString, hexString2Int.
* `20/04/15` [add] UiMessageUtils' demo.
* `20/04/13` [add] NumberUtils. Publish v1.28.0.
* `20/04/12` [opt] TimeUtils#SDF_THREAD_LOCAL.
* `20/04/11` [add] SDCardUtils#getXxTotalSize, SDCardUtils#getXxAvailableSize. FileUtils#getFsTotalSize, FileUtils#getFsAvailableSize.
......
......@@ -14,8 +14,8 @@ class Config {
static compileSdkVersion = 29
static minSdkVersion = 14
static targetSdkVersion = 29
static versionCode = 1_026_001
static versionName = '1.28.0'// E.g. 1.9.72 => 1,009,072
static versionCode = 1_028_002
static versionName = '1.28.3'// E.g. 1.9.72 => 1,009,072
// lib version
static gradlePluginVersion = '3.5.0'
......
......@@ -255,6 +255,10 @@
android:name=".feature.toast.ToastActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:launchMode="singleTop" />
<activity
android:name=".feature.uiMessage.UiMessageActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:launchMode="singleTop" />
<activity
android:name=".feature.vibrate.VibrateActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
......
......@@ -44,6 +44,7 @@ import com.blankj.utilcode.pkg.feature.snackbar.SnackbarActivity
import com.blankj.utilcode.pkg.feature.spStatic.SPStaticActivity
import com.blankj.utilcode.pkg.feature.span.SpanActivity
import com.blankj.utilcode.pkg.feature.toast.ToastActivity
import com.blankj.utilcode.pkg.feature.uiMessage.UiMessageActivity
import com.blankj.utilcode.pkg.feature.vibrate.VibrateActivity
import com.blankj.utilcode.util.CollectionUtils
import com.blankj.utilcode.util.UtilsTransActivity
......@@ -191,6 +192,9 @@ class CoreUtilActivity : CommonActivity() {
}
})
},
CommonItemClick(R.string.demo_uiMessage, true) {
UiMessageActivity.start(this)
},
CommonItemClick(R.string.demo_vibrate, true) {
VibrateActivity.start(this)
}
......
......@@ -2,6 +2,7 @@ package com.blankj.utilcode.pkg.feature.bus
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.support.annotation.Keep
import com.blankj.common.activity.CommonActivity
import com.blankj.common.item.CommonItem
......
......@@ -157,39 +157,47 @@ class BusCompareActivity : CommonActivity() {
* 注销 10000 个订阅者,共执行 10 次取平均值
*/
private fun compareUnregister10000Times() {
val tests = ArrayList<BusEvent>()
for (i in 0..9999) {
val test = BusEvent()
EventBus.getDefault().register(test)
BusUtils.register(test)
tests.add(test)
}
compareWithEventBus("Unregister 10000 times.", 10, 1, object : CompareCallback {
override fun runEventBus() {
for (test in tests) {
EventBus.getDefault().unregister(test)
}
}
override fun runBusUtils() {
for (test in tests) {
BusUtils.unregister(test)
}
}
override fun restState() {
for (test in tests) {
showLoading()
ThreadUtils.executeBySingle(object : ThreadUtils.SimpleTask<List<BusEvent>>() {
override fun doInBackground(): List<BusEvent> {
val tests = ArrayList<BusEvent>()
for (i in 0..9999) {
val test = BusEvent()
EventBus.getDefault().register(test)
BusUtils.register(test)
tests.add(test)
}
return tests
}
}, object : OnFinishCallback {
override fun onFinish() {
for (test in tests) {
EventBus.getDefault().unregister(test)
BusUtils.unregister(test)
}
override fun onSuccess(tests: List<BusEvent>) {
compareWithEventBus("Unregister 10000 times.", 10, 1, object : CompareCallback {
override fun runEventBus() {
for (test in tests) {
EventBus.getDefault().unregister(test)
}
}
override fun runBusUtils() {
for (test in tests) {
BusUtils.unregister(test)
}
}
override fun restState() {
for (test in tests) {
EventBus.getDefault().register(test)
BusUtils.register(test)
}
}
}, object : OnFinishCallback {
override fun onFinish() {
for (test in tests) {
EventBus.getDefault().unregister(test)
BusUtils.unregister(test)
}
}
})
}
})
}
......
......@@ -11,6 +11,7 @@ import com.blankj.common.activity.CommonActivity
import com.blankj.common.item.CommonItem
import com.blankj.common.item.CommonItemClick
import com.blankj.common.item.CommonItemImage
import com.blankj.common.item.CommonItemTitle
import com.blankj.utilcode.pkg.Config
import com.blankj.utilcode.pkg.R
import com.blankj.utilcode.util.*
......@@ -26,6 +27,9 @@ import java.util.*
*/
class ImageActivity : CommonActivity() {
private val savePath = Config.CACHE_PATH + "lena.jpg"
private val titleItem: CommonItemTitle = CommonItemTitle("isImage: $savePath", "");
companion object {
fun start(context: Context) {
val starter = Intent(context, ImageActivity::class.java)
......@@ -57,23 +61,27 @@ class ImageActivity : CommonActivity() {
val width = src.width
val height = src.height
titleItem.setContent(ImageUtils.isImage(savePath).toString())
return CollectionUtils.newArrayList<CommonItem<*>>().apply {
add(CommonItemClick(R.string.image_save) {
val savePath = Config.CACHE_PATH + "lena.jpg"
add(titleItem)
add(CommonItemClick("Save to $savePath") {
ThreadUtils.executeBySingle(object : ThreadUtils.SimpleTask<Boolean>() {
override fun doInBackground(): Boolean {
return ImageUtils.save(src, savePath, Bitmap.CompressFormat.JPEG)
}
override fun onSuccess(result: Boolean) {
titleItem.setContent(ImageUtils.isImage(savePath).toString())
titleItem.update()
SnackbarUtils.with(mContentView)
.setDuration(SnackbarUtils.LENGTH_LONG)
.apply {
if (result) {
setMessage("save to \"$savePath\" successful.")
setMessage("save successful.")
.showSuccess()
} else {
setMessage("save to \"$savePath\" failed.")
setMessage("save failed.")
.showError()
}
}
......
......@@ -39,22 +39,37 @@ class SnackbarActivity : CommonActivity() {
override fun bindItems(): MutableList<CommonItem<*>> {
return CollectionUtils.newArrayList(
CommonItemClick(R.string.snackbar_show_short) {
CommonItemClick(R.string.snackbar_short) {
SnackbarUtils.with(mContentView)
.setMessage(getMsg(R.string.snackbar_short))
.setMessageColor(Color.WHITE)
.setBgResource(R.drawable.snackbar_custom_bg)
.show()
},
CommonItemClick(R.string.snackbar_show_short_with_action) {
CommonItemClick(R.string.snackbar_short_top) {
SnackbarUtils.with(mContentView)
.setMessage(getMsg(R.string.snackbar_short))
.setMessage(getMsg(R.string.snackbar_short_top))
.setMessageColor(Color.WHITE)
.setBgResource(R.drawable.snackbar_custom_bg)
.show(true)
},
CommonItemClick(R.string.snackbar_short_with_action) {
SnackbarUtils.with(mContentView)
.setMessage(getMsg(R.string.snackbar_short_with_action))
.setMessageColor(Color.WHITE)
.setBgResource(R.drawable.snackbar_custom_bg)
.setAction(getString(R.string.snackbar_click), Color.YELLOW) { ToastUtils.showShort(getString(R.string.snackbar_click)) }
.show()
},
CommonItemClick(R.string.snackbar_show_long) {
CommonItemClick(R.string.snackbar_short_with_action_top) {
SnackbarUtils.with(mContentView)
.setMessage(getMsg(R.string.snackbar_short_with_action_top))
.setMessageColor(Color.WHITE)
.setBgResource(R.drawable.snackbar_custom_bg)
.setAction(getString(R.string.snackbar_click), Color.YELLOW) { ToastUtils.showShort(getString(R.string.snackbar_click)) }
.show(true)
},
CommonItemClick(R.string.snackbar_long) {
SnackbarUtils.with(mContentView)
.setMessage(getMsg(R.string.snackbar_long))
.setMessageColor(Color.WHITE)
......@@ -62,16 +77,16 @@ class SnackbarActivity : CommonActivity() {
.setBgResource(R.drawable.snackbar_custom_bg)
.show()
},
CommonItemClick(R.string.snackbar_show_long_with_action) {
CommonItemClick(R.string.snackbar_long_with_action) {
SnackbarUtils.with(mContentView)
.setMessage(getMsg(R.string.snackbar_long))
.setMessage(getMsg(R.string.snackbar_long_with_action))
.setMessageColor(Color.WHITE)
.setBgResource(R.drawable.snackbar_custom_bg)
.setDuration(SnackbarUtils.LENGTH_LONG)
.setAction(getString(R.string.snackbar_click), Color.YELLOW) { ToastUtils.showShort(getString(R.string.snackbar_click)) }
.show()
},
CommonItemClick(R.string.snackbar_show_indefinite) {
CommonItemClick(R.string.snackbar_indefinite) {
SnackbarUtils.with(mContentView)
.setMessage(getMsg(R.string.snackbar_indefinite))
.setMessageColor(Color.WHITE)
......@@ -79,9 +94,9 @@ class SnackbarActivity : CommonActivity() {
.setBgResource(R.drawable.snackbar_custom_bg)
.show()
},
CommonItemClick(R.string.snackbar_show_indefinite_with_action) {
CommonItemClick(R.string.snackbar_indefinite_with_action) {
SnackbarUtils.with(mContentView)
.setMessage(getMsg(R.string.snackbar_indefinite))
.setMessage(getMsg(R.string.snackbar_indefinite_with_action))
.setMessageColor(Color.WHITE)
.setDuration(SnackbarUtils.LENGTH_INDEFINITE)
.setBgResource(R.drawable.snackbar_custom_bg)
......@@ -113,17 +128,17 @@ class SnackbarActivity : CommonActivity() {
snackbarView.setOnClickListener { SnackbarUtils.dismiss() }
}
},
CommonItemClick(R.string.snackbar_show_success) {
CommonItemClick(R.string.snackbar_success) {
SnackbarUtils.with(mContentView)
.setMessage(getMsg(R.string.snackbar_success))
.showSuccess()
},
CommonItemClick(R.string.snackbar_show_warning) {
CommonItemClick(R.string.snackbar_warning) {
SnackbarUtils.with(mContentView)
.setMessage(getMsg(R.string.snackbar_warning))
.showWarning()
},
CommonItemClick(R.string.snackbar_show_error) {
CommonItemClick(R.string.snackbar_error) {
SnackbarUtils.with(mContentView)
.setMessage(getMsg(R.string.snackbar_error))
.showError()
......
package com.blankj.utilcode.pkg.feature.uiMessage
import android.content.Context
import android.content.Intent
import com.blankj.common.activity.CommonActivity
import com.blankj.common.item.CommonItem
import com.blankj.common.item.CommonItemClick
import com.blankj.common.item.CommonItemTitle
import com.blankj.utilcode.pkg.R
import com.blankj.utilcode.util.CollectionUtils
import com.blankj.utilcode.util.UiMessageUtils
/**
* ```
* author: Blankj
* blog : http://blankj.com
* time : 2020/04/14
* desc : demo about UiMessageUtils
* ```
*/
class UiMessageActivity : CommonActivity(), UiMessageUtils.UiMessageCallback {
private val titleItem: CommonItemTitle = CommonItemTitle("", true);
private var sendContent: String = ""
companion object {
fun start(context: Context) {
val starter = Intent(context, UiMessageActivity::class.java)
context.startActivity(starter)
}
}
override fun bindTitleRes(): Int {
return R.string.demo_uiMessage
}
override fun bindItems(): List<CommonItem<*>> {
return CollectionUtils.newArrayList(
titleItem,
CommonItemClick(R.string.uiMessage_add_listener_id) {
UiMessageUtils.getInstance().addListener(R.id.utilCodeUiMessageAddListenerId, this)
},
CommonItemClick(R.string.uiMessage_remove_all_id) {
UiMessageUtils.getInstance().removeListeners(R.id.utilCodeUiMessageAddListenerId)
},
CommonItemClick(R.string.uiMessage_add_listener) {
UiMessageUtils.getInstance().addListener(this)
},
CommonItemClick(R.string.uiMessage_remove_listener) {
UiMessageUtils.getInstance().removeListener(this)
},
CommonItemClick(R.string.uiMessage_send) {
sendContent = "send: UiMessageActivity#${UiMessageActivity.hashCode()}"
titleItem.title = ""
UiMessageUtils.getInstance().send(R.id.utilCodeUiMessageAddListenerId, UiMessageActivity)
}
)
}
override fun handleMessage(localMessage: UiMessageUtils.UiMessage) {
if (localMessage.id == R.id.utilCodeUiMessageAddListenerId) {
var content: String = sendContent
content += "\nreceive: UiMessageActivity#${localMessage.getObject().hashCode()}"
titleItem.title = if (titleItem.title.toString().isEmpty()) {
content
} else {
titleItem.title.toString() + "\n" + content
}
}
}
override fun onDestroy() {
super.onDestroy()
UiMessageUtils.getInstance().removeListeners(R.id.utilCodeUiMessageAddListenerId)
UiMessageUtils.getInstance().removeListener(this)
}
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="utilCodeUiMessageAddListenerId" type="id" />
</resources>
\ No newline at end of file
......@@ -37,6 +37,7 @@
<string name="demo_spStatic">SPStaticUtils Demo</string>
<string name="demo_span">SpanUtils Demo</string>
<string name="demo_toast">ToastUtils Demo</string>
<string name="demo_uiMessage">UiMessage Demo</string>
<string name="demo_trans_activity">TransActivity Demo</string>
<string name="demo_vibrate">VibrateUtils Demo</string>
......@@ -206,7 +207,6 @@
<string name="image_fast_blur">Fast Blur</string>
<string name="image_render_script_blur">Render Script Blur</string>
<string name="image_stack_blur">Stack Blur</string>
<string name="image_save">Save</string>
<string name="image_compress_by_scale">Compress By Scale</string>
<string name="image_compress_by_quality_half">Compress By Quality Half</string>
<string name="image_compress_by_quality_max_size">Compress By Quality Max Size</string>
......@@ -294,26 +294,22 @@
<string name="screen_screenshot">Screenshot</string>
<!--SnackBar 相关-->
<string name="snackbar_show_short">Show Short Snackbar</string>
<string name="snackbar_show_short_with_action">Show Short Snackbar With Action</string>
<string name="snackbar_show_long">Show Long Snackbar</string>
<string name="snackbar_show_long_with_action">Show Long Snackbar With Action</string>
<string name="snackbar_show_indefinite">Show Indefinite Snackbar</string>
<string name="snackbar_show_indefinite_with_action">Show Indefinite Snackbar With Action</string>
<string name="snackbar_add_view">Add View</string>
<string name="snackbar_add_view_with_action">Add View With Action</string>
<string name="snackbar_show_success">Show Success</string>
<string name="snackbar_show_warning">Show Warning</string>
<string name="snackbar_show_error">Show Error</string>
<string name="snackbar_dismiss">Dismiss Snackbar</string>
<string name="snackbar_short">Short Snackbar</string>
<string name="snackbar_short_top">Short Snackbar Top</string>
<string name="snackbar_short_with_action">Short Snackbar With Action</string>
<string name="snackbar_short_with_action_top">Short Snackbar With Action Top</string>
<string name="snackbar_long">Long Snackbar</string>
<string name="snackbar_long_with_action">Long Snackbar With Action</string>
<string name="snackbar_indefinite">Indefinite Snackbar</string>
<string name="snackbar_click">Click</string>
<string name="snackbar_custom_view">Custom View</string>
<string name="snackbar_indefinite_with_action">Indefinite Snackbar With Action</string>
<string name="snackbar_add_view">Add View</string>
<string name="snackbar_add_view_with_action">Add View With Action</string>
<string name="snackbar_success">Success</string>
<string name="snackbar_warning">Warning</string>
<string name="snackbar_error">Error</string>
<string name="snackbar_dismiss">Dismiss Snackbar</string>
<string name="snackbar_click">Click</string>
<string name="snackbar_custom_view">Custom View</string>
<string name="snackbar_click_to_dismiss">Click To Dismiss</string>
<!--SP 相关-->
......@@ -337,7 +333,6 @@
<string name="toast_show_middle">Show Middle</string>
<string name="toast_cancel">Cancel</string>
<string name="toast_show_toast_dialog">Show Toast Dialog</string>
<string name="toast_short">Short</string>
<string name="toast_long">Long</string>
<string name="toast_green_font">Green Font</string>
......@@ -346,6 +341,13 @@
<string name="toast_span">Spannable String</string>
<string name="toast_middle">Middle</string>
<!--UiMessage 相关-->
<string name="uiMessage_add_listener_id">Add Listener Id</string>
<string name="uiMessage_remove_all_id">Remove All Id</string>
<string name="uiMessage_add_listener">Add Listener</string>
<string name="uiMessage_remove_listener">Remove Listener</string>
<string name="uiMessage_send">Send</string>
<!--Vibrate 相关-->
<string name="vibrate_1000ms">Vibrate 1000ms</string>
<string name="vibrate_custom">Vibrate Custom</string>
......
......@@ -209,7 +209,7 @@ public abstract class CommonActivity extends BaseActivity {
public void showLoading(Runnable listener) {
if (mDialogLoading != null) {
dismissLoading();
return;
}
mDialogLoading = new CommonDialogLoading().init(this, listener);
mDialogLoading.show();
......
......@@ -74,8 +74,25 @@ public class CommonItemTitle extends CommonItem {
}
public void setTitle(CharSequence title) {
setTitle(title, true);
}
public void setContent(CharSequence content) {
setContent(content, true);
}
public void setTitle(CharSequence title, boolean isUpdate) {
mTitle = title;
update();
if (isUpdate) {
update();
}
}
public void setContent(CharSequence content, boolean isUpdate) {
mContent = content;
if (isUpdate) {
update();
}
}
public CharSequence getTitle() {
......
......@@ -2,10 +2,10 @@
Gradle:
```groovy
implementation 'com.blankj:utilcode:1.28.0'
implementation 'com.blankj:utilcode:1.28.3'
// if u use AndroidX, use the following
implementation 'com.blankj:utilcodex:1.28.0'
implementation 'com.blankj:utilcodex:1.28.3'
```
......@@ -346,6 +346,7 @@ getRandomColor : 获取随机色
* ### 转换相关 -> [ConvertUtils.java][convert.java] -> [Test][convert.test]
```
int2HexString, hexString2Int : int 与 hexString 互转
bytes2Bits, bits2Bytes : bytes 与 bits 互转
bytes2Chars, chars2Bytes : bytes 与 chars 互转
bytes2HexString, hexString2Bytes : bytes 与 hexString 互转
......@@ -1147,7 +1148,7 @@ cancel : 取消吐司显示
setOnTouchListener: 设置触摸事件
```
* ### UI 消息相关 -> [UiMessageUtils.java][uiMessage.java]
* ### UI 消息相关 -> [UiMessageUtils.java][uiMessage.java] -> [Demo][uiMessage.demo]
```
send : 发送消息
addListener : 新增消息监听器
......@@ -1156,9 +1157,10 @@ removeListener: 移除消息监听器
* ### URI 相关 -> [UriUtils.java][uri.java]
```
res2Uri : res 转 uri
file2Uri: file 转 uri
uri2File: uri 转 file
res2Uri : res 转 uri
file2Uri : file 转 uri
uri2File : uri 转 file
uri2InputStream: uri 转 InputStream
```
* ### UtilsTransActivity -> [UtilsTransActivity.java][trans.java]
......@@ -1388,6 +1390,7 @@ getComments : 获取压缩文件中的注释链表
[touch.java]: https://github.com/Blankj/AndroidUtilCode/blob/master/lib/utilcode/src/main/java/com/blankj/utilcode/util/TouchUtils.java
[uiMessage.java]: https://github.com/Blankj/AndroidUtilCode/blob/master/lib/utilcode/src/main/java/com/blankj/utilcode/util/UiMessageUtils.java
[uiMessage.demo]: https://github.com/Blankj/AndroidUtilCode/blob/master/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/uiMessage/UiMessageActivity.kt
[uri.java]: https://github.com/Blankj/AndroidUtilCode/blob/master/lib/utilcode/src/main/java/com/blankj/utilcode/util/UriUtils.java
......
......@@ -2,10 +2,10 @@
Gradle:
```groovy
implementation 'com.blankj:utilcode:1.28.0'
implementation 'com.blankj:utilcode:1.28.3'
// if u use AndroidX, use the following
implementation 'com.blankj:utilcodex:1.28.0'
implementation 'com.blankj:utilcodex:1.28.3'
```
......@@ -346,6 +346,7 @@ getRandomColor
* ### About Convert -> [ConvertUtils.java][convert.java] -> [Test][convert.test]
```
int2HexString, hexString2Int
bytes2Bits, bits2Bytes
bytes2Chars, chars2Bytes
bytes2HexString, hexString2Bytes
......@@ -1147,7 +1148,7 @@ cancel
setOnTouchListener
```
* ### About UiMessage -> [UiMessageUtils.java][uiMessage.java]
* ### About UiMessage -> [UiMessageUtils.java][uiMessage.java] -> [Demo][uiMessage.demo]
```
send
addListener
......@@ -1159,6 +1160,7 @@ removeListener
res2Uri
file2Uri
uri2File
uri2InputStream
```
* ### UtilsTransActivity -> [UtilsTransActivity.java][trans.java]
......@@ -1385,6 +1387,7 @@ getComments
[touch.java]: https://github.com/Blankj/AndroidUtilCode/blob/master/lib/utilcode/src/main/java/com/blankj/utilcode/util/TouchUtils.java
[uiMessage.java]: https://github.com/Blankj/AndroidUtilCode/blob/master/lib/utilcode/src/main/java/com/blankj/utilcode/util/UiMessageUtils.java
[uiMessage.demo]: https://github.com/Blankj/AndroidUtilCode/blob/master/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/uiMessage/UiMessageActivity.kt
[uri.java]: https://github.com/Blankj/AndroidUtilCode/blob/master/lib/utilcode/src/main/java/com/blankj/utilcode/util/UriUtils.java
......
......@@ -14,8 +14,7 @@
android:name="com.blankj.utilcode.util.UtilsFileProvider"
android:authorities="${applicationId}.utilcode.provider"
android:exported="false"
android:grantUriPermissions="true"
android:multiprocess="true">
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/util_code_provider_paths" />
......
......@@ -34,7 +34,7 @@ public final class BusUtils {
private final Map<String, List<BusInfo>> mTag_BusInfoListMap = new HashMap<>();
private final Map<String, Set<Object>> mClassName_BusesMap = new ConcurrentHashMap<>();
private final Map<String, List<String>> mClassName_TagsMap = new HashMap<>();
private final Map<String, List<String>> mClassName_TagsMap = new ConcurrentHashMap<>();
private final Map<String, Map<String, Object>> mClassName_Tag_Arg4StickyMap = new ConcurrentHashMap<>();
private BusUtils() {
......@@ -122,7 +122,7 @@ public final class BusUtils {
synchronized (mClassName_TagsMap) {
tags = mClassName_TagsMap.get(className);
if (tags == null) {
tags = new ArrayList<>();
tags = new CopyOnWriteArrayList<>();
for (Map.Entry<String, List<BusInfo>> entry : mTag_BusInfoListMap.entrySet()) {
for (BusInfo busInfo : entry.getValue()) {
try {
......
......@@ -38,14 +38,36 @@ import java.util.List;
*/
public final class ConvertUtils {
private static final int BUFFER_SIZE = 8192;
private static final char[] hexDigits =
private static final int BUFFER_SIZE = 8192;
private static final char[] HEX_DIGITS_UPPER =
{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
private static final char[] HEX_DIGITS_LOWER =
{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
private ConvertUtils() {
throw new UnsupportedOperationException("u can't instantiate me...");
}
/**
* Int to hex string.
*
* @param num The int number.
* @return the hex string
*/
public static String int2HexString(int num) {
return Integer.toHexString(num);
}
/**
* Hex string to int.
*
* @param hexString The hex string.
* @return the int
*/
public static int hexString2Int(String hexString) {
return Integer.parseInt(hexString, 16);
}
/**
* Bytes to bits.
*
......@@ -130,7 +152,20 @@ public final class ConvertUtils {
* @return hex string
*/
public static String bytes2HexString(final byte[] bytes) {
return bytes2HexString(bytes, true);
}
/**
* Bytes to hex string.
* <p>e.g. bytes2HexString(new byte[] { 0, (byte) 0xa8 }, true) returns "00A8"</p>
*
* @param bytes The bytes.
* @param isUpperCase True to use upper case, false otherwise.
* @return hex string
*/
public static String bytes2HexString(final byte[] bytes, boolean isUpperCase) {
if (bytes == null) return "";
char[] hexDigits = isUpperCase ? HEX_DIGITS_UPPER : HEX_DIGITS_LOWER;
int len = bytes.length;
if (len <= 0) return "";
char[] ret = new char[len << 1];
......
......@@ -649,7 +649,7 @@ public final class FileUtils {
* @return the files in directory
*/
public static List<File> listFilesInDir(final String dirPath, Comparator<File> comparator) {
return listFilesInDir(getFileByPath(dirPath), false);
return listFilesInDir(getFileByPath(dirPath), false, comparator);
}
/**
......
......@@ -9,10 +9,10 @@ import com.google.gson.reflect.TypeToken;
import java.io.Reader;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
......@@ -29,7 +29,7 @@ public final class GsonUtils {
private static final String KEY_DELEGATE = "delegateGson";
private static final String KEY_LOG_UTILS = "logUtilsGson";
private static final Map<String, Gson> GSONS = new HashMap<>();
private static final Map<String, Gson> GSONS = new ConcurrentHashMap<>();
private GsonUtils() {
throw new UnsupportedOperationException("u can't instantiate me...");
......@@ -85,7 +85,7 @@ public final class GsonUtils {
* @param object The object to serialize.
* @return object serialized into json.
*/
public static String toJson(@NonNull final Object object) {
public static String toJson(final Object object) {
return toJson(getGson(), object);
}
......@@ -96,7 +96,7 @@ public final class GsonUtils {
* @param typeOfSrc The specific genericized type of src.
* @return object serialized into json.
*/
public static String toJson(@NonNull final Object src, @NonNull final Type typeOfSrc) {
public static String toJson(final Object src, @NonNull final Type typeOfSrc) {
return toJson(getGson(), src, typeOfSrc);
}
......@@ -107,7 +107,7 @@ public final class GsonUtils {
* @param object The object to serialize.
* @return object serialized into json.
*/
public static String toJson(@NonNull final Gson gson, @NonNull final Object object) {
public static String toJson(@NonNull final Gson gson, final Object object) {
return gson.toJson(object);
}
......@@ -119,7 +119,7 @@ public final class GsonUtils {
* @param typeOfSrc The specific genericized type of src.
* @return object serialized into json.
*/
public static String toJson(@NonNull final Gson gson, @NonNull final Object src, @NonNull final Type typeOfSrc) {
public static String toJson(@NonNull final Gson gson, final Object src, @NonNull final Type typeOfSrc) {
return gson.toJson(src, typeOfSrc);
}
......@@ -130,7 +130,7 @@ public final class GsonUtils {
* @param type Type json will be converted to.
* @return instance of type
*/
public static <T> T fromJson(@NonNull final String json, @NonNull final Class<T> type) {
public static <T> T fromJson(final String json, @NonNull final Class<T> type) {
return fromJson(getGson(), json, type);
}
......@@ -141,7 +141,7 @@ public final class GsonUtils {
* @param type type type json will be converted to.
* @return instance of type
*/
public static <T> T fromJson(@NonNull final String json, @NonNull final Type type) {
public static <T> T fromJson(final String json, @NonNull final Type type) {
return fromJson(getGson(), json, type);
}
......@@ -175,7 +175,7 @@ public final class GsonUtils {
* @param type Type json will be converted to.
* @return instance of type
*/
public static <T> T fromJson(@NonNull final Gson gson, @NonNull final String json, @NonNull final Class<T> type) {
public static <T> T fromJson(@NonNull final Gson gson, final String json, @NonNull final Class<T> type) {
return gson.fromJson(json, type);
}
......@@ -187,7 +187,7 @@ public final class GsonUtils {
* @param type type type json will be converted to.
* @return instance of type
*/
public static <T> T fromJson(@NonNull final Gson gson, @NonNull final String json, @NonNull final Type type) {
public static <T> T fromJson(@NonNull final Gson gson, final String json, @NonNull final Type type) {
return gson.fromJson(json, type);
}
......@@ -199,7 +199,7 @@ public final class GsonUtils {
* @param type type type json will be converted to.
* @return instance of type
*/
public static <T> T fromJson(@NonNull final Gson gson, @NonNull final Reader reader, @NonNull final Class<T> type) {
public static <T> T fromJson(@NonNull final Gson gson, final Reader reader, @NonNull final Class<T> type) {
return gson.fromJson(reader, type);
}
......@@ -211,7 +211,7 @@ public final class GsonUtils {
* @param type type type json will be converted to.
* @return instance of type
*/
public static <T> T fromJson(@NonNull final Gson gson, @NonNull final Reader reader, @NonNull final Type type) {
public static <T> T fromJson(@NonNull final Gson gson, final Reader reader, @NonNull final Type type) {
return gson.fromJson(reader, type);
}
......
......@@ -183,14 +183,21 @@ public final class ImageUtils {
boolean willNotCacheDrawing = view.willNotCacheDrawing();
view.setDrawingCacheEnabled(true);
view.setWillNotCacheDrawing(false);
final Bitmap drawingCache = view.getDrawingCache();
Bitmap drawingCache = view.getDrawingCache();
Bitmap bitmap;
if (null == drawingCache) {
view.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
view.buildDrawingCache();
bitmap = Bitmap.createBitmap(view.getDrawingCache());
drawingCache = view.getDrawingCache();
if (drawingCache != null) {
bitmap = Bitmap.createBitmap(drawingCache);
} else {
bitmap = Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
view.draw(canvas);
}
} else {
bitmap = Bitmap.createBitmap(drawingCache);
}
......@@ -279,8 +286,12 @@ public final class ImageUtils {
*/
public static Bitmap getBitmap(final InputStream is, final int maxWidth, final int maxHeight) {
if (is == null) return null;
byte[] bytes = UtilsBridge.inputStream2Bytes(is);
return getBitmap(bytes, 0, maxWidth, maxHeight);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(is, null, options);
options.inSampleSize = calculateInSampleSize(options, maxWidth, maxHeight);
options.inJustDecodeBounds = false;
return BitmapFactory.decodeStream(is, null, options);
}
/**
......@@ -1578,11 +1589,11 @@ public final class ImageUtils {
* @return {@code true}: yes<br>{@code false}: no
*/
public static boolean isImage(final String filePath) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
try {
Bitmap bitmap = BitmapFactory.decodeFile(filePath, options);
return bitmap != null && options.outWidth != -1 && options.outHeight != -1;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filePath, options);
return options.outWidth > 0 && options.outHeight > 0;
} catch (Exception e) {
return false;
}
......
......@@ -135,7 +135,7 @@ public final class KeyboardUtils {
public static void hideSoftInputByToggle(final Activity activity) {
long nowMillis = System.currentTimeMillis();
long delta = nowMillis - millis;
if (KeyboardUtils.isSoftInputVisible(activity) && Math.abs(delta) > 500) {
if (Math.abs(delta) > 500 && KeyboardUtils.isSoftInputVisible(activity)) {
KeyboardUtils.toggleSoftInput();
}
millis = nowMillis;
......
......@@ -197,7 +197,8 @@ public class MessengerUtils {
}
void unbind() {
Message msg = Message.obtain(mReceiveServeMsgHandler, WHAT_UNSUBSCRIBE);
int key = UtilsBridge.getCurrentProcessName().hashCode();
Message msg = Message.obtain(mReceiveServeMsgHandler, WHAT_UNSUBSCRIBE, key, 0);
msg.replyTo = mClient;
try {
mServer.send(msg);
......
......@@ -432,10 +432,10 @@ public final class PermissionUtils {
int requestCode,
String[] permissions,
int[] grantResults) {
activity.finish();
if (sInstance != null && sInstance.mPermissionsRequest != null) {
sInstance.onRequestPermissionsResult(activity);
}
activity.finish();
}
......
......@@ -47,7 +47,7 @@ public final class PhoneUtils {
@SuppressLint("HardwareIds")
@RequiresPermission(READ_PHONE_STATE)
public static String getDeviceId() {
if (Build.VERSION.SDK_INT >= 29) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
return "";
}
TelephonyManager tm = getTelephonyManager();
......@@ -70,6 +70,14 @@ public final class PhoneUtils {
@SuppressLint("HardwareIds")
@RequiresPermission(READ_PHONE_STATE)
public static String getSerial() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
try {
return Build.getSerial();
} catch (SecurityException e) {
e.printStackTrace();
return "";
}
}
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ? Build.getSerial() : Build.SERIAL;
}
......@@ -100,7 +108,7 @@ public final class PhoneUtils {
@SuppressLint("HardwareIds")
@RequiresPermission(READ_PHONE_STATE)
public static String getImeiOrMeid(boolean isImei) {
if (Build.VERSION.SDK_INT >= 29) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
return "";
}
TelephonyManager tm = getTelephonyManager();
......@@ -200,6 +208,14 @@ public final class PhoneUtils {
@SuppressLint("HardwareIds")
@RequiresPermission(READ_PHONE_STATE)
public static String getIMSI() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
try {
getTelephonyManager().getSubscriberId();
} catch (SecurityException e) {
e.printStackTrace();
return "";
}
}
return getTelephonyManager().getSubscriberId();
}
......
package com.blankj.utilcode.util;
import android.os.Build;
import android.support.annotation.ColorInt;
import android.support.annotation.DrawableRes;
import android.support.annotation.IntDef;
import android.support.annotation.IntRange;
import android.support.annotation.LayoutRes;
import android.support.annotation.NonNull;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.Snackbar;
import android.text.SpannableString;
import android.text.Spanned;
......@@ -13,6 +15,8 @@ import android.text.style.ForegroundColorSpan;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.widget.FrameLayout;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
......@@ -186,8 +190,33 @@ public final class SnackbarUtils {
* Show the snackbar.
*/
public Snackbar show() {
final View view = this.view;
return show(false);
}
/**
* Show the snackbar.
*
* @param isShowTop True to show the snack bar on the top, false otherwise.
*/
public Snackbar show(boolean isShowTop) {
View view = this.view;
if (view == null) return null;
if (isShowTop) {
ViewGroup suitableParent = findSuitableParentCopyFromSnackbar(view);
View topSnackBarContainer = suitableParent.findViewWithTag("topSnackBarCoordinatorLayout");
if (topSnackBarContainer == null) {
CoordinatorLayout topSnackBarCoordinatorLayout = new CoordinatorLayout(view.getContext());
topSnackBarCoordinatorLayout.setTag("topSnackBarCoordinatorLayout");
topSnackBarCoordinatorLayout.setRotation(180);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// bring to front
topSnackBarCoordinatorLayout.setElevation(100);
}
suitableParent.addView(topSnackBarCoordinatorLayout, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
topSnackBarContainer = topSnackBarCoordinatorLayout;
}
view = topSnackBarContainer;
}
if (messageColor != COLOR_DEFAULT) {
SpannableString spannableString = new SpannableString(message);
ForegroundColorSpan colorSpan = new ForegroundColorSpan(messageColor);
......@@ -199,7 +228,13 @@ public final class SnackbarUtils {
sReference = new WeakReference<>(Snackbar.make(view, message, duration));
}
final Snackbar snackbar = sReference.get();
final View snackbarView = snackbar.getView();
final Snackbar.SnackbarLayout snackbarView = (Snackbar.SnackbarLayout) snackbar.getView();
if (isShowTop) {
for (int i = 0; i < snackbarView.getChildCount(); i++) {
View child = snackbarView.getChildAt(i);
child.setRotation(180);
}
}
if (bgResource != -1) {
snackbarView.setBackgroundResource(bgResource);
} else if (bgColor != COLOR_DEFAULT) {
......@@ -224,30 +259,57 @@ public final class SnackbarUtils {
* Show the snackbar with success style.
*/
public void showSuccess() {
showSuccess(false);
}
/**
* Show the snackbar with success style.
*
* @param isShowTop True to show the snack bar on the top, false otherwise.
*/
public void showSuccess(boolean isShowTop) {
bgColor = COLOR_SUCCESS;
messageColor = COLOR_MESSAGE;
actionTextColor = COLOR_MESSAGE;
show();
show(isShowTop);
}
/**
* Show the snackbar with warning style.
*/
public void showWarning() {
showWarning(false);
}
/**
* Show the snackbar with warning style.
*
* @param isShowTop True to show the snackbar on the top, false otherwise.
*/
public void showWarning(boolean isShowTop) {
bgColor = COLOR_WARNING;
messageColor = COLOR_MESSAGE;
actionTextColor = COLOR_MESSAGE;
show();
show(isShowTop);
}
/**
* Show the snackbar with error style.
*/
public void showError() {
showError(false);
}
/**
* Show the snackbar with error style.
*
* @param isShowTop True to show the snackbar on the top, false otherwise.
*/
public void showError(boolean isShowTop) {
bgColor = COLOR_ERROR;
messageColor = COLOR_MESSAGE;
actionTextColor = COLOR_MESSAGE;
show();
show(isShowTop);
}
/**
......@@ -305,4 +367,29 @@ public final class SnackbarUtils {
layout.addView(child, params);
}
}
private static ViewGroup findSuitableParentCopyFromSnackbar(View view) {
ViewGroup fallback = null;
do {
if (view instanceof CoordinatorLayout) {
return (ViewGroup) view;
}
if (view instanceof FrameLayout) {
if (view.getId() == android.R.id.content) {
return (ViewGroup) view;
}
fallback = (ViewGroup) view;
}
if (view != null) {
ViewParent parent = view.getParent();
view = parent instanceof View ? (View) parent : null;
}
} while (view != null);
return fallback;
}
}
......@@ -248,36 +248,19 @@ public final class UiMessageUtils implements Handler.Callback {
}
public int getId() {
isUiThread();
return mMessage.what;
}
public Object getObject() {
isUiThread();
return mMessage.obj;
}
private void isUiThread() {
if (null == mMessage) {
throw new IllegalStateException("You can't use LocalMessage instance from a non-UI thread. " +
"Extract the data from LocalMessage and don't hold a reference to it outside of handleMessage()");
}
}
@Override
public String toString() {
isUiThread();
final StringBuilder b = new StringBuilder();
b.append("{ id=");
b.append(getId());
if (getObject() != null) {
b.append(" obj=");
b.append(getObject());
}
b.append(" }");
return b.toString();
return "{ " +
"id=" + getId() +
", obj=" + getObject() +
" }";
}
}
......
......@@ -16,6 +16,9 @@ import android.text.TextUtils;
import android.util.Log;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
......@@ -67,6 +70,18 @@ public final class UriUtils {
* @return file
*/
public static File uri2File(@NonNull final Uri uri) {
File file = uri2FileReal(uri);
if (file != null) return file;
return copyUri2Cache(uri);
}
/**
* Uri to file.
*
* @param uri The uri.
* @return file
*/
private static File uri2FileReal(@NonNull final Uri uri) {
Log.d("UriUtils", uri.toString());
String authority = uri.getAuthority();
String scheme = uri.getScheme();
......@@ -144,19 +159,31 @@ public final class UriUtils {
}// end 1_0
else if ("com.android.providers.downloads.documents".equals(authority)) {
final String id = DocumentsContract.getDocumentId(uri);
if (!TextUtils.isEmpty(id)) {
if (TextUtils.isEmpty(id)) {
Log.d("UriUtils", uri.toString() + " parse failed(id is null). -> 1_1");
return null;
}
if (id.startsWith("raw:")) {
return new File(id.substring(4));
}
String[] contentUriPrefixesToTry = new String[]{
"content://downloads/public_downloads",
"content://downloads/all_downloads",
"content://downloads/my_downloads"
};
for (String contentUriPrefix : contentUriPrefixesToTry) {
Uri contentUri = ContentUris.withAppendedId(Uri.parse(contentUriPrefix), Long.valueOf(id));
try {
final Uri contentUri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"),
Long.valueOf(id)
);
return getFileFromUri(contentUri, "1_1");
} catch (NumberFormatException e) {
if (id.startsWith("raw:")) {
return new File(id.substring(4));
File file = getFileFromUri(contentUri, "1_1");
if (file != null) {
return file;
}
} catch (Exception ignore) {
}
}
Log.d("UriUtils", uri.toString() + " parse failed. -> 1_1");
return null;
}// end 1_1
......@@ -214,6 +241,11 @@ public final class UriUtils {
File fileDir = Environment.getExternalStorageDirectory();
return new File(fileDir, path.substring("/QQBrowser".length(), path.length()));
}
} else if ("com.huawei.hidisk.fileprovider".equals(uri.getAuthority())) {
String path = uri.getPath();
if (!TextUtils.isEmpty(path)) {
return new File(path.replace("/root", ""));
}
}
final Cursor cursor = Utils.getApp().getContentResolver().query(
......@@ -242,4 +274,38 @@ public final class UriUtils {
cursor.close();
}
}
private static File copyUri2Cache(Uri uri) {
Log.d("UriUtils", "copyUri2Cache() called");
InputStream is = uri2InputStream(uri);
File file = new File(Utils.getApp().getCacheDir(), "" + System.currentTimeMillis());
UtilsBridge.writeFileFromIS(file.getAbsolutePath(), is);
return file;
}
/**
* uri to input stream.
*
* @param uri The uri.
* @return the input stream
*/
public static InputStream uri2InputStream(Uri uri) {
StringBuilder stringBuilder = new StringBuilder();
InputStream is = null;
try {
is = Utils.getApp().getContentResolver().openInputStream(uri);
return is;
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
......@@ -42,9 +42,20 @@ public final class Utils {
* @param app application
*/
public static void init(final Application app) {
if (sApp != null) return;
if (app == null) {
Log.e("Utils", "app is null.");
return;
}
if (sApp == null) {
sApp = app;
UtilsBridge.init(sApp);
UtilsBridge.preLoad();
return;
}
if (sApp.equals(app)) return;
UtilsBridge.unInit(sApp);
sApp = app;
UtilsBridge.init();
UtilsBridge.init(sApp);
}
/**
......
......@@ -40,9 +40,13 @@ final class UtilsActivityLifecycleImpl implements Application.ActivityLifecycleC
private int mConfigCount = 0;
private boolean mIsBackground = false;
void init() {
void init(Application app) {
app.registerActivityLifecycleCallbacks(this);
}
void unInit(Application app) {
mActivityList.clear();
Utils.getApp().registerActivityLifecycleCallbacks(this);
app.unregisterActivityLifecycleCallbacks(this);
}
Activity getTopActivity() {
......
......@@ -35,8 +35,15 @@ import static android.Manifest.permission.CALL_PHONE;
*/
class UtilsBridge {
static void init() {
UtilsActivityLifecycleImpl.INSTANCE.init();
static void init(Application app) {
UtilsActivityLifecycleImpl.INSTANCE.init(app);
}
static void unInit(Application app) {
UtilsActivityLifecycleImpl.INSTANCE.unInit(app);
}
static void preLoad() {
preLoad(AdaptScreenUtils.getPreLoadRunnable());
}
......
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="ActivityTranslucent" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:background">@android:color/transparent</item>
<item name="android:colorBackgroundCacheHint">@null</item>
<item name="android:windowActionBar">false</item>
<item name="android:windowNoTitle">true</item>
<item name="android:backgroundDimEnabled">false</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowAnimationStyle">@null</item>
<item name="android:windowDisablePreview">true</item>
</style>
</resources>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<paths>
<root-path
name="root"
name="root_path"
path="" />
<files-path
......@@ -23,4 +23,8 @@
<external-cache-path
name="external_cache_path"
path="." />
<external-media-path
name="external_media_path"
path="." />
</paths>
\ No newline at end of file
......@@ -6,7 +6,7 @@
组件化方案中各业务是相互隔离的,所以两个业务模块要通信的话,就需要通过路由或者接口下沉来完成,业界的方案都无法与 **[AucFrame](https://github.com/Blankj/AucFrameTemplate)** 完美融合,所以我就只好自己动手来完成一个更方便、精简、完美的 `ApiUtils`
它功能类似 SPI,但比 SPI 更适合于 Android,而且功能更强大,这里也吐槽下 Android 中使用 ServiceLoader 会引起的 ANR 的问题,虽然 kotlinx 中 R8 加入了 FastServiceLoader,但如果不用 kotlinx 的项目还是无法解决 ANR 的问题;我也试过把 AutoService 中生成的内容放入到 assets 文件中,仅仅只有些许提升,还是无法从根上解决问题
它功能类似 SPI,但比 SPI 更适合于 Android,而且功能更强大,这里也吐槽下 Android 中使用 ServiceLoader 会引起的 ANR 的问题,虽然 kotlinx 中 R8 加入了 FastServiceLoader,但如果不用 kotlinx 的项目还是无法解决 ANR 的问题;解决方案肯定是有的,这里就不展开讨论这个问题了
**[AucFrame](https://github.com/Blankj/AucFrameTemplate)** 架构中,我们可以通过 `ApiUtils` 来自由调用各模块的 `apis`,各业务通过对外提供的 `export` 模块来供其他业务方使用,自身只需要实现自身的 `export` 中的 `apis` 即可。其 **[AucFrame](https://github.com/Blankj/AucFrameTemplate)** 的架构图如下所示:
......@@ -63,6 +63,19 @@ android {
当然,如果你项目是开启混淆的话,全量引入 **[AndroidUtilCode](https://github.com/Blankj/AndroidUtilCode)** 也是可以的,混淆会帮你去除未使用到的类和方法。
api 完整的 DSL 如下所示:
```groovy
api {
abortOnError boolean // api 扫描有问题是否终止编译,默认 true
apiUtilsClass String // ApiUtils 类的路径,默认 'com.blankj.utilcode.util.ApiUtils'
onlyScanLibRegex String// 设置 transform 只扫描库的正则,比如 auc 配置的 '^([:]|(com\\.blankj)).+$',
// [:] 表示扫描本地 module,因为本地 module 在 transform 中的 jar 包名是以 : 开头的,比如 :feature:utilcode:feature_utilcode_pkg,
// com.blankj 表示扫描远端仓库以 com.blankj 开头的,比如 com.blankj:utilcode:xx
jumpScanLibRegex String// 和 onlyScanLibRegex 类似,不过是指要跳过哪些扫描的,和 onlyScanLibRegex 不能共存,onlyScanLibRegex 优先级更高
}
```
### 例子
插件和依赖都配置完毕,下面就让我们在项目中使用吧,举一个实际的例子,比如 `login` 模块中存在 `LoginActivity``main` 模块存在 `MainActivity`,这两个模块是平行的关系,两者互不依赖,现在我们通过 `ApiUtils``LoginActivity` 来启动 `MainActivity`,在 **[AucFrame](https://github.com/Blankj/AucFrameTemplate)** 中每个业务模块下都有 `export` 模块,类似于你们自己项目中的底层公共模块,因为是 `login` 来调用 `main` 模块,所以是 `mian` 模块需要提供 `api` 来供 `login` 来调,所以我们在 `main``export` 中加入一个继承自 `ApiUtils.BaseApi` 的抽象类 `MainApi`,并添加启动 `MainActivity` 的抽象方法,我们把方法搞得更复杂点,带上自定义的参数和返回值,具体如下所示:
......
......@@ -61,6 +61,19 @@ android {
当然,如果你项目是开启混淆的话,全量引入 **[AndroidUtilCode](https://github.com/Blankj/AndroidUtilCode)** 也是可以的,混淆会帮你去除未使用到的类和方法。
bus 完整的 DSL 如下所示:
```groovy
bus {
abortOnError boolean // bus 扫描有问题是否终止编译,默认 true
busUtilsClass String // BusUtils 类的路径,默认 'com.blankj.utilcode.util.BusUtils'
onlyScanLibRegex String// 设置 transform 只扫描库的正则,比如 auc 配置的 '^([:]|(com\\.blankj)).+$',
// [:] 表示扫描本地 module,因为本地 module 在 transform 中的 jar 包名是以 : 开头的,比如 :feature:utilcode:feature_utilcode_pkg,
// com.blankj 表示扫描远端仓库以 com.blankj 开头的,比如 com.blankj:utilcode:xx
jumpScanLibRegex String// 和 onlyScanLibRegex 类似,不过是指要跳过哪些扫描的,和 onlyScanLibRegex 不能共存,onlyScanLibRegex 优先级更高
}
```
好了,插件和依赖都配置完毕,下面介绍基本使用。
### 基本使用
......@@ -412,7 +425,7 @@ public void compareUnregister10000Times() {
}
```
修改 `oneParamFun` 为两个参数的话,为了确保项目不会因为 `BusUtils` 在运行时崩溃,`api` 插件会使其在编译时就不过,此时 `__bus__.json` 文件如下所示,提示你参数个数不对:
修改 `oneParamFun` 为两个参数的话,为了确保项目不会因为 `BusUtils` 在运行时崩溃,`bus` 插件会使其在编译时就不过,此时 `__bus__.json` 文件如下所示,提示你参数个数不对:
```json
{
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册