LiveDataBus是基于LiveData实现的类似EventBus的消息通信框架,它是基于LiveData实现的.
public final class LiveDataBus {
private final Map<String, BusMutableLiveData<Object>> bus;
private LiveDataBus() {
bus = new HashMap<>();
}
private static class SingletonHolder {
private static final LiveDataBus DEFAULT_BUS = new LiveDataBus();
}
public static LiveDataBus get() {
return SingletonHolder.DEFAULT_BUS;
}
public <T> MutableLiveData<T> with(String key, Class<T> type) {
if (!bus.containsKey(key)) {
bus.put(key, new BusMutableLiveData<>());
}
return (MutableLiveData<T>) bus.get(key);
}
public MutableLiveData<Object> with(String key) {
return with(key, Object.class);
}
private static class ObserverWrapper<T> implements Observer<T> {
private Observer<T> observer;
public ObserverWrapper(Observer<T> observer) {
this.observer = observer;
}
@Override
public void onChanged(@Nullable T t) {
if (observer != null) {
if (isCallOnObserve()) {
return;
}
observer.onChanged(t);
}
}
private boolean isCallOnObserve() {
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
if (stackTrace != null && stackTrace.length > 0) {
for (StackTraceElement element : stackTrace) {
if ("android.arch.lifecycle.LiveData".equals(element.getClassName()) && "observeForever".equals(element.getMethodName())) {
return true;
}
}
}
return false;
}
}
private static class BusMutableLiveData<T> extends MutableLiveData<T> {
private Map<Observer, Observer> observerMap = new HashMap<>();
@Override
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) {
super.observe(owner, observer);
try {
hook(observer);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void observeForever(@NonNull Observer<T> observer) {
if (!observerMap.containsKey(observer)) {
observerMap.put(observer, new ObserverWrapper(observer));
}
super.observeForever(observerMap.get(observer));
}
@Override
public void removeObserver(@NonNull Observer<T> observer) {
Observer realObserver = null;
if (observerMap.containsKey(observer)) {
realObserver = observerMap.remove(observer);
} else {
realObserver = observer;
}
super.removeObserver(realObserver);
}
private void hook(@NonNull Observer<T> observer) throws Exception {
//get wrapper's version
Class<LiveData> classLiveData = LiveData.class;
Field fieldObservers = classLiveData.getDeclaredField("mObservers");
fieldObservers.setAccessible(true);
Object objectObservers = fieldObservers.get(this);
Class<?> classObservers = objectObservers.getClass();
Method methodGet = classObservers.getDeclaredMethod("get", Object.class);
methodGet.setAccessible(true);
Object objectWrapperEntry = methodGet.invoke(objectObservers, observer);
Object objectWrapper = null;
if (objectWrapperEntry instanceof Map.Entry) {
objectWrapper = ((Map.Entry) objectWrapperEntry).getValue();
}
if (objectWrapper == null) {
throw new NullPointerException("Wrapper can not be bull!");
}
Class<?> classObserverWrapper = objectWrapper.getClass().getSuperclass();
Field fieldLastVersion = classObserverWrapper.getDeclaredField("mLastVersion");
fieldLastVersion.setAccessible(true);
//get livedata's version
Field fieldVersion = classLiveData.getDeclaredField("mVersion");
fieldVersion.setAccessible(true);
Object objectVersion = fieldVersion.get(this);
//set wrapper's version
fieldLastVersion.set(objectWrapper, objectVersion);
}
}
}
LiveDataBus.get()
.with("tag", String.class)
.observe(this, new Observer<String>() {
@Override
public void onChanged(@Nullable String s) {
}
});
LiveDataBus.get().with("tag").setValue(str);
在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',
“输出”是一个序列化的OpenStruct。定义标题try(:output).try(:data).try(:title)结束什么会更好?:) 最佳答案 或者只是这样:deftitleoutput.data.titlerescuenilend 关于ruby-on-rails-更好的替代方法try(:output).try(:data).try(:name)?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.c
我正在使用DMOZ的listofurltopics,其中包含一些具有包含下划线的主机名的url。例如:608609TheOuterHeaven610InformationandimagegalleryofMcFarlane'sactionfiguresforTrigun,Akira,TenchiMuyoandotherJapaneseSci-Fianimations.611Top/Arts/Animation/Anime/Collectibles/Models_and_Figures/Action_Figures612虽然此url可以在网络浏览器中使用(或者至少在我的浏览器中可以使用:
你知道jrails的替代品吗?它或多或少已经过时(使用jQuery1.5-现在1.7是当前版本)。有人知道替代方案吗?谢谢编辑:我知道如何使用jqueryallone构建rails助手-但我喜欢rails助手,所以我不想单独使用jquery(没有jrails) 最佳答案 我一直在Rails中使用Prototype助手,最近我决定转而使用JQuery。起初我查看了JRails,因为它是一个直接替代品,因此需要最少的工作。但是!在阅读了更多关于JQuery的信息并尝试使用它之后,我逐渐明白,结合使用Rails和JQuery的最佳方式就是
关闭。这个问题不符合StackOverflowguidelines.它目前不接受答案。要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于StackOverflow来说是偏离主题的,因为它们往往会吸引自以为是的答案和垃圾邮件。相反,describetheproblem以及迄今为止为解决该问题所做的工作。关闭9年前。Improvethisquestion我想知道是否有人知道Ruby的rubyzip替代品,它可以处理各种格式,特别是zip/rar/7z?我知道libarchive,但它对我的目的来说并不完整(它是一个很好的gem)。(澄清一下,libarchive-对我不起作用-因为
我爱Sanitize.这是一个了不起的实用程序。我遇到的唯一问题是,它需要永远准备一个开发环境,因为它使用Nokogiri,这对编译时间来说是一种痛苦。是否有任何程序可以在不使用Nokogiri的情况下执行Sanitize的操作(如果没有别的,只是温和地执行它的操作)?这将以指数方式提供帮助! 最佳答案 Rails有自己的SanitizeHelper。根据http://api.rubyonrails.org/classes/ActionView/Helpers/SanitizeHelper.html,它将Thissanitizehe
我希望我的项目的顶级Rakefile使用树中更深的rakefile来构建东西;即顶层rakefile说明如何构建项目(大图),而较低层的rakefile说明如何构建特定模块(本map片)。当然有一组共享的配置,用于在任务之间共享时执行的详细信息:所以它主要是关于保持对需要构建的内容的描述,尽可能接近正在构建的源。例如。/Source/Module/code.foo和cie应该使用/Source/Module/Rakefile中的指令构建;并且/Rakefile了解模块之间的依赖关系。我不关心它是否使用多个rake进程(ala递归make),或者只是创建单独的构建环境。无论哪种方式,它都
我正在寻找Ruby的Marshal功能的直接替代品,希望它比Marshal具有以下一个或多个优势:更快的序列化/反序列化更简洁(或更小)的对象图谢谢!! 最佳答案 不幸的是,这不能作为替代品,因为Marshall会自动处理复杂类型。看起来msgpack将需要构建额外的功能(如Marshal的内部结构)将迭代定义相关对象的Ruby结构。 关于ruby-比Ruby编码(marshal)更快/更有效的替代品?,我们在StackOverflow上找到一个类似的问题:
我正在使用Dir.glob访问与通配符模式匹配的所有文件的集合。Dir.glob('**/*.txt'){|file_name|parsefile_name}因为这个glob调用是递归的,并且因为涉及很多文件,所以glob在block开始之前需要很长时间来构建文件数组。我想要的是一种访问所有相同文件的方法,但在Ruby“发现”每个文件后立即调用block,以便立即处理第一个文件,而不是等待整个目录树完成搜索。有这样的构造吗? 最佳答案 您还可以使用find和IO.popenIO.popen("find.-name'*.txt'").
我已经使用了一段时间的shoulda,并且阅读并使用了rspec。我没有做过深入的比较和对比。但在我看来,两者之间有一些重叠,但它们不是1-1的替代品。我正在考虑使用rspec在我的rails系统中编写一些单元测试,而不替换所有使用shoulda编写的现有测试。只是作为一种获得感觉的方式。这是个好主意吗?我可以逐渐从一个转移到另一个还是自找麻烦?我应该考虑其中一个比另一个明显的优势吗?谢谢! 最佳答案 我不得不反对Chris的回答,即它们是替代方案。我在我的Rails应用程序中同时使用Shoulda和Rspec,它们相互补充得很好。