Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
S
Sobot_module_Dev
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
sobot_android
Sobot_module_Dev
Commits
fffb7f32
Commit
fffb7f32
authored
Dec 06, 2023
by
zhengnw@sobot.com
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
widget 1.1.3 添加livedata 事件总线
parent
7a5ea746
Hide whitespace changes
Inline
Side-by-side
Showing
27 changed files
with
1838 additions
and
1 deletion
+1838
-1
sobot-widget-publish-mavencentral.gradle
sobot_widget/sobot-widget-publish-mavencentral.gradle
+1
-1
ExternalLiveData.java
...rc/main/java/android/arch/lifecycle/ExternalLiveData.java
+81
-0
SobotLiveEventBus.java
.../java/com/sobot/widget/livedatabus/SobotLiveEventBus.java
+70
-0
Config.java
...c/main/java/com/sobot/widget/livedatabus/core/Config.java
+69
-0
Console.java
.../main/java/com/sobot/widget/livedatabus/core/Console.java
+19
-0
LiveEvent.java
...ain/java/com/sobot/widget/livedatabus/core/LiveEvent.java
+6
-0
LiveEventBusCore.java
...a/com/sobot/widget/livedatabus/core/LiveEventBusCore.java
+613
-0
Observable.java
...in/java/com/sobot/widget/livedatabus/core/Observable.java
+114
-0
ObservableConfig.java
...a/com/sobot/widget/livedatabus/core/ObservableConfig.java
+31
-0
IpcConfig.java
...om/sobot/widget/livedatabus/ipc/annotation/IpcConfig.java
+15
-0
IpcConst.java
...ava/com/sobot/widget/livedatabus/ipc/consts/IpcConst.java
+11
-0
BooleanProcessor.java
...m/sobot/widget/livedatabus/ipc/core/BooleanProcessor.java
+21
-0
DoubleProcessor.java
...om/sobot/widget/livedatabus/ipc/core/DoubleProcessor.java
+22
-0
FloatProcessor.java
...com/sobot/widget/livedatabus/ipc/core/FloatProcessor.java
+22
-0
IntProcessor.java
...a/com/sobot/widget/livedatabus/ipc/core/IntProcessor.java
+22
-0
LongProcessor.java
.../com/sobot/widget/livedatabus/ipc/core/LongProcessor.java
+22
-0
ParcelableProcessor.java
...obot/widget/livedatabus/ipc/core/ParcelableProcessor.java
+23
-0
Processor.java
...java/com/sobot/widget/livedatabus/ipc/core/Processor.java
+10
-0
ProcessorManager.java
...m/sobot/widget/livedatabus/ipc/core/ProcessorManager.java
+126
-0
SerializableProcessor.java
...ot/widget/livedatabus/ipc/core/SerializableProcessor.java
+24
-0
StringProcessor.java
...om/sobot/widget/livedatabus/ipc/core/StringProcessor.java
+21
-0
LebIpcReceiver.java
...sobot/widget/livedatabus/ipc/receiver/LebIpcReceiver.java
+27
-0
DefaultLogger.java
...va/com/sobot/widget/livedatabus/logger/DefaultLogger.java
+39
-0
Logger.java
...main/java/com/sobot/widget/livedatabus/logger/Logger.java
+10
-0
LoggerManager.java
...va/com/sobot/widget/livedatabus/logger/LoggerManager.java
+42
-0
AppUtils.java
...ain/java/com/sobot/widget/livedatabus/utils/AppUtils.java
+367
-0
ThreadUtils.java
.../java/com/sobot/widget/livedatabus/utils/ThreadUtils.java
+10
-0
No files found.
sobot_widget/sobot-widget-publish-mavencentral.gradle
View file @
fffb7f32
...
...
@@ -13,7 +13,7 @@ ext {
PUBLISH_GROUP_ID
=
"com.sobot.library"
//项目包名
PUBLISH_ARTIFACT_ID
=
'widget'
//项目名
// PUBLISH_ARTIFACT_ID = 'widget_x' //项目名
PUBLISH_VERSION
=
'1.1.
2
'
//版本号
PUBLISH_VERSION
=
'1.1.
3
'
//版本号
}
...
...
sobot_widget/src/main/java/android/arch/lifecycle/ExternalLiveData.java
0 → 100644
View file @
fffb7f32
package
android
.
arch
.
lifecycle
;
import
static
android
.
arch
.
lifecycle
.
Lifecycle
.
State
.
CREATED
;
import
static
android
.
arch
.
lifecycle
.
Lifecycle
.
State
.
DESTROYED
;
import
android.support.annotation.NonNull
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.Method
;
public
class
ExternalLiveData
<
T
>
extends
MutableLiveData
<
T
>
{
public
static
final
int
START_VERSION
=
LiveData
.
START_VERSION
;
@Override
public
void
observe
(
@NonNull
LifecycleOwner
owner
,
@NonNull
Observer
<
T
>
observer
)
{
if
(
owner
.
getLifecycle
().
getCurrentState
()
==
DESTROYED
)
{
// ignore
return
;
}
try
{
//use ExternalLifecycleBoundObserver instead of LifecycleBoundObserver
LifecycleBoundObserver
wrapper
=
new
ExternalLifecycleBoundObserver
(
owner
,
observer
);
LifecycleBoundObserver
existing
=
(
LifecycleBoundObserver
)
callMethodPutIfAbsent
(
observer
,
wrapper
);
if
(
existing
!=
null
&&
!
existing
.
isAttachedTo
(
owner
))
{
throw
new
IllegalArgumentException
(
"Cannot add the same observer"
+
" with different lifecycles"
);
}
if
(
existing
!=
null
)
{
return
;
}
owner
.
getLifecycle
().
addObserver
(
wrapper
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
}
public
int
getVersion
()
{
return
super
.
getVersion
();
}
/**
* determine when the observer is active, means the observer can receive message
* the default value is CREATED, means if the observer's state is above create,
* for example, the onCreate() of activity is called
* you can change this value to CREATED/STARTED/RESUMED
* determine on witch state, you can receive message
*
* @return Lifecycle.State
*/
protected
Lifecycle
.
State
observerActiveLevel
()
{
return
CREATED
;
}
class
ExternalLifecycleBoundObserver
extends
LifecycleBoundObserver
{
ExternalLifecycleBoundObserver
(
@NonNull
LifecycleOwner
owner
,
Observer
<
T
>
observer
)
{
super
(
owner
,
observer
);
}
@Override
boolean
shouldBeActive
()
{
return
mOwner
.
getLifecycle
().
getCurrentState
().
isAtLeast
(
observerActiveLevel
());
}
}
private
Object
getFieldObservers
()
throws
Exception
{
Field
fieldObservers
=
LiveData
.
class
.
getDeclaredField
(
"mObservers"
);
fieldObservers
.
setAccessible
(
true
);
return
fieldObservers
.
get
(
this
);
}
private
Object
callMethodPutIfAbsent
(
Object
observer
,
Object
wrapper
)
throws
Exception
{
Object
mObservers
=
getFieldObservers
();
Class
<?>
classOfSafeIterableMap
=
mObservers
.
getClass
();
Method
putIfAbsent
=
classOfSafeIterableMap
.
getDeclaredMethod
(
"putIfAbsent"
,
Object
.
class
,
Object
.
class
);
putIfAbsent
.
setAccessible
(
true
);
return
putIfAbsent
.
invoke
(
mObservers
,
observer
,
wrapper
);
}
}
sobot_widget/src/main/java/com/sobot/widget/livedatabus/SobotLiveEventBus.java
0 → 100644
View file @
fffb7f32
package
com
.
sobot
.
widget
.
livedatabus
;
import
android.support.annotation.NonNull
;
import
com.sobot.widget.livedatabus.core.Config
;
import
com.sobot.widget.livedatabus.core.LiveEvent
;
import
com.sobot.widget.livedatabus.core.LiveEventBusCore
;
import
com.sobot.widget.livedatabus.core.Observable
;
import
com.sobot.widget.livedatabus.core.ObservableConfig
;
public
class
SobotLiveEventBus
{
/**
* get observable by key with type
*
* @param key key
* @param type type
* @param <T> T
* @return Observable
*/
public
static
<
T
>
Observable
<
T
>
get
(
@NonNull
String
key
,
@NonNull
Class
<
T
>
type
)
{
return
LiveEventBusCore
.
get
().
with
(
key
,
type
);
}
/**
* get observable by key
*
* @param key String
* @param <T> T
* @return Observable
*/
public
static
<
T
>
Observable
<
T
>
get
(
@NonNull
String
key
)
{
return
(
Observable
<
T
>)
get
(
key
,
Object
.
class
);
}
/**
* get observable from eventType
*
* @param eventType Class
* @param <T> T
* @return Observable
*/
public
static
<
T
extends
LiveEvent
>
Observable
<
T
>
get
(
@NonNull
Class
<
T
>
eventType
)
{
return
get
(
eventType
.
getName
(),
eventType
);
}
/**
* use the inner class Config to set params
* first of all, call config to get the Config instance
* then, call the method of Config to config LiveEventBus
* call this method in Application.onCreate
* @return Config
*/
public
static
Config
config
()
{
return
LiveEventBusCore
.
get
().
config
();
}
/**
* use the inner class Config to set params
* first of all, call config to get the Config instance
* then, call the method of Config to config LiveEventBus
* call this method in Application.onCreate
* @param key String
* @return Config
*/
public
static
ObservableConfig
config
(
@NonNull
String
key
)
{
return
LiveEventBusCore
.
get
().
config
(
key
);
}
}
\ No newline at end of file
sobot_widget/src/main/java/com/sobot/widget/livedatabus/core/Config.java
0 → 100644
View file @
fffb7f32
package
com
.
sobot
.
widget
.
livedatabus
.
core
;
import
android.content.Context
;
import
android.support.annotation.NonNull
;
import
com.sobot.widget.livedatabus.logger.Logger
;
import
com.sobot.widget.livedatabus.utils.AppUtils
;
public
class
Config
{
/**
* lifecycleObserverAlwaysActive
* set if then observer can always receive message
* true: observer can always receive message
* false: observer can only receive message when resumed
*
* @param active boolean
* @return Config
*/
public
Config
lifecycleObserverAlwaysActive
(
boolean
active
)
{
LiveEventBusCore
.
get
().
setLifecycleObserverAlwaysActive
(
active
);
return
this
;
}
/**
* @param clear boolean
* @return true: clear livedata when no observer observe it
* false: not clear livedata unless app was killed
*/
public
Config
autoClear
(
boolean
clear
)
{
LiveEventBusCore
.
get
().
setAutoClear
(
clear
);
return
this
;
}
/**
* config broadcast
* only if you called this method, you can use broadcastValue() to send broadcast message
*
* @param context Context
* @return Config
*/
public
Config
setContext
(
Context
context
)
{
AppUtils
.
init
(
context
);
LiveEventBusCore
.
get
().
registerReceiver
();
return
this
;
}
/**
* setLogger, if not set, use DefaultLogger
*
* @param logger Logger
* @return Config
*/
public
Config
setLogger
(
@NonNull
Logger
logger
)
{
LiveEventBusCore
.
get
().
setLogger
(
logger
);
return
this
;
}
/**
* set logger enable or disable, default enable
*
* @param enable boolean
* @return Config
*/
public
Config
enableLogger
(
boolean
enable
)
{
LiveEventBusCore
.
get
().
enableLogger
(
enable
);
return
this
;
}
}
sobot_widget/src/main/java/com/sobot/widget/livedatabus/core/Console.java
0 → 100644
View file @
fffb7f32
package
com
.
sobot
.
widget
.
livedatabus
.
core
;
/**
* 调试信息控制台
*/
public
final
class
Console
{
private
Console
()
{
}
/**
* 获取控制台信息
*
* @return 调试信息
*/
public
static
String
getInfo
()
{
return
LiveEventBusCore
.
get
().
console
.
getConsoleInfo
();
}
}
sobot_widget/src/main/java/com/sobot/widget/livedatabus/core/LiveEvent.java
0 → 100644
View file @
fffb7f32
package
com
.
sobot
.
widget
.
livedatabus
.
core
;
import
java.io.Serializable
;
public
interface
LiveEvent
extends
Serializable
{
}
sobot_widget/src/main/java/com/sobot/widget/livedatabus/core/LiveEventBusCore.java
0 → 100644
View file @
fffb7f32
package
com
.
sobot
.
widget
.
livedatabus
.
core
;
import
android.app.Application
;
import
android.arch.lifecycle.ExternalLiveData
;
import
android.arch.lifecycle.Lifecycle
;
import
android.arch.lifecycle.LifecycleOwner
;
import
android.arch.lifecycle.LiveData
;
import
android.arch.lifecycle.Observer
;
import
android.content.Intent
;
import
android.content.IntentFilter
;
import
android.os.Build
;
import
android.os.Handler
;
import
android.os.Looper
;
import
android.support.annotation.MainThread
;
import
android.support.annotation.NonNull
;
import
android.support.annotation.Nullable
;
import
com.sobot.widget.livedatabus.ipc.consts.IpcConst
;
import
com.sobot.widget.livedatabus.ipc.core.ProcessorManager
;
import
com.sobot.widget.livedatabus.ipc.receiver.LebIpcReceiver
;
import
com.sobot.widget.livedatabus.logger.DefaultLogger
;
import
com.sobot.widget.livedatabus.logger.Logger
;
import
com.sobot.widget.livedatabus.logger.LoggerManager
;
import
com.sobot.widget.livedatabus.utils.AppUtils
;
import
com.sobot.widget.livedatabus.utils.ThreadUtils
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.Method
;
import
java.util.HashMap
;
import
java.util.Map
;
import
java.util.logging.Level
;
/**
* LiveEventBusCore
*/
public
final
class
LiveEventBusCore
{
/**
* 单例模式实现
*/
private
static
class
SingletonHolder
{
private
static
final
LiveEventBusCore
DEFAULT_BUS
=
new
LiveEventBusCore
();
}
public
static
LiveEventBusCore
get
()
{
return
SingletonHolder
.
DEFAULT_BUS
;
}
/**
* 存放LiveEvent
*/
private
final
Map
<
String
,
LiveEvent
<
Object
>>
bus
;
/**
* 可配置的项
*/
private
final
Config
config
=
new
Config
();
private
boolean
lifecycleObserverAlwaysActive
;
private
boolean
autoClear
;
private
LoggerManager
logger
;
private
final
Map
<
String
,
ObservableConfig
>
observableConfigs
;
/**
* 跨进程通信
*/
private
LebIpcReceiver
receiver
;
private
boolean
isRegisterReceiver
=
false
;
/**
* 调试
*/
final
InnerConsole
console
=
new
InnerConsole
();
private
LiveEventBusCore
()
{
bus
=
new
HashMap
<>();
observableConfigs
=
new
HashMap
<>();
lifecycleObserverAlwaysActive
=
true
;
autoClear
=
false
;
logger
=
new
LoggerManager
(
new
DefaultLogger
());
receiver
=
new
LebIpcReceiver
();
registerReceiver
();
}
public
synchronized
<
T
>
Observable
<
T
>
with
(
String
key
,
Class
<
T
>
type
)
{
if
(!
bus
.
containsKey
(
key
))
{
bus
.
put
(
key
,
new
LiveEvent
<>(
key
));
}
return
(
Observable
<
T
>)
bus
.
get
(
key
);
}
/**
* use the class Config to set params
* first of all, call config to get the Config instance
* then, call the method of Config to config LiveEventBus
* call this method in Application.onCreate
* @return Config
*/
public
Config
config
()
{
return
config
;
}
public
ObservableConfig
config
(
String
key
)
{
if
(!
observableConfigs
.
containsKey
(
key
))
{
observableConfigs
.
put
(
key
,
new
ObservableConfig
());
}
return
observableConfigs
.
get
(
key
);
}
void
setLogger
(
@NonNull
Logger
logger
)
{
this
.
logger
.
setLogger
(
logger
);
}
void
enableLogger
(
boolean
enable
)
{
this
.
logger
.
setEnable
(
enable
);
}
void
registerReceiver
()
{
if
(
isRegisterReceiver
)
{
return
;
}
Application
application
=
AppUtils
.
getApp
();
if
(
application
!=
null
)
{
IntentFilter
intentFilter
=
new
IntentFilter
();
intentFilter
.
addAction
(
IpcConst
.
ACTION
);
application
.
registerReceiver
(
receiver
,
intentFilter
);
isRegisterReceiver
=
true
;
}
}
void
setLifecycleObserverAlwaysActive
(
boolean
lifecycleObserverAlwaysActive
)
{
this
.
lifecycleObserverAlwaysActive
=
lifecycleObserverAlwaysActive
;
}
void
setAutoClear
(
boolean
autoClear
)
{
this
.
autoClear
=
autoClear
;
}
private
class
LiveEvent
<
T
>
implements
Observable
<
T
>
{
@NonNull
private
final
String
key
;
private
final
LifecycleLiveData
<
T
>
liveData
;
private
final
Map
<
Observer
,
ObserverWrapper
<
T
>>
observerMap
=
new
HashMap
<>();
private
final
Handler
mainHandler
=
new
Handler
(
Looper
.
getMainLooper
());
LiveEvent
(
@NonNull
String
key
)
{
this
.
key
=
key
;
this
.
liveData
=
new
LifecycleLiveData
<>(
key
);
}
/**
* 进程内发送消息
*
* @param value 发送的消息
*/
@Override
public
void
post
(
T
value
)
{
if
(
ThreadUtils
.
isMainThread
())
{
postInternal
(
value
);
}
else
{
mainHandler
.
post
(
new
PostValueTask
(
value
));
}
}
/**
* App内发送消息,跨进程使用
*
* @param value 发送的消息
*/
@Override
public
void
postAcrossProcess
(
T
value
)
{
broadcast
(
value
,
false
,
true
);
}
/**
* App之间发送消息
*
* @param value 发送的消息
*/
@Override
public
void
postAcrossApp
(
T
value
)
{
broadcast
(
value
,
false
,
false
);
}
/**
* 进程内发送消息,延迟发送
*
* @param value 发送的消息
* @param delay 延迟毫秒数
*/
@Override
public
void
postDelay
(
T
value
,
long
delay
)
{
mainHandler
.
postDelayed
(
new
PostValueTask
(
value
),
delay
);
}
/**
* 进程内发送消息,延迟发送,带生命周期
* 如果延时发送消息的时候sender处于非激活状态,消息取消发送
*
* @param owner 消息发送者
* @param value 发送的消息
* @param delay 延迟毫秒数
*/
@Override
public
void
postDelay
(
LifecycleOwner
owner
,
final
T
value
,
long
delay
)
{
mainHandler
.
postDelayed
(
new
PostLifeValueTask
(
value
,
owner
),
delay
);
}
/**
* 进程内发送消息
* 强制接收到消息的顺序和发送顺序一致
*
* @param value 发送的消息
*/
@Override
public
void
postOrderly
(
T
value
)
{
mainHandler
.
post
(
new
PostValueTask
(
value
));
}
/**
* App之间发送消息
*
* @param value 发送的消息
*/
@Override
@Deprecated
public
void
broadcast
(
T
value
)
{
broadcast
(
value
,
false
,
false
);
}
/**
* 以广播的形式发送一个消息
* 需要跨进程、跨APP发送消息的时候调用该方法
*
* @param value 发送的消息
* @param foreground true:前台广播、false:后台广播
* @param onlyInApp true:只在APP内有效、false:全局有效
*/
@Override
public
void
broadcast
(
final
T
value
,
final
boolean
foreground
,
final
boolean
onlyInApp
)
{
if
(
AppUtils
.
getApp
()
!=
null
)
{
if
(
ThreadUtils
.
isMainThread
())
{
broadcastInternal
(
value
,
foreground
,
onlyInApp
);
}
else
{
mainHandler
.
post
(
new
Runnable
()
{
@Override
public
void
run
()
{
broadcastInternal
(
value
,
foreground
,
onlyInApp
);
}
});
}
}
else
{
post
(
value
);
}
}
/**
* 注册一个Observer,生命周期感知,自动取消订阅
*
* @param owner LifecycleOwner
* @param observer 观察者
*/
@Override
public
void
observe
(
@NonNull
final
LifecycleOwner
owner
,
@NonNull
final
Observer
<
T
>
observer
)
{
if
(
ThreadUtils
.
isMainThread
())
{
observeInternal
(
owner
,
observer
);
}
else
{
mainHandler
.
post
(
new
Runnable
()
{
@Override
public
void
run
()
{
observeInternal
(
owner
,
observer
);
}
});
}
}
/**
* 注册一个Observer,生命周期感知,自动取消订阅
* 如果之前有消息发送,可以在注册时收到消息(消息同步)
*
* @param owner LifecycleOwner
* @param observer 观察者
*/
@Override
public
void
observeSticky
(
@NonNull
final
LifecycleOwner
owner
,
@NonNull
final
Observer
<
T
>
observer
)
{
if
(
ThreadUtils
.
isMainThread
())
{
observeStickyInternal
(
owner
,
observer
);
}
else
{
mainHandler
.
post
(
new
Runnable
()
{
@Override
public
void
run
()
{
observeStickyInternal
(
owner
,
observer
);
}
});
}
}
/**
* 注册一个Observer,需手动解除绑定
*
* @param observer 观察者
*/
@Override
public
void
observeForever
(
@NonNull
final
Observer
<
T
>
observer
)
{
if
(
ThreadUtils
.
isMainThread
())
{
observeForeverInternal
(
observer
);
}
else
{
mainHandler
.
post
(
new
Runnable
()
{
@Override
public
void
run
()
{
observeForeverInternal
(
observer
);
}
});
}
}
/**
* 注册一个Observer,需手动解除绑定
* 如果之前有消息发送,可以在注册时收到消息(消息同步)
*
* @param observer 观察者
*/
@Override
public
void
observeStickyForever
(
@NonNull
final
Observer
<
T
>
observer
)
{
if
(
ThreadUtils
.
isMainThread
())
{
observeStickyForeverInternal
(
observer
);
}
else
{
mainHandler
.
post
(
new
Runnable
()
{
@Override
public
void
run
()
{
observeStickyForeverInternal
(
observer
);
}
});
}
}
/**
* 通过observeForever或observeStickyForever注册的,需要调用该方法取消订阅
*
* @param observer 观察者
*/
@Override
public
void
removeObserver
(
@NonNull
final
Observer
<
T
>
observer
)
{
if
(
ThreadUtils
.
isMainThread
())
{
removeObserverInternal
(
observer
);
}
else
{
mainHandler
.
post
(
new
Runnable
()
{
@Override
public
void
run
()
{
removeObserverInternal
(
observer
);
}
});
}
}
@MainThread
private
void
postInternal
(
T
value
)
{
logger
.
log
(
Level
.
INFO
,
"post: "
+
value
+
" with key: "
+
key
);
liveData
.
setValue
(
value
);
}
@MainThread
private
void
broadcastInternal
(
T
value
,
boolean
foreground
,
boolean
onlyInApp
)
{
logger
.
log
(
Level
.
INFO
,
"broadcast: "
+
value
+
" foreground: "
+
foreground
+
" with key: "
+
key
);
Application
application
=
AppUtils
.
getApp
();
if
(
application
==
null
)
{
logger
.
log
(
Level
.
WARNING
,
"application is null, you can try setContext() when config"
);
return
;
}
Intent
intent
=
new
Intent
(
IpcConst
.
ACTION
);
if
(
foreground
&&
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
JELLY_BEAN
)
{
intent
.
addFlags
(
Intent
.
FLAG_RECEIVER_FOREGROUND
);
}
if
(
onlyInApp
)
{
intent
.
setPackage
(
application
.
getPackageName
());
}
intent
.
putExtra
(
IpcConst
.
KEY
,
key
);
boolean
handle
=
ProcessorManager
.
getManager
().
writeTo
(
intent
,
value
);
try
{
if
(
handle
)
{
application
.
sendBroadcast
(
intent
);
}
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
}
@MainThread
private
void
observeInternal
(
@NonNull
LifecycleOwner
owner
,
@NonNull
Observer
<
T
>
observer
)
{
ObserverWrapper
<
T
>
observerWrapper
=
new
ObserverWrapper
<>(
observer
);
observerWrapper
.
preventNextEvent
=
liveData
.
getVersion
()
>
ExternalLiveData
.
START_VERSION
;
liveData
.
observe
(
owner
,
observerWrapper
);
logger
.
log
(
Level
.
INFO
,
"observe observer: "
+
observerWrapper
+
"("
+
observer
+
")"
+
" on owner: "
+
owner
+
" with key: "
+
key
);
}
@MainThread
private
void
observeStickyInternal
(
@NonNull
LifecycleOwner
owner
,
@NonNull
Observer
<
T
>
observer
)
{
ObserverWrapper
<
T
>
observerWrapper
=
new
ObserverWrapper
<>(
observer
);
liveData
.
observe
(
owner
,
observerWrapper
);
logger
.
log
(
Level
.
INFO
,
"observe sticky observer: "
+
observerWrapper
+
"("
+
observer
+
")"
+
" on owner: "
+
owner
+
" with key: "
+
key
);
}
@MainThread
private
void
observeForeverInternal
(
@NonNull
Observer
<
T
>
observer
)
{
ObserverWrapper
<
T
>
observerWrapper
=
new
ObserverWrapper
<>(
observer
);
observerWrapper
.
preventNextEvent
=
liveData
.
getVersion
()
>
ExternalLiveData
.
START_VERSION
;
observerMap
.
put
(
observer
,
observerWrapper
);
liveData
.
observeForever
(
observerWrapper
);
logger
.
log
(
Level
.
INFO
,
"observe forever observer: "
+
observerWrapper
+
"("
+
observer
+
")"
+
" with key: "
+
key
);
}
@MainThread
private
void
observeStickyForeverInternal
(
@NonNull
Observer
<
T
>
observer
)
{
ObserverWrapper
<
T
>
observerWrapper
=
new
ObserverWrapper
<>(
observer
);
observerMap
.
put
(
observer
,
observerWrapper
);
liveData
.
observeForever
(
observerWrapper
);
logger
.
log
(
Level
.
INFO
,
"observe sticky forever observer: "
+
observerWrapper
+
"("
+
observer
+
")"
+
" with key: "
+
key
);
}
@MainThread
private
void
removeObserverInternal
(
@NonNull
Observer
<
T
>
observer
)
{
Observer
<
T
>
realObserver
;
if
(
observerMap
.
containsKey
(
observer
))
{
realObserver
=
observerMap
.
remove
(
observer
);
}
else
{
realObserver
=
observer
;
}
liveData
.
removeObserver
(
realObserver
);
}
private
class
LifecycleLiveData
<
T
>
extends
ExternalLiveData
<
T
>
{
private
final
String
key
;
public
LifecycleLiveData
(
String
key
)
{
this
.
key
=
key
;
}
@Override
protected
Lifecycle
.
State
observerActiveLevel
()
{
return
lifecycleObserverAlwaysActive
()
?
Lifecycle
.
State
.
CREATED
:
Lifecycle
.
State
.
STARTED
;
}
@Override
public
void
removeObserver
(
@NonNull
Observer
<
T
>
observer
)
{
super
.
removeObserver
(
observer
);
if
(
autoClear
()
&&
!
liveData
.
hasObservers
())
{
LiveEventBusCore
.
get
().
bus
.
remove
(
key
);
}
logger
.
log
(
Level
.
INFO
,
"observer removed: "
+
observer
);
}
private
boolean
lifecycleObserverAlwaysActive
()
{
if
(
observableConfigs
.
containsKey
(
key
))
{
ObservableConfig
config
=
observableConfigs
.
get
(
key
);
if
(
config
.
lifecycleObserverAlwaysActive
!=
null
)
{
return
config
.
lifecycleObserverAlwaysActive
;
}
}
return
lifecycleObserverAlwaysActive
;
}
private
boolean
autoClear
()
{
if
(
observableConfigs
.
containsKey
(
key
))
{
ObservableConfig
config
=
observableConfigs
.
get
(
key
);
if
(
config
.
autoClear
!=
null
)
{
return
config
.
autoClear
;
}
}
return
autoClear
;
}
}
private
class
PostValueTask
implements
Runnable
{
private
Object
newValue
;
public
PostValueTask
(
@NonNull
Object
newValue
)
{
this
.
newValue
=
newValue
;
}
@Override
public
void
run
()
{
postInternal
((
T
)
newValue
);
}
}
private
class
PostLifeValueTask
implements
Runnable
{
private
Object
newValue
;
private
LifecycleOwner
owner
;
public
PostLifeValueTask
(
@NonNull
Object
newValue
,
@Nullable
LifecycleOwner
owner
)
{
this
.
newValue
=
newValue
;
this
.
owner
=
owner
;
}
@Override
public
void
run
()
{
if
(
owner
!=
null
)
{
if
(
owner
.
getLifecycle
().
getCurrentState
().
isAtLeast
(
Lifecycle
.
State
.
STARTED
))
{
postInternal
((
T
)
newValue
);
}
}
}
}
}
private
class
ObserverWrapper
<
T
>
implements
Observer
<
T
>
{
@NonNull
private
final
Observer
<
T
>
observer
;
private
boolean
preventNextEvent
=
false
;
ObserverWrapper
(
@NonNull
Observer
<
T
>
observer
)
{
this
.
observer
=
observer
;
}
@Override
public
void
onChanged
(
@Nullable
T
t
)
{
if
(
preventNextEvent
)
{
preventNextEvent
=
false
;
return
;
}
logger
.
log
(
Level
.
INFO
,
"message received: "
+
t
);
try
{
observer
.
onChanged
(
t
);
}
catch
(
ClassCastException
e
)
{
logger
.
log
(
Level
.
WARNING
,
"class cast error on message received: "
+
t
,
e
);
}
catch
(
Exception
e
)
{
logger
.
log
(
Level
.
WARNING
,
"error on message received: "
+
t
,
e
);
}
}
}
class
InnerConsole
{
String
getConsoleInfo
()
{
StringBuilder
sb
=
new
StringBuilder
();
sb
.
append
(
"*********Base info*********"
).
append
(
"\n"
);
sb
.
append
(
getBaseInfo
());
sb
.
append
(
"*********Event info*********"
).
append
(
"\n"
);
sb
.
append
(
getBusInfo
());
return
sb
.
toString
();
}
String
getBaseInfo
()
{
StringBuilder
sb
=
new
StringBuilder
();
sb
.
append
(
"lifecycleObserverAlwaysActive: "
).
append
(
lifecycleObserverAlwaysActive
).
append
(
"\n"
)
.
append
(
"autoClear: "
).
append
(
autoClear
).
append
(
"\n"
)
.
append
(
"logger enable: "
).
append
(
logger
.
isEnable
()).
append
(
"\n"
)
.
append
(
"logger: "
).
append
(
logger
.
getLogger
()).
append
(
"\n"
)
.
append
(
"Receiver register: "
).
append
(
isRegisterReceiver
).
append
(
"\n"
)
.
append
(
"Application: "
).
append
(
AppUtils
.
getApp
()).
append
(
"\n"
);
return
sb
.
toString
();
}
String
getBusInfo
()
{
StringBuilder
sb
=
new
StringBuilder
();
for
(
String
key
:
bus
.
keySet
())
{
sb
.
append
(
"Event name: "
+
key
).
append
(
"\n"
);
ExternalLiveData
liveData
=
bus
.
get
(
key
).
liveData
;
sb
.
append
(
"\tversion: "
+
liveData
.
getVersion
()).
append
(
"\n"
);
sb
.
append
(
"\thasActiveObservers: "
+
liveData
.
hasActiveObservers
()).
append
(
"\n"
);
sb
.
append
(
"\thasObservers: "
+
liveData
.
hasObservers
()).
append
(
"\n"
);
sb
.
append
(
"\tActiveCount: "
+
getActiveCount
(
liveData
)).
append
(
"\n"
);
sb
.
append
(
"\tObserverCount: "
+
getObserverCount
(
liveData
)).
append
(
"\n"
);
sb
.
append
(
"\tObservers: "
).
append
(
"\n"
);
sb
.
append
(
"\t\t"
+
getObserverInfo
(
liveData
)).
append
(
"\n"
);
}
return
sb
.
toString
();
}
private
int
getActiveCount
(
LiveData
liveData
)
{
try
{
Field
field
=
LiveData
.
class
.
getDeclaredField
(
"mActiveCount"
);
field
.
setAccessible
(
true
);
return
(
int
)
field
.
get
(
liveData
);
}
catch
(
Exception
e
)
{
return
-
1
;
}
}
private
int
getObserverCount
(
LiveData
liveData
)
{
try
{
Field
field
=
LiveData
.
class
.
getDeclaredField
(
"mObservers"
);
field
.
setAccessible
(
true
);
Object
mObservers
=
field
.
get
(
liveData
);
Class
<?>
classOfSafeIterableMap
=
mObservers
.
getClass
();
Method
size
=
classOfSafeIterableMap
.
getDeclaredMethod
(
"size"
);
size
.
setAccessible
(
true
);
return
(
int
)
size
.
invoke
(
mObservers
);
}
catch
(
Exception
e
)
{
return
-
1
;
}
}
private
String
getObserverInfo
(
LiveData
liveData
)
{
try
{
Field
field
=
LiveData
.
class
.
getDeclaredField
(
"mObservers"
);
field
.
setAccessible
(
true
);
Object
mObservers
=
field
.
get
(
liveData
);
return
mObservers
.
toString
();
}
catch
(
Exception
e
)
{
return
""
;
}
}
}
}
sobot_widget/src/main/java/com/sobot/widget/livedatabus/core/Observable.java
0 → 100644
View file @
fffb7f32
package
com
.
sobot
.
widget
.
livedatabus
.
core
;
import
android.arch.lifecycle.LifecycleOwner
;
import
android.arch.lifecycle.Observer
;
import
android.support.annotation.NonNull
;
public
interface
Observable
<
T
>
{
/**
* 进程内发送消息
*
* @param value 发送的消息
*/
void
post
(
T
value
);
/**
* App内发送消息,跨进程使用
*
* @param value 发送的消息
*/
void
postAcrossProcess
(
T
value
);
/**
* App之间发送消息
*
* @param value 发送的消息
*/
void
postAcrossApp
(
T
value
);
/**
* 进程内发送消息,延迟发送
*
* @param value 发送的消息
* @param delay 延迟毫秒数
*/
void
postDelay
(
T
value
,
long
delay
);
/**
* 进程内发送消息,延迟发送,带生命周期
* 如果延时发送消息的时候sender处于非激活状态,消息取消发送
*
* @param sender 消息发送者
* @param value 发送的消息
* @param delay 延迟毫秒数
*/
void
postDelay
(
LifecycleOwner
sender
,
T
value
,
long
delay
);
/**
* 进程内发送消息
* 强制接收到消息的顺序和发送顺序一致
*
* @param value 发送的消息
*/
void
postOrderly
(
T
value
);
/**
* 以广播的形式发送一个消息
* 需要跨进程、跨APP发送消息的时候调用该方法
* 可使用postAcrossProcess or postAcrossApp代替
*
* @param value 发送的消息
*/
@Deprecated
void
broadcast
(
T
value
);
/**
* 以广播的形式发送一个消息
* 需要跨进程、跨APP发送消息的时候调用该方法
*
* @param value 发送的消息
* @param foreground true:前台广播、false:后台广播
* @param onlyInApp true:只在APP内有效、false:全局有效
*/
void
broadcast
(
T
value
,
boolean
foreground
,
boolean
onlyInApp
);
/**
* 注册一个Observer,生命周期感知,自动取消订阅
*
* @param owner LifecycleOwner
* @param observer 观察者
*/
void
observe
(
@NonNull
LifecycleOwner
owner
,
@NonNull
Observer
<
T
>
observer
);
/**
* 注册一个Observer,生命周期感知,自动取消订阅
* 如果之前有消息发送,可以在注册时收到消息(消息同步)
*
* @param owner LifecycleOwner
* @param observer 观察者
*/
void
observeSticky
(
@NonNull
LifecycleOwner
owner
,
@NonNull
Observer
<
T
>
observer
);
/**
* 注册一个Observer,需手动解除绑定
*
* @param observer 观察者
*/
void
observeForever
(
@NonNull
Observer
<
T
>
observer
);
/**
* 注册一个Observer,需手动解除绑定
* 如果之前有消息发送,可以在注册时收到消息(消息同步)
*
* @param observer 观察者
*/
void
observeStickyForever
(
@NonNull
Observer
<
T
>
observer
);
/**
* 通过observeForever或observeStickyForever注册的,需要调用该方法取消订阅
*
* @param observer 观察者
*/
void
removeObserver
(
@NonNull
Observer
<
T
>
observer
);
}
sobot_widget/src/main/java/com/sobot/widget/livedatabus/core/ObservableConfig.java
0 → 100644
View file @
fffb7f32
package
com
.
sobot
.
widget
.
livedatabus
.
core
;
public
class
ObservableConfig
{
Boolean
lifecycleObserverAlwaysActive
=
null
;
Boolean
autoClear
=
null
;
/**
* lifecycleObserverAlwaysActive
* set if then observer can always receive message
* true: observer can always receive message
* false: observer can only receive message when resumed
*
* @param active boolean
* @return ObservableConfig
*/
public
ObservableConfig
lifecycleObserverAlwaysActive
(
boolean
active
)
{
lifecycleObserverAlwaysActive
=
active
;
return
this
;
}
/**
* @param clear boolean
* @return true: clear livedata when no observer observe it
* false: not clear livedata unless app was killed
*/
public
ObservableConfig
autoClear
(
boolean
clear
)
{
autoClear
=
clear
;
return
this
;
}
}
sobot_widget/src/main/java/com/sobot/widget/livedatabus/ipc/annotation/IpcConfig.java
0 → 100644
View file @
fffb7f32
package
com
.
sobot
.
widget
.
livedatabus
.
ipc
.
annotation
;
import
com.sobot.widget.livedatabus.ipc.core.Processor
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Target
(
ElementType
.
TYPE
)
public
@interface
IpcConfig
{
Class
<?
extends
Processor
>
processor
();
}
sobot_widget/src/main/java/com/sobot/widget/livedatabus/ipc/consts/IpcConst.java
0 → 100644
View file @
fffb7f32
package
com
.
sobot
.
widget
.
livedatabus
.
ipc
.
consts
;
public
class
IpcConst
{
public
static
final
String
ACTION
=
"intent.action.ACTION_LEB_IPC"
;
public
static
final
String
KEY
=
"leb_ipc_key"
;
public
static
final
String
KEY_VALUE
=
"leb_ipc_value"
;
public
static
final
String
KEY_PROCESSOR_NAME
=
"leb_ipc_processor_name"
;
public
static
final
String
KEY_BUNDLE
=
"leb_ipc_bundle"
;
public
static
final
String
KEY_CLASS_NAME
=
"leb_ipc_class_name"
;
}
sobot_widget/src/main/java/com/sobot/widget/livedatabus/ipc/core/BooleanProcessor.java
0 → 100644
View file @
fffb7f32
package
com
.
sobot
.
widget
.
livedatabus
.
ipc
.
core
;
import
android.os.Bundle
;
import
com.sobot.widget.livedatabus.ipc.consts.IpcConst
;
public
class
BooleanProcessor
implements
Processor
{
@Override
public
boolean
writeToBundle
(
Bundle
bundle
,
Object
value
)
{
if
(!(
value
instanceof
Boolean
))
{
return
false
;
}
bundle
.
putBoolean
(
IpcConst
.
KEY_VALUE
,
(
boolean
)
value
);
return
true
;
}
@Override
public
Object
createFromBundle
(
Bundle
bundle
)
{
return
bundle
.
getBoolean
(
IpcConst
.
KEY_VALUE
);
}
}
sobot_widget/src/main/java/com/sobot/widget/livedatabus/ipc/core/DoubleProcessor.java
0 → 100644
View file @
fffb7f32
package
com
.
sobot
.
widget
.
livedatabus
.
ipc
.
core
;
import
android.os.Bundle
;
import
com.sobot.widget.livedatabus.ipc.consts.IpcConst
;
public
class
DoubleProcessor
implements
Processor
{
@Override
public
boolean
writeToBundle
(
Bundle
bundle
,
Object
value
)
{
if
(!(
value
instanceof
Double
))
{
return
false
;
}
bundle
.
putDouble
(
IpcConst
.
KEY_VALUE
,
(
Double
)
value
);
return
true
;
}
@Override
public
Object
createFromBundle
(
Bundle
bundle
)
{
return
bundle
.
getDouble
(
IpcConst
.
KEY_VALUE
);
}
}
sobot_widget/src/main/java/com/sobot/widget/livedatabus/ipc/core/FloatProcessor.java
0 → 100644
View file @
fffb7f32
package
com
.
sobot
.
widget
.
livedatabus
.
ipc
.
core
;
import
android.os.Bundle
;
import
com.sobot.widget.livedatabus.ipc.consts.IpcConst
;
public
class
FloatProcessor
implements
Processor
{
@Override
public
boolean
writeToBundle
(
Bundle
bundle
,
Object
value
)
{
if
(!(
value
instanceof
Float
))
{
return
false
;
}
bundle
.
putFloat
(
IpcConst
.
KEY_VALUE
,
(
float
)
value
);
return
true
;
}
@Override
public
Object
createFromBundle
(
Bundle
bundle
)
{
return
bundle
.
getFloat
(
IpcConst
.
KEY_VALUE
);
}
}
sobot_widget/src/main/java/com/sobot/widget/livedatabus/ipc/core/IntProcessor.java
0 → 100644
View file @
fffb7f32
package
com
.
sobot
.
widget
.
livedatabus
.
ipc
.
core
;
import
android.os.Bundle
;
import
com.sobot.widget.livedatabus.ipc.consts.IpcConst
;
public
class
IntProcessor
implements
Processor
{
@Override
public
boolean
writeToBundle
(
Bundle
bundle
,
Object
value
)
{
if
(!(
value
instanceof
Integer
))
{
return
false
;
}
bundle
.
putInt
(
IpcConst
.
KEY_VALUE
,
(
int
)
value
);
return
true
;
}
@Override
public
Object
createFromBundle
(
Bundle
bundle
)
{
return
bundle
.
getInt
(
IpcConst
.
KEY_VALUE
);
}
}
sobot_widget/src/main/java/com/sobot/widget/livedatabus/ipc/core/LongProcessor.java
0 → 100644
View file @
fffb7f32
package
com
.
sobot
.
widget
.
livedatabus
.
ipc
.
core
;
import
android.os.Bundle
;
import
com.sobot.widget.livedatabus.ipc.consts.IpcConst
;
public
class
LongProcessor
implements
Processor
{
@Override
public
boolean
writeToBundle
(
Bundle
bundle
,
Object
value
)
{
if
(!(
value
instanceof
Long
))
{
return
false
;
}
bundle
.
putLong
(
IpcConst
.
KEY_VALUE
,
(
long
)
value
);
return
true
;
}
@Override
public
Object
createFromBundle
(
Bundle
bundle
)
{
return
bundle
.
getLong
(
IpcConst
.
KEY_VALUE
);
}
}
sobot_widget/src/main/java/com/sobot/widget/livedatabus/ipc/core/ParcelableProcessor.java
0 → 100644
View file @
fffb7f32
package
com
.
sobot
.
widget
.
livedatabus
.
ipc
.
core
;
import
android.os.Bundle
;
import
android.os.Parcelable
;
import
com.sobot.widget.livedatabus.ipc.consts.IpcConst
;
public
class
ParcelableProcessor
implements
Processor
{
@Override
public
boolean
writeToBundle
(
Bundle
bundle
,
Object
value
)
{
if
(!(
value
instanceof
Parcelable
))
{
return
false
;
}
bundle
.
putParcelable
(
IpcConst
.
KEY_VALUE
,
(
Parcelable
)
value
);
return
true
;
}
@Override
public
Object
createFromBundle
(
Bundle
bundle
)
{
return
bundle
.
getParcelable
(
IpcConst
.
KEY_VALUE
);
}
}
sobot_widget/src/main/java/com/sobot/widget/livedatabus/ipc/core/Processor.java
0 → 100644
View file @
fffb7f32
package
com
.
sobot
.
widget
.
livedatabus
.
ipc
.
core
;
import
android.os.Bundle
;
public
interface
Processor
{
boolean
writeToBundle
(
Bundle
bundle
,
Object
value
)
throws
Exception
;
Object
createFromBundle
(
Bundle
bundle
)
throws
Exception
;
}
sobot_widget/src/main/java/com/sobot/widget/livedatabus/ipc/core/ProcessorManager.java
0 → 100644
View file @
fffb7f32
package
com
.
sobot
.
widget
.
livedatabus
.
ipc
.
core
;
import
android.content.Intent
;
import
android.os.Bundle
;
import
com.sobot.widget.livedatabus.ipc.annotation.IpcConfig
;
import
com.sobot.widget.livedatabus.ipc.consts.IpcConst
;
import
java.util.Arrays
;
import
java.util.HashMap
;
import
java.util.LinkedList
;
import
java.util.List
;
import
java.util.Map
;
public
class
ProcessorManager
{
private
static
class
SingletonHolder
{
private
static
final
ProcessorManager
INSTANCE
=
new
ProcessorManager
();
}
public
static
ProcessorManager
getManager
()
{
return
SingletonHolder
.
INSTANCE
;
}
private
final
List
<
Processor
>
baseProcessors
;
private
final
Map
<
String
,
Processor
>
processorMap
;
{
baseProcessors
=
new
LinkedList
<>(
Arrays
.
asList
(
new
StringProcessor
(),
new
IntProcessor
(),
new
BooleanProcessor
(),
new
DoubleProcessor
(),
new
FloatProcessor
(),
new
LongProcessor
(),
new
SerializableProcessor
(),
new
ParcelableProcessor
()));
processorMap
=
new
HashMap
<>();
for
(
Processor
processor
:
baseProcessors
)
{
processorMap
.
put
(
processor
.
getClass
().
getName
(),
processor
);
}
}
private
ProcessorManager
()
{
}
public
boolean
writeTo
(
Intent
intent
,
Object
value
)
{
if
(
intent
==
null
||
value
==
null
)
{
return
false
;
}
Bundle
bundle
=
new
Bundle
();
boolean
processed
=
false
;
//用指定的processor处理
IpcConfig
config
=
value
.
getClass
().
getAnnotation
(
IpcConfig
.
class
);
if
(
config
!=
null
)
{
Class
<?
extends
Processor
>
processorType
=
config
.
processor
();
String
processorTypeName
=
processorType
.
getName
();
if
(!
processorMap
.
containsKey
(
processorTypeName
))
{
try
{
processorMap
.
put
(
processorTypeName
,
processorType
.
newInstance
());
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
}
Processor
processor
=
processorMap
.
get
(
processorTypeName
);
if
(
processor
!=
null
)
{
try
{
boolean
handle
=
processor
.
writeToBundle
(
bundle
,
value
);
if
(
handle
)
{
intent
.
putExtra
(
IpcConst
.
KEY_PROCESSOR_NAME
,
processor
.
getClass
().
getName
());
intent
.
putExtra
(
IpcConst
.
KEY_BUNDLE
,
bundle
);
processed
=
true
;
}
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
}
if
(
processed
)
{
return
true
;
}
}
//用默认的processor处理
for
(
Processor
processor
:
baseProcessors
)
{
try
{
boolean
handle
=
processor
.
writeToBundle
(
bundle
,
value
);
if
(
handle
)
{
intent
.
putExtra
(
IpcConst
.
KEY_PROCESSOR_NAME
,
processor
.
getClass
().
getName
());
intent
.
putExtra
(
IpcConst
.
KEY_BUNDLE
,
bundle
);
processed
=
true
;
break
;
}
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
}
return
processed
;
}
public
Object
createFrom
(
Intent
intent
)
{
if
(
intent
==
null
)
{
return
null
;
}
String
processorName
=
intent
.
getStringExtra
(
IpcConst
.
KEY_PROCESSOR_NAME
);
Bundle
bundle
=
intent
.
getBundleExtra
(
IpcConst
.
KEY_BUNDLE
);
if
(
processorName
==
null
||
processorName
.
length
()
==
0
||
bundle
==
null
)
{
return
null
;
}
if
(!
processorMap
.
containsKey
(
processorName
))
{
try
{
processorMap
.
put
(
processorName
,
(
Processor
)
Class
.
forName
(
processorName
).
newInstance
());
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
}
Processor
processor
=
processorMap
.
get
(
processorName
);
if
(
processor
==
null
)
{
return
null
;
}
try
{
return
processor
.
createFromBundle
(
bundle
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
return
null
;
}
}
}
sobot_widget/src/main/java/com/sobot/widget/livedatabus/ipc/core/SerializableProcessor.java
0 → 100644
View file @
fffb7f32
package
com
.
sobot
.
widget
.
livedatabus
.
ipc
.
core
;
import
android.os.Bundle
;
import
com.sobot.widget.livedatabus.ipc.consts.IpcConst
;
import
java.io.Serializable
;
public
class
SerializableProcessor
implements
Processor
{
@Override
public
boolean
writeToBundle
(
Bundle
bundle
,
Object
value
)
{
if
(!(
value
instanceof
Serializable
))
{
return
false
;
}
bundle
.
putSerializable
(
IpcConst
.
KEY_VALUE
,
(
Serializable
)
value
);
return
true
;
}
@Override
public
Object
createFromBundle
(
Bundle
bundle
)
{
return
bundle
.
getSerializable
(
IpcConst
.
KEY_VALUE
);
}
}
sobot_widget/src/main/java/com/sobot/widget/livedatabus/ipc/core/StringProcessor.java
0 → 100644
View file @
fffb7f32
package
com
.
sobot
.
widget
.
livedatabus
.
ipc
.
core
;
import
android.os.Bundle
;
import
com.sobot.widget.livedatabus.ipc.consts.IpcConst
;
public
class
StringProcessor
implements
Processor
{
@Override
public
boolean
writeToBundle
(
Bundle
bundle
,
Object
value
)
{
if
(!(
value
instanceof
String
))
{
return
false
;
}
bundle
.
putString
(
IpcConst
.
KEY_VALUE
,
(
String
)
value
);
return
true
;
}
@Override
public
Object
createFromBundle
(
Bundle
bundle
)
{
return
bundle
.
getString
(
IpcConst
.
KEY_VALUE
);
}
}
sobot_widget/src/main/java/com/sobot/widget/livedatabus/ipc/receiver/LebIpcReceiver.java
0 → 100644
View file @
fffb7f32
package
com
.
sobot
.
widget
.
livedatabus
.
ipc
.
receiver
;
import
android.content.BroadcastReceiver
;
import
android.content.Context
;
import
android.content.Intent
;
import
com.sobot.widget.livedatabus.SobotLiveEventBus
;
import
com.sobot.widget.livedatabus.ipc.consts.IpcConst
;
import
com.sobot.widget.livedatabus.ipc.core.ProcessorManager
;
public
class
LebIpcReceiver
extends
BroadcastReceiver
{
@Override
public
void
onReceive
(
Context
context
,
Intent
intent
)
{
if
(
IpcConst
.
ACTION
.
equals
(
intent
.
getAction
()))
{
try
{
String
key
=
intent
.
getStringExtra
(
IpcConst
.
KEY
);
Object
value
=
ProcessorManager
.
getManager
().
createFrom
(
intent
);
if
(
key
!=
null
&&
value
!=
null
)
{
SobotLiveEventBus
.
get
(
key
).
post
(
value
);
}
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
}
}
}
sobot_widget/src/main/java/com/sobot/widget/livedatabus/logger/DefaultLogger.java
0 → 100644
View file @
fffb7f32
package
com
.
sobot
.
widget
.
livedatabus
.
logger
;
import
android.util.Log
;
import
java.util.logging.Level
;
public
class
DefaultLogger
implements
Logger
{
private
static
final
String
TAG
=
"[LiveEventBus]"
;
@Override
public
void
log
(
Level
level
,
String
msg
)
{
if
(
level
==
Level
.
SEVERE
)
{
Log
.
e
(
TAG
,
msg
);
}
else
if
(
level
==
Level
.
WARNING
)
{
Log
.
w
(
TAG
,
msg
);
}
else
if
(
level
==
Level
.
INFO
)
{
Log
.
i
(
TAG
,
msg
);
}
else
if
(
level
==
Level
.
CONFIG
)
{
Log
.
d
(
TAG
,
msg
);
}
else
if
(
level
!=
Level
.
OFF
)
{
Log
.
v
(
TAG
,
msg
);
}
}
@Override
public
void
log
(
Level
level
,
String
msg
,
Throwable
th
)
{
if
(
level
==
Level
.
SEVERE
)
{
Log
.
e
(
TAG
,
msg
,
th
);
}
else
if
(
level
==
Level
.
WARNING
)
{
Log
.
w
(
TAG
,
msg
,
th
);
}
else
if
(
level
==
Level
.
INFO
)
{
Log
.
i
(
TAG
,
msg
,
th
);
}
else
if
(
level
==
Level
.
CONFIG
)
{
Log
.
d
(
TAG
,
msg
,
th
);
}
else
if
(
level
!=
Level
.
OFF
)
{
Log
.
v
(
TAG
,
msg
,
th
);
}
}
}
sobot_widget/src/main/java/com/sobot/widget/livedatabus/logger/Logger.java
0 → 100644
View file @
fffb7f32
package
com
.
sobot
.
widget
.
livedatabus
.
logger
;
import
java.util.logging.Level
;
public
interface
Logger
{
void
log
(
Level
level
,
String
msg
);
void
log
(
Level
level
,
String
msg
,
Throwable
th
);
}
sobot_widget/src/main/java/com/sobot/widget/livedatabus/logger/LoggerManager.java
0 → 100644
View file @
fffb7f32
package
com
.
sobot
.
widget
.
livedatabus
.
logger
;
import
java.util.logging.Level
;
public
class
LoggerManager
implements
Logger
{
private
Logger
logger
;
private
boolean
enable
=
true
;
public
LoggerManager
(
Logger
logger
)
{
this
.
logger
=
logger
;
}
public
boolean
isEnable
()
{
return
enable
;
}
public
void
setEnable
(
boolean
enable
)
{
this
.
enable
=
enable
;
}
public
Logger
getLogger
()
{
return
logger
;
}
public
void
setLogger
(
Logger
logger
)
{
this
.
logger
=
logger
;
}
@Override
public
void
log
(
Level
level
,
String
msg
)
{
if
(
enable
)
{
logger
.
log
(
level
,
msg
);
}
}
@Override
public
void
log
(
Level
level
,
String
msg
,
Throwable
th
)
{
if
(
enable
)
{
logger
.
log
(
level
,
msg
,
th
);
}
}
}
sobot_widget/src/main/java/com/sobot/widget/livedatabus/utils/AppUtils.java
0 → 100644
View file @
fffb7f32
package
com
.
sobot
.
widget
.
livedatabus
.
utils
;
import
android.annotation.SuppressLint
;
import
android.app.Activity
;
import
android.app.ActivityManager
;
import
android.app.Application
;
import
android.app.Application.ActivityLifecycleCallbacks
;
import
android.content.Context
;
import
android.os.Bundle
;
import
android.support.v4.content.FileProvider
;
import
android.view.View
;
import
android.view.inputmethod.InputMethodManager
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.InvocationTargetException
;
import
java.util.HashMap
;
import
java.util.HashSet
;
import
java.util.Iterator
;
import
java.util.LinkedList
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Set
;
/**
* from Github: https://github.com/Blankj/AndroidUtilCode
*/
public
final
class
AppUtils
{
private
static
final
String
PERMISSION_ACTIVITY_CLASS_NAME
=
"com.blankj.utilcode.util.PermissionUtils$PermissionActivity"
;
private
static
final
ActivityLifecycleImpl
ACTIVITY_LIFECYCLE
=
new
ActivityLifecycleImpl
();
@SuppressLint
(
"StaticFieldLeak"
)
private
static
Application
sApplication
;
private
AppUtils
()
{
throw
new
UnsupportedOperationException
(
"u can't instantiate me..."
);
}
/**
* Init utils.
* <p>Init it in the class of Application.</p>
*
* @param context context
*/
public
static
void
init
(
final
Context
context
)
{
if
(
context
==
null
)
{
init
(
getApplicationByReflect
());
return
;
}
init
((
Application
)
context
.
getApplicationContext
());
}
/**
* Init utils.
* <p>Init it in the class of Application.</p>
*
* @param app application
*/
public
static
void
init
(
final
Application
app
)
{
if
(
sApplication
==
null
)
{
if
(
app
==
null
)
{
sApplication
=
getApplicationByReflect
();
}
else
{
sApplication
=
app
;
}
sApplication
.
registerActivityLifecycleCallbacks
(
ACTIVITY_LIFECYCLE
);
}
else
{
if
(
app
!=
null
&&
app
.
getClass
()
!=
sApplication
.
getClass
())
{
sApplication
.
unregisterActivityLifecycleCallbacks
(
ACTIVITY_LIFECYCLE
);
ACTIVITY_LIFECYCLE
.
mActivityList
.
clear
();
sApplication
=
app
;
sApplication
.
registerActivityLifecycleCallbacks
(
ACTIVITY_LIFECYCLE
);
}
}
}
/**
* Return the context of Application object.
*
* @return the context of Application object
*/
public
static
Application
getApp
()
{
if
(
sApplication
!=
null
)
return
sApplication
;
Application
app
=
getApplicationByReflect
();
init
(
app
);
return
app
;
}
private
static
Application
getApplicationByReflect
()
{
try
{
@SuppressLint
(
"PrivateApi"
)
Class
<?>
activityThread
=
Class
.
forName
(
"android.app.ActivityThread"
);
Object
thread
=
activityThread
.
getMethod
(
"currentActivityThread"
).
invoke
(
null
);
Object
app
=
activityThread
.
getMethod
(
"getApplication"
).
invoke
(
thread
);
if
(
app
==
null
)
{
throw
new
NullPointerException
(
"u should init first"
);
}
return
(
Application
)
app
;
}
catch
(
NoSuchMethodException
e
)
{
e
.
printStackTrace
();
}
catch
(
IllegalAccessException
e
)
{
e
.
printStackTrace
();
}
catch
(
InvocationTargetException
e
)
{
e
.
printStackTrace
();
}
catch
(
ClassNotFoundException
e
)
{
e
.
printStackTrace
();
}
throw
new
NullPointerException
(
"u should init first"
);
}
static
ActivityLifecycleImpl
getActivityLifecycle
()
{
return
ACTIVITY_LIFECYCLE
;
}
static
LinkedList
<
Activity
>
getActivityList
()
{
return
ACTIVITY_LIFECYCLE
.
mActivityList
;
}
static
Context
getTopActivityOrApp
()
{
if
(
isAppForeground
())
{
Activity
topActivity
=
ACTIVITY_LIFECYCLE
.
getTopActivity
();
return
topActivity
==
null
?
AppUtils
.
getApp
()
:
topActivity
;
}
else
{
return
AppUtils
.
getApp
();
}
}
static
boolean
isAppForeground
()
{
ActivityManager
am
=
(
ActivityManager
)
AppUtils
.
getApp
().
getSystemService
(
Context
.
ACTIVITY_SERVICE
);
if
(
am
==
null
)
return
false
;
List
<
ActivityManager
.
RunningAppProcessInfo
>
info
=
am
.
getRunningAppProcesses
();
if
(
info
==
null
||
info
.
size
()
==
0
)
return
false
;
for
(
ActivityManager
.
RunningAppProcessInfo
aInfo
:
info
)
{
if
(
aInfo
.
importance
==
ActivityManager
.
RunningAppProcessInfo
.
IMPORTANCE_FOREGROUND
)
{
return
aInfo
.
processName
.
equals
(
AppUtils
.
getApp
().
getPackageName
());
}
}
return
false
;
}
static
class
ActivityLifecycleImpl
implements
ActivityLifecycleCallbacks
{
final
LinkedList
<
Activity
>
mActivityList
=
new
LinkedList
<>();
final
Map
<
Object
,
OnAppStatusChangedListener
>
mStatusListenerMap
=
new
HashMap
<>();
final
Map
<
Activity
,
Set
<
OnActivityDestroyedListener
>>
mDestroyedListenerMap
=
new
HashMap
<>();
private
int
mForegroundCount
=
0
;
private
int
mConfigCount
=
0
;
private
boolean
mIsBackground
=
false
;
@Override
public
void
onActivityCreated
(
Activity
activity
,
Bundle
savedInstanceState
)
{
setTopActivity
(
activity
);
}
@Override
public
void
onActivityStarted
(
Activity
activity
)
{
if
(!
mIsBackground
)
{
setTopActivity
(
activity
);
}
if
(
mConfigCount
<
0
)
{
++
mConfigCount
;
}
else
{
++
mForegroundCount
;
}
}
@Override
public
void
onActivityResumed
(
Activity
activity
)
{
setTopActivity
(
activity
);
if
(
mIsBackground
)
{
mIsBackground
=
false
;
postStatus
(
true
);
}
}
@Override
public
void
onActivityPaused
(
Activity
activity
)
{
/**/
}
@Override
public
void
onActivityStopped
(
Activity
activity
)
{
if
(
activity
.
isChangingConfigurations
())
{
--
mConfigCount
;
}
else
{
--
mForegroundCount
;
if
(
mForegroundCount
<=
0
)
{
mIsBackground
=
true
;
postStatus
(
false
);
}
}
}
@Override
public
void
onActivitySaveInstanceState
(
Activity
activity
,
Bundle
outState
)
{
/**/
}
@Override
public
void
onActivityDestroyed
(
Activity
activity
)
{
mActivityList
.
remove
(
activity
);
consumeOnActivityDestroyedListener
(
activity
);
fixSoftInputLeaks
(
activity
);
}
Activity
getTopActivity
()
{
if
(!
mActivityList
.
isEmpty
())
{
final
Activity
topActivity
=
mActivityList
.
getLast
();
if
(
topActivity
!=
null
)
{
return
topActivity
;
}
}
Activity
topActivityByReflect
=
getTopActivityByReflect
();
if
(
topActivityByReflect
!=
null
)
{
setTopActivity
(
topActivityByReflect
);
}
return
topActivityByReflect
;
}
void
addOnAppStatusChangedListener
(
final
Object
object
,
final
OnAppStatusChangedListener
listener
)
{
mStatusListenerMap
.
put
(
object
,
listener
);
}
void
removeOnAppStatusChangedListener
(
final
Object
object
)
{
mStatusListenerMap
.
remove
(
object
);
}
void
removeOnActivityDestroyedListener
(
final
Activity
activity
)
{
if
(
activity
==
null
)
return
;
mDestroyedListenerMap
.
remove
(
activity
);
}
void
addOnActivityDestroyedListener
(
final
Activity
activity
,
final
OnActivityDestroyedListener
listener
)
{
if
(
activity
==
null
||
listener
==
null
)
return
;
Set
<
OnActivityDestroyedListener
>
listeners
;
if
(!
mDestroyedListenerMap
.
containsKey
(
activity
))
{
listeners
=
new
HashSet
<>();
mDestroyedListenerMap
.
put
(
activity
,
listeners
);
}
else
{
listeners
=
mDestroyedListenerMap
.
get
(
activity
);
if
(
listeners
.
contains
(
listener
))
return
;
}
listeners
.
add
(
listener
);
}
private
void
postStatus
(
final
boolean
isForeground
)
{
if
(
mStatusListenerMap
.
isEmpty
())
return
;
for
(
OnAppStatusChangedListener
onAppStatusChangedListener
:
mStatusListenerMap
.
values
())
{
if
(
onAppStatusChangedListener
==
null
)
return
;
if
(
isForeground
)
{
onAppStatusChangedListener
.
onForeground
();
}
else
{
onAppStatusChangedListener
.
onBackground
();
}
}
}
private
void
setTopActivity
(
final
Activity
activity
)
{
if
(
PERMISSION_ACTIVITY_CLASS_NAME
.
equals
(
activity
.
getClass
().
getName
()))
return
;
if
(
mActivityList
.
contains
(
activity
))
{
if
(!
mActivityList
.
getLast
().
equals
(
activity
))
{
mActivityList
.
remove
(
activity
);
mActivityList
.
addLast
(
activity
);
}
}
else
{
mActivityList
.
addLast
(
activity
);
}
}
private
void
consumeOnActivityDestroyedListener
(
Activity
activity
)
{
Iterator
<
Map
.
Entry
<
Activity
,
Set
<
OnActivityDestroyedListener
>>>
iterator
=
mDestroyedListenerMap
.
entrySet
().
iterator
();
while
(
iterator
.
hasNext
())
{
Map
.
Entry
<
Activity
,
Set
<
OnActivityDestroyedListener
>>
entry
=
iterator
.
next
();
if
(
entry
.
getKey
()
==
activity
)
{
Set
<
OnActivityDestroyedListener
>
value
=
entry
.
getValue
();
for
(
OnActivityDestroyedListener
listener
:
value
)
{
listener
.
onActivityDestroyed
(
activity
);
}
iterator
.
remove
();
}
}
}
private
Activity
getTopActivityByReflect
()
{
try
{
@SuppressLint
(
"PrivateApi"
)
Class
<?>
activityThreadClass
=
Class
.
forName
(
"android.app.ActivityThread"
);
Object
currentActivityThreadMethod
=
activityThreadClass
.
getMethod
(
"currentActivityThread"
).
invoke
(
null
);
Field
mActivityListField
=
activityThreadClass
.
getDeclaredField
(
"mActivityList"
);
mActivityListField
.
setAccessible
(
true
);
Map
activities
=
(
Map
)
mActivityListField
.
get
(
currentActivityThreadMethod
);
if
(
activities
==
null
)
return
null
;
for
(
Object
activityRecord
:
activities
.
values
())
{
Class
activityRecordClass
=
activityRecord
.
getClass
();
Field
pausedField
=
activityRecordClass
.
getDeclaredField
(
"paused"
);
pausedField
.
setAccessible
(
true
);
if
(!
pausedField
.
getBoolean
(
activityRecord
))
{
Field
activityField
=
activityRecordClass
.
getDeclaredField
(
"activity"
);
activityField
.
setAccessible
(
true
);
return
(
Activity
)
activityField
.
get
(
activityRecord
);
}
}
}
catch
(
ClassNotFoundException
e
)
{
e
.
printStackTrace
();
}
catch
(
IllegalAccessException
e
)
{
e
.
printStackTrace
();
}
catch
(
InvocationTargetException
e
)
{
e
.
printStackTrace
();
}
catch
(
NoSuchMethodException
e
)
{
e
.
printStackTrace
();
}
catch
(
NoSuchFieldException
e
)
{
e
.
printStackTrace
();
}
return
null
;
}
private
static
void
fixSoftInputLeaks
(
final
Activity
activity
)
{
if
(
activity
==
null
)
return
;
InputMethodManager
imm
=
(
InputMethodManager
)
AppUtils
.
getApp
().
getSystemService
(
Context
.
INPUT_METHOD_SERVICE
);
if
(
imm
==
null
)
return
;
String
[]
leakViews
=
new
String
[]{
"mLastSrvView"
,
"mCurRootView"
,
"mServedView"
,
"mNextServedView"
};
for
(
String
leakView
:
leakViews
)
{
try
{
Field
leakViewField
=
InputMethodManager
.
class
.
getDeclaredField
(
leakView
);
if
(
leakViewField
==
null
)
continue
;
if
(!
leakViewField
.
isAccessible
())
{
leakViewField
.
setAccessible
(
true
);
}
Object
obj
=
leakViewField
.
get
(
imm
);
if
(!(
obj
instanceof
View
))
continue
;
View
view
=
(
View
)
obj
;
if
(
view
.
getRootView
()
==
activity
.
getWindow
().
getDecorView
().
getRootView
())
{
leakViewField
.
set
(
imm
,
null
);
}
}
catch
(
Throwable
ignore
)
{
/**/
}
}
}
}
public
static
final
class
FileProvider4UtilCode
extends
FileProvider
{
@Override
public
boolean
onCreate
()
{
AppUtils
.
init
(
getContext
());
return
true
;
}
}
///////////////////////////////////////////////////////////////////////////
// interface
///////////////////////////////////////////////////////////////////////////
public
interface
OnAppStatusChangedListener
{
void
onForeground
();
void
onBackground
();
}
public
interface
OnActivityDestroyedListener
{
void
onActivityDestroyed
(
Activity
activity
);
}
}
sobot_widget/src/main/java/com/sobot/widget/livedatabus/utils/ThreadUtils.java
0 → 100644
View file @
fffb7f32
package
com
.
sobot
.
widget
.
livedatabus
.
utils
;
import
android.os.Looper
;
public
final
class
ThreadUtils
{
public
static
boolean
isMainThread
()
{
return
Looper
.
myLooper
()
==
Looper
.
getMainLooper
();
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment