各位大神们跪求大神av网站进击的巨人的event熟肉啊!

&>&&>&《进击的巨人》真人版,高清中文熟肉
在岛国8月1日新上映的《进击的巨人》真人版,凭借出色的特效效果,不出几天就登上了票房榜榜首。
电影在原著的基础上进行了修改,引得不少漫画观众的不满。
不过,由漫画改编的电影很少有非常成功的。
进击的巨人在国内是禁播的哦~
下载地址:(自带中文字幕),磁力链接请复制到下载工具下载。
Trackback (0)
还没有Trackback微信:doyo_game
盼望着盼望着!《进击的巨人》到了第二季的脚步终是近了
  2013年的年度动漫大作《进击的巨人》曾经感动了无数动漫粉,正当我们热情渐渐褪去之时,日,于东京国际会展中心举办的「进击!巨人中学校×进击の巨人“进击祭”Reading
Event」祭典活动中透露,确定由谏山创原作改编的《进击的巨人》第二季动画放送,将于2017年春季正式展开。主题歌等其他具体情报尚未公开。
/article/264897
阅读本文后,您的心情是:(选择后可查看结果)
今日关注游戏热门游戏:
进击的巨人(送兵长)
昨日手游领卡排行
手游测试表
本游戏暂无对应的卡
&&&当前预订人数:613
(本游戏暂无新手卡发放,建议您点击“预订”按钮。成功预订游戏后,您将在第一时间收到该游戏所有发号通知信息,避免迷茫的等待,请您留意通知系统的消息提示。)
★★★4月18日安卓全国咆哮公测★★★
★★★国内首款进击的巨人卡牌★★★&
★★★五千万粉丝推荐动漫巨作★★★
国内首款由同名动漫题材改编的卡牌手游《进击的巨人(送兵长)》根据风靡全球的同名动漫改编而成,堪称史上最惨烈卡牌手游!
-卡牌!最全角色完美收集:Q版精致的炫酷卡牌,精美的卡牌完美还原动漫角色!
-战斗!首创飞行动态作战:独创飞行战斗,完美营造出立体集中装置飞行作战的感觉!
-策略!独创暴走进击巅峰:运用三系兵团展现整体战斗思路,做到真正的攻守兼备!
-还原!屌爆剧情原汁原味:在终于原著基础上,完美的还原动漫剧情,再现战斗激情!
-复仇!自由之翼全服战斗:竞技场全服死斗模式,天梯排名紧张刺激,尽享尊贵万人敬仰!&
您可能喜欢的游戏
[新手卡] 05-06 00:48已上架
[新手卡] 05-05 20:35已上架
[新手卡] 05-05 20:27已上架
[新手卡] 05-05 20:27已上架
[新手卡] 05-05 16:47已上架
[新手卡] 05-05 16:37已上架
[激活码] 05-05 15:49已补仓
[新手卡] 05-05 12:11已上架
[新手卡] 05-05 11:53已上架
[新手卡] 05-05 11:43已上架
[新手卡] 05-05 11:17已上架
[新手卡] 05-05 10:18已上架
[新手卡] 05-05 08:44已上架
[新手卡] 05-04 17:24已上架
[新手卡] 05-04 17:24已上架
[新手卡] 05-04 14:38已上架1301人阅读
Android源码分析
“If I have seen further it is by standing on ye shoulders of Giants。”
开篇简介:巨人系列,是打算为读者带来我所阅读的源码做一些分析与讲解,详细的娓娓道来可能对现在的我来说,时间与水平上都不足够,只能为大家带来粗浅的东西。但愿能对读者提供些许帮助。
事件总线设计框架——EventBus
提起事件总线设计却不得不提GoF的观察者模式,可以说前者吸取了后者的精髓——订阅/发布机制
观察者模式结构示意图:
事件总线设计结构示意图:
在此我归档出几个显而易见的不同点
观察者模式
主体对象(1)观察者对象(N)
事件总线(一般为1)事件(N)事件监听器(N)
信息传递方式
包裹在事件中
Ok !概念总是来唬人的,就像我考了三次都没过的党课一样鸡肋。不过当你知道如何实践之后,概念就是你的总结
接下来开始大致的介绍下EventBus一些基本的类,便于对代码的理解。
以下是代码关联结构图:
(声明:以下图多为来自的EventBus讲解,比我讲解的更加全面,不过没有源码说明,想看的朋友不妨看完我的,再移步不迟)
从上图我们可以看到3种Poster,他们对应着不同的ThreadMode
如果使用 onEvent作为订阅函数,那么该事件在哪个线程发布出来的,onEvent就会在这个线程中运行,也就是说发布事件和接收事件线程在同一个线程。使用这个方法时,在 onEvent方法中不能执行耗时操作,如果执行耗时操作容易导致事件分发延迟
onEventMainThread
如果使用onEventMainThread作为订阅函数,那么不论事件是在哪个线程中发布出来的,onEventMainThread都会在UI线程中执行,接收事件就会在UI线程中运行,这个在Android中是非常有用的,因为在Android中只能在UI线程中跟新UI,所以在onEvnetMainThread 方法中是不能执行耗时操作的
onEventBackground
如果使用onEventBackgrond作为订阅函数,那么如果事件是在UI线程中发布出来的,那onEventBackground就会在子线程中运行,如果事件本来就是子线程中发布出来的,那么onEventBackground函数直接在该子线程中执行。
onEventAsync
使用这个函数作为订阅函数,那么无论事件在哪个线程发布,都会创建新的子线程在执行 onEventAsync.
以下是下面常出现的名词
传递的信息
需要监听信息的东西?这样描述吧…
事件监听器
接收到事件后,订阅者要做的事(方法)
订阅者+事件监听器
给点时间,大概五分钟吧,了解这个结构图、不同的模式和基本名词。大家就已经基本了解EventBus的代码结构,除了一些边角的类如异常类,配置类,工具类等,与主体功能无关。
初步了解大致功能运行流程,之后再深入阅读,假如时间足够。XD。
接下来,马上就要看EventBus的源码了,在看源码前,大家可以思考下,对EventBus那些东西最好奇?抱着问题去看,以期在源码中找到解答。
于我而言,我想知道这些东西 :
EventBus是如何在通知其他Activity或Fragment刷新UI线程的?
EventBus使用的时候为什么要注册和反注册,为什么传 Context 呢?
EventBus 如何实现多种线程模式的?
EventBus 使用的时候,为什么要要求取方法名一致?
答案就在代码中~
How time flies!
五分钟回来。开始讲诉我们的EventBus的基本流程啦~
first step: register
1. getDefault()
Only a singleton ~ 主要做的还是一些基本的变量声明之类的,不细说。下面列出构造函数
EventBus(EventBusBuilder builder) {
subscriptionsByEventType = new HashMap&Class&?&, CopyOnWriteArrayList&Subscription&&();
typesBySubscriber = new HashMap&Object, List&Class&?&&&();
stickyEvents = new ConcurrentHashMap&Class&?&, Object&();
mainThreadPoster = new HandlerPoster(this, Looper.getMainLooper(), 10);
backgroundPoster = new BackgroundPoster(this);
asyncPoster = new AsyncPoster(this);
subscriberMethodFinder = new SubscriberMethodFinder(builder.skipMethodVerificationForClasses);
logSubscriberExceptions = builder.logSubscriberE
logNoSubscriberMessages = builder.logNoSubscriberM
sendSubscriberExceptionEvent = builder.sendSubscriberExceptionE
sendNoSubscriberEvent = builder.sendNoSubscriberE
throwSubscriberException = builder.throwSubscriberE
eventInheritance = builder.eventI
executorService = builder.executorS
2.register(this)
EventBus 中有5个register * 的方法,不过他们都是使用了同一个 register:
* subscriber
任意class,不一定为activity等
是否为sticky事件
* priority
private synchronized void register(Object subscriber, boolean sticky, int priority) {
List&SubscriberMethod& subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriber.getClass());
for (SubscriberMethod subscriberMethod : subscriberMethods) {
subscribe(subscriber, subscriberMethod, sticky, priority);
以上代码补充一点:EventBus中的事件分为一般事件和 Sticky 事件,相对于一般事件,Sticky 事件不同之处在于,当事件发布后,再有订阅者开始订阅该类型事件,依然能收到该类型事件最近一个 Sticky 事件。
我们走入以上代码的 findSubscriberMethods 部分
* 通过方法名匹配,得到onEvent *
方法,并设置ThreadMode.
* subscriberClass
List&SubscriberMethod& findSubscriberMethods(Class&?& subscriberClass) {
String key = subscriberClass.getName();
List&SubscriberMethod& subscriberM
synchronized (methodCache) {
subscriberMethods = methodCache.get(key);
if (subscriberMethods != null) {
return subscriberM
subscriberMethods = new ArrayList&SubscriberMethod&();
Class&?& clazz = subscriberC
HashSet&String& eventTypesFound = new HashSet&String&();
StringBuilder methodKeyBuilder = new StringBuilder();
while (clazz != null) {
String name = clazz.getName();
if (name.startsWith("java.") || name.startsWith("javax.") || name.startsWith("android.")) {
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
String methodName = method.getName();
if (methodName.startsWith(ON_EVENT_METHOD_NAME)) {
int modifiers = method.getModifiers();
if ((modifiers & Modifier.PUBLIC) != 0 && (modifiers & MODIFIERS_IGNORE) == 0) {
Class&?&[] parameterTypes = method.getParameterTypes();
if (parameterTypes.length == 1) {
String modifierString = methodName.substring(ON_EVENT_METHOD_NAME.length());
ThreadMode threadM
if (modifierString.length() == 0) {
threadMode = ThreadMode.PostT
} else if (modifierString.equals("MainThread")) {
threadMode = ThreadMode.MainT
} else if (modifierString.equals("BackgroundThread")) {
threadMode = ThreadMode.BackgroundT
} else if (modifierString.equals("Async")) {
threadMode = ThreadMode.A
if (skipMethodVerificationForClasses.containsKey(clazz)) {
throw new EventBusException("Illegal onEvent method, check for typos: " + method);
Class&?& eventType = parameterTypes[0];
methodKeyBuilder.setLength(0);
methodKeyBuilder.append(methodName);
methodKeyBuilder.append('&').append(eventType.getName());
String methodKey = methodKeyBuilder.toString();
if (eventTypesFound.add(methodKey)) {
subscriberMethods.add(new SubscriberMethod(method, threadMode, eventType));
} else if (!skipMethodVerificationForClasses.containsKey(clazz)) {
Log.d(EventBus.TAG, "Skipping method (not public, static or abstract): " + clazz + "."
+ methodName);
clazz = clazz.getSuperclass();
if (subscriberMethods.isEmpty()) {
throw new EventBusException("Subscriber " + subscriberClass + " has no public methods called "
+ ON_EVENT_METHOD_NAME);
synchronized (methodCache) {
methodCache.put(key, subscriberMethods);
return subscriberM
其实也只是通过我们的字符串匹配而来的。这点上,EventBus应该是参考了“约定优于配置的思想”
找到我们class(订阅者)的所有onEvent *方法(事件监听器)了。继续看我们的
subscribe(subscriber, subscriberMethod, sticky, priority);忘记它做了什么的同学可以继续回滚上去看。
* subscriber
* subscriberMethod
事件监听器
是否为sticky事件
* priority
private void subscribe(Object subscriber, SubscriberMethod subscriberMethod, boolean sticky, int priority) {
Class&?& eventType = subscriberMethod.eventT
CopyOnWriteArrayList&Subscription& subscriptions = subscriptionsByEventType.get(eventType);
Subscription newSubscription = new Subscription(subscriber, subscriberMethod, priority);
if (subscriptions == null) {
subscriptions = new CopyOnWriteArrayList&Subscription&();
subscriptionsByEventType.put(eventType, subscriptions);
if (subscriptions.contains(newSubscription)) {
throw new EventBusException("Subscriber " + subscriber.getClass() + " already registered to event "
+ eventType);
int size = subscriptions.size();
for (int i = 0; i &= i++) {
if (i == size || newSubscription.priority & subscriptions.get(i).priority) {
subscriptions.add(i, newSubscription);
List&Class&?&& subscribedEvents = typesBySubscriber.get(subscriber);
if (subscribedEvents == null) {
subscribedEvents = new ArrayList&Class&?&&();
typesBySubscriber.put(subscriber, subscribedEvents);
subscribedEvents.add(eventType);
if (sticky) {
if (eventInheritance) {
Set&Map.Entry&Class&?&, Object&& entries = stickyEvents.entrySet();
for (Map.Entry&Class&?&, Object& entry : entries) {
Class&?& candidateEventType = entry.getKey();
if (eventType.isAssignableFrom(candidateEventType)) {
Object stickyEvent = entry.getValue();
checkPostStickyEventToSubscription(newSubscription, stickyEvent);
Object stickyEvent = stickyEvents.get(eventType);
checkPostStickyEventToSubscription(newSubscription, stickyEvent);
最后的方法如下
private void checkPostStickyEventToSubscription(Subscription newSubscription, Object stickyEvent) {
if (stickyEvent != null) {
postToSubscription(newSubscription, stickyEvent, Looper.getMainLooper() == Looper.myLooper());
register的流程就结束了,那么在回顾一下,加深下印象
That is all,第一步就这么完成了。是不是很容易?个人觉得EventBus还是很容易的。
这里顺带给大家讲诉下上文说的报错的点的优化。
这里主要针对项目耦合度太大,继承层级过深的情况
EventBus.getDefault().register(this)
一般大家都会常使用这样来注册,传入是当前的上下文。可是当你继承父类(该父类已经注册过)的时候,子类再注册,会执行以上的错误,”Subscriber XXXX already registered to event XXXX;
原因是:子类的context与父类是相同的,不允许重复注册,避免方法就是父类写了之后,子类不要写。或通过以下方法判断下
if(!EventBus.getDefault().isRegister(this){
EventBus.getDefault().register(this);
这里也推荐大家一个写法
在当前类中再定义一个内部类
private class MyBean{
public void onEventMainThead(OneEvent oneEvent){
注册时如下定义
myBean =new MyBean
EventBus.getDefault().register(myBean);
EventBus.getDefault().unregister(myBean);
second step:unregister()
你以为我会说post?No! No! No 简单先来,看看最后的unregister吧,短短几行罢了
代码如下:
* Unregisters the given subscriber from all event classes.
public synchronized void unregister(Object subscriber) {
List&Class&?&& subscribedTypes = typesBySubscriber.get(subscriber);
if (subscribedTypes != null) {
for (Class&?& eventType : subscribedTypes) {
unubscribeByEventType(subscriber, eventType);
typesBySubscriber.remove(subscriber);
Log.w(TAG, "Subscriber to unregister was not registered before: " + subscriber.getClass());
其中跳到了奇怪的地方,我们再跟进去看看
private void unubscribeByEventType(Object subscriber, Class&?& eventType) {
List&Subscription& subscriptions = subscriptionsByEventType.get(eventType);
if (subscriptions != null) {
int size = subscriptions.size();
for (int i = 0; i & i++) {
Subscription subscription = subscriptions.get(i);
if (subscription.subscriber == subscriber) {
subscription.active = false;
subscriptions.remove(i);
嗯哼~上文注册时关联在subscriptionsByEventType(订阅信息与事件的关联)和typesBySubscriber(事件与订阅者的关联)中的对象在反注册的时候都被remove了。so easy!~
值得一提的事,注册时的异常问题在反注册时候是没有的
third step: post
看到这里同学们也都累了,所以我们先看看post的流程图
假如你觉得ok,我们继续~
了解EventBus类中的PostingThreadState类
* For ThreadLocal, much faster to set (and get multiple values).
final static class PostingThreadState {
final List&Object& eventQueue = new ArrayList&Object&();
boolean isP
boolean isMainT
读名知意,我就不多说了。
接下来正式看看我们的post方法
* Posts the given event to the event bus.
public void post(Object event) {
PostingThreadState postingState = currentPostingThreadState.get();
List&Object& eventQueue = postingState.eventQ
eventQueue.add(event);
if (!postingState.isPosting) {
postingState.isMainThread = Looper.getMainLooper() == Looper.myLooper();
postingState.isPosting = true;
if (postingState.canceled) {
throw new EventBusException("Internal error. Abort state was not reset");
while (!eventQueue.isEmpty()) {
postSingleEvent(eventQueue.remove(0), postingState);
} finally {
postingState.isPosting = false;
postingState.isMainThread = false;
主要post还是在postSingleEvent()里,我们再尾行,或者尾随看看。
代码如下:
private void postSingleEvent(Object event, PostingThreadState postingState) throws Error {
Class&?& eventClass = event.getClass();
boolean subscriptionFound = false;
if (eventInheritance) {
List&Class&?&& eventTypes = lookupAllEventTypes(eventClass);
int countTypes = eventTypes.size();
for (int h = 0; h & countT h++) {
Class&?& clazz = eventTypes.get(h);
subscriptionFound |= postSingleEventForEventType(event, postingState, clazz);
subscriptionFound = postSingleEventForEventType(event, postingState, eventClass);
if (!subscriptionFound) {
if (logNoSubscriberMessages) {
Log.d(TAG, "No subscribers registered for event " + eventClass);
if (sendNoSubscriberEvent && eventClass != NoSubscriberEvent.class &&
eventClass != SubscriberExceptionEvent.class) {
post(new NoSubscriberEvent(this, event));
postSingleEventForEventType我们集体的post就放在这个方法里,离大结局不远了。行百里者,半九十!
要post的事件
* postingState
* eventClass
要post的事件或是其接口或父类
private boolean postSingleEventForEventType(Object event, PostingThreadState postingState, Class&?& eventClass) {
CopyOnWriteArrayList&Subscription&
synchronized (this) {
subscriptions = subscriptionsByEventType.get(eventClass);
if (subscriptions != null && !subscriptions.isEmpty()) {
for (Subscription subscription : subscriptions) {
postingState.event =
postingState.subscription =
boolean aborted = false;
postToSubscription(subscription, event, postingState.isMainThread);
aborted = postingState.
} finally {
postingState.event = null;
postingState.subscription = null;
postingState.canceled = false;
if (aborted) {
return true;
return false;
终于要看到关于我们想要看到的post真正要做的事啦,前面都只是判断而已,现在才到处理,看看 postToSubscription这个方法
,还记得我们的ThreadMode么?
* subscription
* isMainThread
是否为主线程
private void postToSubscription(Subscription subscription, Object event, boolean isMainThread) {
switch (subscription.subscriberMethod.threadMode) {
case PostThread:
invokeSubscriber(subscription, event);
case MainThread:
if (isMainThread) {
invokeSubscriber(subscription, event);
mainThreadPoster.enqueue(subscription, event);
case BackgroundThread:
if (isMainThread) {
backgroundPoster.enqueue(subscription, event);
invokeSubscriber(subscription, event);
case Async:
asyncPoster.enqueue(subscription, event);
throw new IllegalStateException("Unknown thread mode: " + subscription.subscriberMethod.threadMode);
ok,终于处理到我们的事件了,EventBus是如何实现各种ThreadMode的调用呢?这是一个很有意思的点。是我看eventBus的目的之一。
其实所有的原理都只是反射。但是如何实现的呢?先概括如下
在UI线程中时,继承的Handler类,在handleMessage中调用的反射;
在子线程时候,继承Runable类,用Executors.newCachedThreadPool().execute(this)来执行任务。其中run方法里也用了反射。
所以我们先来看看它的反射方法,所有的反射都是用得它:
void invokeSubscriber(PendingPost pendingPost) {
Object event = pendingPost.event;
Subscription subscription = pendingPost.
PendingPost.releasePendingPost(pendingPost);
if (subscription.active) {
invokeSubscriber(subscription, event);
事件监听器如何执行的我们明白了,接下来就先介绍下几个Poster类的相同属性的变量。
private final PendingPostQ
private final EventBus eventB
个人觉得这三种poster没有太大的点,很容易看明白,所以
以下贴出我的注释。关于这三种Poster
final class HandlerPoster extends Handler {
private final PendingPostQ
private final int maxMillisInsideHandleM
private final EventBus eventB
private boolean handlerA
HandlerPoster(EventBus eventBus, Looper looper, int maxMillisInsideHandleMessage) {
super(looper);
this.eventBus = eventB
this.maxMillisInsideHandleMessage = maxMillisInsideHandleM
queue = new PendingPostQueue();
void enqueue(Subscription subscription, Object event) {
PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);
synchronized (this) {
queue.enqueue(pendingPost);
if (!handlerActive) {
handlerActive = true;
if (!sendMessage(obtainMessage())) {
throw new EventBusException("Could not send handler message");
public void handleMessage(Message msg) {
boolean rescheduled = false;
long started = SystemClock.uptimeMillis();
while (true) {
PendingPost pendingPost = queue.poll();
if (pendingPost == null) {
synchronized (this) {
pendingPost = queue.poll();
if (pendingPost == null) {
handlerActive = false;
eventBus.invokeSubscriber(pendingPost);
long timeInMethod = SystemClock.uptimeMillis() -
if (timeInMethod &= maxMillisInsideHandleMessage) {
if (!sendMessage(obtainMessage())) {
throw new EventBusException("Could not send handler message");
rescheduled = true;
} finally {
handlerActive =
final class BackgroundPoster implements Runnable {
private final PendingPostQ
private final EventBus eventB
private volatile boolean executorR
BackgroundPoster(EventBus eventBus) {
this.eventBus = eventB
queue = new PendingPostQueue();
public void enqueue(Subscription subscription, Object event) {
PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);
synchronized (this) {
queue.enqueue(pendingPost);
if (!executorRunning) {
executorRunning = true;
eventBus.getExecutorService().execute(this);
public void run() {
while (true) {
PendingPost pendingPost = queue.poll(1000);
if (pendingPost == null) {
synchronized (this) {
pendingPost = queue.poll();
if (pendingPost == null) {
executorRunning = false;
eventBus.invokeSubscriber(pendingPost);
} catch (InterruptedException e) {
Log.w("Event", Thread.currentThread().getName() + " was interruppted", e);
} finally {
executorRunning = false;
看过上面的,这下面这个是最简单的,没什么营养
class AsyncPoster implements Runnable {
private final PendingPostQ
private final EventBus eventB
AsyncPoster(EventBus eventBus) {
this.eventBus = eventB
queue = new PendingPostQueue();
public void enqueue(Subscription subscription, Object event) {
PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);
queue.enqueue(pendingPost);
eventBus.getExecutorService().execute(this);
public void run() {
PendingPost pendingPost = queue.poll();
if(pendingPost == null) {
throw new IllegalStateException("No pending post available");
eventBus.invokeSubscriber(pendingPost);
这是我第一份讲解源码,如果有解释的不明白,或者模棱两可的地方,希望各位看官记得指正我。我还很弱,要专心练剑。
附上以上内容的
That is all~~ Thanks!
总结:作为时间总线的设计,看着一遍下来,应该也能知道个大概,特别是继承属性与Sticky事件,平时几乎用不到,不看源码,一般都不知道。精华的点是在如何处理ThreadMode吧。这种思路,对我这种菜鸡而言,还是第一次见,很受启发。
后感:EventBus的源码十分简单,很适合作为大家看的第一份源码。源码是读的过程中是枯燥的。不过收获的丰富的。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
(3)(4)(4)(1)(2)(1)(2)}

我要回帖

更多关于 跪求大神有此种子 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信