范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

爆肝写了个Android性能监测工具(支持Fps流量内存启动)

  1.App性能如何量化
  如何衡量一个APP性能好坏?直观感受就是:启动快、流畅、不闪退、耗电少等感官指标,反应到技术层面包装下就是:FPS(帧率)、界面渲染速度、Crash率、网络、CPU使用率、电量损耗速度等,一般挑其中几个关键指标作为APP质量的标尺。目前也有多种开源APM监控方案,但大部分偏向离线检测,对于线上监测而言显得太重,可能会适得其反,方案简单对比如下:
  SDK
  现状与问题
  是否推荐直接线上使用
  腾讯matrix
  功能全,但是重,而且运行测试期间经常Crash
  否
  腾讯GT
  2018年之后没更新,关注度低,本身功能挺多,也挺重性价比还不如matrix
  否
  网易Emmagee
  2018年之后没更新,几乎没有关注度,重
  否
  听云App
  适合监测网络跟启动,场景受限
  否
  还有其他多种APM检测工具,功能复杂多样,但其实很多指标并不是特别重要,实现越复杂,线上风险越大,因此,并不建议直接使用。而且,分析多家APP的实现原理,其核心思路基本相同,且门槛也并不是特别高,建议自研一套,在灵活性、安全性上更有保障,更容易做到轻量级。本文主旨就是围绕几个关键指标:FPS、内存(内存泄漏)、界面启动、流量等,实现轻量级的线上监测。 2.核心性能指标拆解
  • 稳定性:Crash统计
  Crash统计与聚合有比较通用的策略,比如Firebase、Bugly等,不在本文讨论范围。
  • 网络请求
  每个APP的网络请求一般都存在统一的Hook点,门槛很低,且各家请求协议与SDK有别,很难实现统一的网络请求监测,其次,想要真正定位网络请求问题,可能牵扯整个请求的链路,更适合做一套网络全链路监控APM,也不在讨论范围。
  • 冷启动时间及各个Activity页面启动时间 (存在统一方案)
  • 页面FPS、卡顿、ANR (存在统一方案)
  • 内存统计及内存泄露侦测 (存在统一方案)
  • 流量消耗 (存在统一方案)
  • 电量 (存在统一方案)
  • CPU使用率(CPU):还没想好咋么用,7.0之后实现机制也变了,先不考虑。
  线上监测的重点就聚焦后面几个,下面逐个拆解如何实现。
  启动耗时
  直观上说界面启动就是:从点击一个图标到看到下一个界面首帧,如果这个过程耗时较长,用户会会感受到顿挫,影响体验。从场景上说,启动耗时间简单分两种:
  冷启动耗时 :在APP未启动的情况下,从点击桌面icon 到看到闪屏Activity的首帧(非默认背景)。
  界面启动耗时 :APP启动后,从上一个界面pause,到下一个界面首帧可见。
  本文粒度较粗,主要聚焦Activity,这里有个比较核心的时机:Activity首帧可见点,这个点究竟在什么时候?经分析测试发现,不同版本表现不一,在Android 10 之前这个点与onWindowFocusChanged回调点基本吻合,在Android 10 之后,系统做了优化,将首帧可见的时机提前到onWindowFocusChanged之前,可以简单看做onResume(或者onAttachedToWindow)之后,对于一开始点击icon的点,可以约等于APP进程启动的点,拿到了上面两个时间点,就可以得到冷启动耗时。
  APP进程启动的点可以通过加载一个空的ContentProvider来记录,因为ContentProvider的加载时机比较靠前,早于Application的onCreate之前,相对更准确一点,很多SDK的初始也采用这种方式,实现如下: public class LauncherHelpProvider extends ContentProvider {      // 用来记录启动时间     public static long sStartUpTimeStamp = SystemClock.uptimeMillis();     ...      }
  这样就得到了冷启动的开始时间,如何得到第一个Activity界面可见的时间呢?比较简单的做法是在SplashActivity中进行打点,对于Android 10 以前的,可以在onWindowFocusChanged中打点,在Android 10以后,可以在onResume之后进行打点。不过,做SDK需要减少对业务的入侵,可以借助Applicattion监听Activity Lifecycle无入侵获取这个时间点。对于Android 10之前系统, 可以利用ViewTreeObserve监听nWindowFocusChange回调,达到无入侵获取onWindowFocusChanged调用点,示意代码如下:application.registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() {    ....    @Override public void onActivityResumed(@NonNull final Activity activity) {     super.onActivityResumed(activity);     launcherFlag |= resumeFlag;                 activity.getWindow().getDecorView().getViewTreeObserver().addOnWindowFocusChangeListener(new ViewTreeObserver.OnWindowFocusChangeListener() {                  @Override         public void onWindowFocusChanged(boolean b) {             if (b && (launcherFlag ^ startFlag) == 0) {                                 final boolean isColdStarUp = ActivityStack.getInstance().getBottomActivity() == activity;                                  final long coldLauncherTime = SystemClock.uptimeMillis() - LauncherHelpProvider.sStartUpTimeStamp;                 final long activityLauncherTime = SystemClock.uptimeMillis() - mActivityLauncherTimeStamp;                 activity.getWindow().getDecorView().getViewTreeObserver().removeOnWindowFocusChangeListener(this);                                  mHandler.post(new Runnable() {                     @Override                     public void run() {                         if (isColdStarUp) {                         //todo 监听到冷启动耗时                         ...
  对于Android 10以后的系统,可以在onActivityResumed回调时添加一UI线程Message来达到监听目的,代码如下:@Override public void onActivityResumed(@NonNull final Activity activity) {     super.onActivityResumed(activity);     if (launcherFlag != 0 && (launcherFlag & resumeFlag) == 0) {         launcherFlag |= resumeFlag;         if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) {             //  10 之后有改动,第一帧可见提前了 可认为onActivityResumed之后             mUIHandler.post(new Runnable() {                 @Override                 public void run() {                                             }             });         }
  如此就可以检测到冷启动耗时。APP启动后,各Activity启动耗时计算逻辑类似,首帧可见点沿用上面方案即可,不过这里还缺少上一个界面暂停的点,经分析测试,锚在上一个Actiivty pause的时候比较合理,因此Activity启动耗时定义如下:Activity启动耗时 = 当前Activity 首帧可见 - 上一个Activity onPause被调用
  同样为了减轻对业务入侵,也依赖registerActivityLifecycleCallbacks来实现:补全上方缺失:application.registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() {     @Override     public void onActivityPaused(@NonNull Activity activity) {         super.onActivityPaused(activity);                  mActivityLauncherTimeStamp = SystemClock.uptimeMillis();         launcherFlag = 0;     }     ... @Override public void onActivityResumed(@NonNull final Activity activity) {     super.onActivityResumed(activity);     launcherFlag |= resumeFlag;              ...
  到这里就获取了两个比较关键的启动耗时,不过,实际使用中可能存在各种异常场景:比如闪屏页在onCreate或者onResume中调用了finish跳转首页,对于这种场景就需要额外处理,比如在onCreate中调用了finish,onResume可能不会被调用,这个时候就要在 onCreate之后进行统计,同时利用用Activity.isFinishing()标识这种场景,其次,启动耗时对于不同配置也是不一样的,不能用绝对时间衡量,只能横向对比,简单线上效果如下:
  线上效果如下:
  流畅度及FPS(Frames Per Second)监测
  FPS是图像领域中的定义,指画面每秒传输帧数,每秒帧数越多,显示的动作就越流畅。FPS可以作为衡量流畅度的一个指标,但是,从各厂商的报告来看,仅用FPS来衡量是否流畅并不科学。电影或视频的FPS并不高,30的FPS即可满足人眼需求,稳定在30FPS的动画,并不会让人感到卡顿,但如果FPS 很不稳定的话,就很容易感知到卡顿,注意,这里有个词叫稳定。举个极端例子:前500ms刷新了59帧,后500ms只绘制一帧,即使达到了60FPS,仍会感知卡顿,这里就突出稳定的重要性。不过FPS也并不是完全没用,可以用其上限定义流畅,用其下限可以定义卡顿,对于中间阶段的感知,FPS无能为力,如下示意:
  上面那个是极端例子,Android 系统中,VSYNC会杜绝16ms内刷新两次,那么在中间的情况下怎么定义流畅?比如,FPS降低到50会卡吗?答案是不一定。50的FPS如果是均分到各个节点,用户是感知不到掉帧的,但,如果丢失的10帧全部在一次绘制点,那就能明显感知卡顿,这个时候,瞬时帧率的意义更大,如下:
  Matrix给的卡顿标准:
  总之,相比1s平均FPS,瞬时掉帧程度的严重性更能反应界面流畅程度,因此FPS监测的重点是侦测瞬时掉帧程度。
  在应用中,FPS对动画及列表意义较大,监测开始的时机放在界面启动并展示第一帧之后,这样就能跟启动完美衔接起来.// 帧率不统计第一帧 @Override public void onActivityResumed(@NonNull final Activity activity) {     super.onActivityResumed(activity);     activity.getWindow().getDecorView().getViewTreeObserver().addOnWindowFocusChangeListener(new ViewTreeObserver.OnWindowFocusChangeListener() {         @Override         public void onWindowFocusChanged(boolean b) {             if (b) {                              resumeTrack();                 activity.getWindow().getDecorView().getViewTreeObserver().removeOnWindowFocusChangeListener(this); ... }
  侦测停止的时机也比较简单在onActivityPaused:界面失去焦点,无法与用户交互的时候。@Override public void onActivityPaused(@NonNull Activity activity) {     super.onActivityPaused(activity);     pauseTrack(activity.getApplication()); }
  如何侦测瞬时FPS?有两种常用方式:
  360 ArgusAPM类实现方式:监测Choreographer两次Vsync时间差。
  BlockCanary的实现方式:监测UI线程单条Message执行时间。
  360的实现依赖Choreographer VSYNC回调,具体实现如下:循环添加Choreographer.FrameCallback。Choreographer.getInstance().postFrameCallback(new Choreographer.FrameCallback() {      @Override         public void doFrame(long frameTimeNanos) {             mFpsCount++;             mFrameTimeNanos = frameTimeNanos;             if (isCanWork()) {                 //注册下一帧回调                 Choreographer.getInstance().postFrameCallback(this);             } else {                 mCurrentCount = 0;             }         } });
  这种监听有个问题就是,监听过于频繁,因为在无需界面刷新的时候Choreographer.FrameCallback还是不断循环执行,浪费CPU资源,对线上运行采集并不友好,相比之下BlockCanary的监听单个Message执行要友善的多,而且同样能够涵盖UI绘制耗时、两帧之间的耗时,额外执行负担较低,也是本文采取的策略,核心实现参照Matrix:
  • 监听Message执行耗时。
  • 通过反射循环添加Choreographer.FrameCallback区分doFrame耗时。
  为Looper设置一个LooperPrinter,根据回传信息头区分消息执行开始与结束,计算Message耗时:原理如下:public static void loop() {     ...     if (logging != null) {         logging.println(">>>>> Dispatching to " + msg.target + " " +                 msg.callback + ": " + msg.what);     }      ...     if (logging != null) {         logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);     }
  自定义LooperPrinter如下:class LooperPrinter implements Printer {  @Override public void println(String x) {    ...     if (isValid) {              dispatch(x.charAt(0) == ">", x); }
  利用回调参数">>>>"与"<<<"的 区别即可诊断出Message执行耗时,从而确定是否导致掉帧。以上实现针对所有UI Message,原则上UI线程所有的消息都应该保持轻量级,任何消息超时都应当算作异常行为,所以,直接拿来做掉帧监测没特大问题的。但是,有些特殊情况可能对FPS计算有一些误判,比如,在touch时间里往UI线程塞了很多消息,单条一般不会影响滚动,但多条聚合可能会带来影响,如果没跳消息执行时间很短,这种方式就可能统计不到,当然这种业务的写法本身就存在问题,所以先不考虑这种场景。
  Choreographer有个方法addCallbackLocked,通过这个方法添加的任务会被加入到VSYNC回调,会跟Input、动画、UI绘制一起执行,因此可以用来作为鉴别是否是UI重绘的Message,看看是不是重绘或者触摸事件导致的卡顿掉帧。Choreographer源码如下:@UnsupportedAppUsage public void addCallbackLocked(long dueTime, Object action, Object token) {     CallbackRecord callback = obtainCallbackLocked(dueTime, action, token);     CallbackRecord entry = mHead;     if (entry == null) {         mHead = callback;         return;     }     if (dueTime < entry.dueTime) {         callback.next = entry;         mHead = callback;         return;     }     while (entry.next != null) {         if (dueTime < entry.next.dueTime) {             callback.next = entry.next;             break;         }         entry = entry.next;     }     entry.next = callback; }
  该方法不为外部可见,因此需要通过反射获取。private synchronized void addFrameCallback(int type, Runnable callback, boolean isAddHeader) {      try {                       addInputQueue = reflectChoreographerMethod(0 "addCallbackLocked", long.class, Object.class, Object.class);                        if (null != method) {                 method.invoke(callbackQueues[type], !isAddHeader ? SystemClock.uptimeMillis() : -1, callback, null);             }
  然后在每次执行结束后,重新将callback添加回Choreographer的Queue,监听下一次UI绘制。@Override public void dispatchEnd() {     super.dispatchEnd();     if (mStartTime > 0) {         long cost = SystemClock.uptimeMillis() - mStartTime;                  collectInfoAndDispatch(ActivityStack.getInstance().getTopActivity(), cost, mInDoFrame);         if (mInDoFrame) {                      addFrameCallBack();             mInDoFrame = false;         }     } }
  这样就能检测到每次Message执行的时间,它可以直接用来计算瞬时帧率。瞬时掉帧程度 = Message耗时/16 -1 (不足1 可看做1)
  瞬时掉帧小于2次可以认为没有发生抖动,如果出现了单个Message执行过长,可认为发生了掉帧,流畅度与瞬时帧率监测大概就是这样。不过,同启动耗时类似,不同配置结果不同,不能用绝对时间衡量,只能横向对比,简单线上效果如下:
  内存泄露及内存使用侦测
  内存泄露有个比较出名的库LeakCanary,实现原理也比较清晰,就是利用弱引用+ReferenceQueue,其实只用弱引用也可以做,ReferenceQueue只是个辅助作用,LeakCanary除了泄露检测还有个堆栈Dump的功能,虽然很好,但是这个功能并不适合线上,而且,只要能监听到Activity泄露,本地分析原因是比较快的,没必要将堆栈Dump出来。因此,本文只实现Activity泄露监测能力,不在线上分析原因。而且,参考LeakCanary,改用一个WeakHashMap实现上述功能,不在主动暴露ReferenceQueue这个对象。WeakHashMap最大的特点是其key对象被自动弱引用,可以被回收,利用这个特点,用其key监听Activity回收就能达到泄露监测的目的。核心实现如下:application.registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() {      @Override     public void onActivityDestroyed(@NonNull Activity activity) {         super.onActivityDestroyed(activity);                  mActivityStringWeakHashMap.put(activity, activity.getClass().getSimpleName());     }      @Override     public void onActivityStopped(@NonNull final Activity activity) {         super.onActivityStopped(activity);         //  退后台,GC 找LeakActivity         if (!ActivityStack.getInstance().isInBackGround()) {             return;         }         Runtime.getRuntime().gc();         mHandler.postDelayed(new Runnable() {             @Override             public void run() {                 try {                     if (!ActivityStack.getInstance().isInBackGround()) {                         return;                     }                     try {                         //   申请个稍微大的对象,促进GC                         byte[] leakHelpBytes = new byte[4 * 1024 * 1024];                         for (int i = 0; i < leakHelpBytes.length; i += 1024) {                             leakHelpBytes[i] = 1;                         }                     } catch (Throwable ignored) {                     }                     Runtime.getRuntime().gc();                     SystemClock.sleep(100);                     System.runFinalization();                     HashMap hashMap = new HashMap<>();                     for (Map.Entry activityStringEntry : mActivityStringWeakHashMap.entrySet()) {                         String name = activityStringEntry.getKey().getClass().getName();                         Integer value = hashMap.get(name);                         if (value == null) {                             hashMap.put(name, 1);                         } else {                             hashMap.put(name, value + 1);                         }                     }                     if (mMemoryListeners.size() > 0) {                         for (Map.Entry entry : hashMap.entrySet()) {                             for (ITrackMemoryListener listener : mMemoryListeners) {                                 listener.onLeakActivity(entry.getKey(), entry.getValue());                             }                         }                     }                 } catch (Exception ignored) {                 }             }         }, 10000);     }
  线上选择监测没必要实时,将其延后到APP进入后台的时候,在APP进入后台之后主动触发一次GC,然后延时10s,进行检查,之所以延时10s,是因为GC不是同步的,为了让GC操作能够顺利执行完,这里选择10s后检查。在检查前分配一个4M的大内存块,再次确保GC执行,之后就可以根据WeakHashMap的特性,查找有多少Activity还保留在其中,这些Activity就是泄露Activity。
  关于内存检测
  内存检测比较简单,弄清几个关键的指标就行,这些指标都能通过 Debug.MemoryInfo获取。Debug.MemoryInfo debugMemoryInfo = new Debug.MemoryInfo(); Debug.getMemoryInfo(debugMemoryInfo); appMemory.nativePss = debugMemoryInfo.nativePss >> 10; appMemory.dalvikPss = debugMemoryInfo.dalvikPss >> 10; appMemory.totalPss = debugMemoryInfo.getTotalPss() >> 10;
  这里关心三个就行:
  1. TotalPss(整体内存,native+dalvik+共享)
  2. nativePss (native内存)
  3. dalvikPss (java内存 OOM原因)
  一般而言total是大于nativ+dalvik的,因为它包含了共享内存,理论上我们只关心native跟dalvik就行,以上就是关于内存的监测能力,不过内存泄露不是100%正确,暴露明显问题即可,效果如下:
  流量监测
  流量监测的实现相对简单,利用系统提供的TrafficStats.getUidRxBytes方法,配合Actvity生命周期,即可获取每个Activity的流量消耗。具体做法:在Activity start的时候记录起点,在pause的时候累加,最后在Destroyed的时候统计整个Activity的流量消耗,如果想要做到Fragment维度,就要具体业务具体分析了,简单实现如下:application.registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() {      @Override     public void onActivityStarted(@NonNull Activity activity) {         super.onActivityStarted(activity);                  markActivityStart(activity);     }      @Override     public void onActivityPaused(@NonNull Activity activity) {         super.onActivityPaused(activity);                  markActivityPause(activity);     }      @Override     public void onActivityDestroyed(@NonNull Activity activity) {         super.onActivityDestroyed(activity);                  markActivityDestroy(activity);     } };
  电量检测Android电量状态能通过以下方法实时获取,只是对于分析来说有点麻烦,需要根据不同手机、不同配置做聚合,单处采集很简单。IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); android.content.Intent batteryStatus = application.registerReceiver(null, filter); int status = batteryStatus.getIntExtra("status", 0); boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||         status == BatteryManager.BATTERY_STATUS_FULL; int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
  不过并不能获取绝对电量,只能看百分比,因为对单个Activity来做电量监测并不靠谱,往往都是0,可以在APP推到后台后,对这个在线时长的电池消耗做监测,这个可能还能看出一些电量变化。CPU使用监测
  没想好怎么弄,显不出力。
  3数据整合与基线制定
  APP端只是完成的数据的采集,数据的整合及根系还是要依赖后台数据分析,根据不同配置,不同场景才能制定一套比较合理的基线,而且,这种基线肯定不是绝对的,只能是相对的,这套基线将来可以作为页面性能评估标准,对Android而言,挺难,机型太多。总结
  启动有相对靠谱节点。
  瞬时FPS(瞬时掉帧程度)意义更大。
  内存泄露可以一个WeakHashMap简单搞定。
  电量及CPU还不知道怎么用。
  作者:看书的小蜗牛
  转载地址:https://www.jianshu.com/p/978b7bce6290

68岁林青霞9亿豪宅火灾后续!20多位佣人被救,本尊出面回应损失林青霞9亿豪宅着火后续7月8日凌晨,大家还在甜美的睡梦中的时候。香港飞蛾山上的一栋豪宅突然起火,火势凶猛,现场都是滚滚浓烟,网友透露,这一场大火,足足烧了7个多小时。经过努力的扑救娱乐圈死得最悲惨的5位女明星,年龄均在29岁,生前各个美貌如花天有不测风云,人有旦夕祸福人生一世,不过是一个又一个24小时的叠加,人虽然不能抗拒生死,但总有人在最美好的年华里失去了生命,让人深感惋惜。接下来小编要说的就是娱乐圈死得最悲惨的五位嘎子谢孟伟,别疯了,留点后路吧想看人数26,上线6天分账不到25万。这部由嘎子谢孟伟主演的网络电影,不管是口碑还是分账收入,都算得上惨不忍睹。但日前曝光的电影片段,却意外造就了嘎子偷狗这个热门梗儿。画面中,谢孟向往6刘震云狂怼黄磊何炅,却对张艺兴彬彬有礼,原因现实历时近两个月的播出,由何炅黄磊张艺兴彭昱畅以及张子枫5位明星担任常驻嘉宾的慢综艺向往的生活第六季已经接近尾声,目前正式录制已经结束,而播出进度也已经过半。虽然常驻阵容和飞行嘉宾阵容跌至1399元,256GB6nm旗舰芯片,小米爆款手机加速清仓关注手机行业的都知道,安卓手机更新换代的速度是非常快的,迫于市场竞争压力,主流品牌推新品的速度也越来越快,这也导致安卓手机普遍出现保值率低,降价速度快,黄金销售周期短的问题。对于厂为何说闲鱼存在灰色交易?知情人给出解释,并非空穴来风在互联网的高速发展之下,人们的生活发生了翻天覆地的变化,这主要还是因为互联网改变了人们的很多生活方式就比如人们的购物方式,以及二手产品的销售方式。以前有很多人都是到线下实体店去买东小米12SPro对比荣耀Magic4Pro,Pro之间的较量小米12SPro荣耀Magic4Pro性能骁龙8Gen1LPDDR5UFS3。1骁龙8Gen1LPDDR5UFS3。1屏幕6。73英寸120Hz三星E5AMOLED柔性曲面屏分辨率阿里老兵亲述不懂这些,你的复盘都是白费功夫复盘工作法的本质是一种绩效管理工具,它能够为员工提供一个反馈结果反观过程的场景。一场高质量的工作复盘能够帮助员工成长,而管理者也能通过这一管理工具辅导和赋能员工,从而实现个人和组织截至七月初,这4款千元机性价比最高,用到2025年毫无压力截至七月初,这4款千元机性价比最高,用到2025年毫无压力!iQOOZ5iQOO系列千元机,配置上是满血的UFS3。1LPDDR5骁龙778G,号称性能铁三角的规格,足矣媲美4k价红魔7S系列7月11日发布,标配165W快充头满血征战沙场对于喜欢玩游戏的小伙伴来说,相信对于红魔游戏手机这个品牌一定不会陌生,近日,随着红魔7S系列游戏手机开始官宣预热,不少想要下半年换装备的玩家,都开始将目光聚焦到这款7月11日即将发7月份最值得买的3款手机,覆盖低中高三档,几乎零差评7月份最值得买的4款手机,覆盖低中高三档,几乎零差评!红米note11TPro红米note系列新品,搭载中端旗舰芯片天玑8100,给力的散热方案下,机子畅玩主流手游无压力。屏幕是最UFC张伟丽挑战卡拉日期正式敲定8月21日,张伟丽VS卡拉埃斯帕扎的女子草量级冠军战日期正式敲定,这场对决将作为北京时间11月13日在纽约麦迪逊花园广场举行的PPV赛事UFC281的联合主赛。张伟丽目前战绩为22转会消息皇马马德里巴塞罗那曼联马德里竞技富勒姆拜仁慕尼黑莫德里奇想踢到40岁。他决心在此之前获得续约。孟菲斯德佩的情况,还是和周六一样。两天前与巴萨达成协议终止合同正在与尤文图斯谈判合同和个人条款本周决定(来源罗马诺)西班牙体育报称,乌多拉多故意报复撞倒马宁,河南队成为球场垃圾就是因为打法转型8月21日的中超联赛晚间场,武汉长江主场对阵河南嵩山龙门,上半场第15分钟,河南外援多拉多在跑动中故意背后撞翻主裁马宁,VAR介入后多拉多被马宁直红罚下。当天深夜,河南队发布官方公张伟丽确定11月再次挑战金腰带UFC(终极格斗冠军赛)21日正式宣布,中国名将张伟丽将于北京时间11月13日在纽约麦迪逊花园广场挑战女子草量级现任冠军卡拉埃斯帕扎。这场对决也将作为UFC281的联合主赛,当晚头庄神豪言带领公牛夺冠,称湖人和篮网不识货,篮板率位列历史第一德拉蒙德庄神在今年休赛期离开篮网之后,以两年660万美元的价格加盟了公牛队,作为现役NBA当中篮板球实力最好的球员,庄神在篮下的时候总可以依靠强壮的身体和敏锐的嗅觉抢下篮板球,并且浓眉与拉文互换东家?联盟高管这是双赢交易浓眉为家乡球队效力北京时间8月22日,湖人收获一个奇特的交易设想,一名NBA匿名高管为湖人出招,认为湖人应该用浓眉单换拉文才能双赢。如果交易能实现,湖人的三巨头阵容将会变成詹姆斯拉文威少,而拉文的机0进球3连败!英超劲旅1。24亿欧打水漂,曼联前主帅深陷泥潭英超联赛第3轮结束一场焦点对决,前曼联主帅莫耶斯执教的西汉姆联,坐镇主场迎战上一场刚爆冷40完胜曼联的海欧布莱顿。最终坐拥主场之势没能转化成胜利,西汉姆联队02落败,遭遇新赛季开局太罕见!曼联双红会海报主角是无名小卒?C罗会作何感想欧洲五大联赛正如火如荼的进行着,英超联赛更是一如既往的竞争激烈。两轮过后利物浦仍没有取得胜利,而曼联更是两战皆负排名积分榜垫底。双方都急需一场胜利来提升士气,今天凌晨,这场双红会即切尔西历史上最昂贵的五笔U19签约!谁物超所值?在新东家博利的领导下,切尔西仍在继续做着与阿布领导下的西伦敦俱乐部同样的事情。这位美国商人正在为斯坦福桥引进世界级的球员,同时也签下了能够塑造俱乐部未来的年轻人。自从兰帕德执教期间纽卡斯尔高位逼抢未能贯穿始终曼城右路为什么会被圣马打爆8月22日消息,在纽卡斯尔33曼城这场比赛之后,很少再有人认为曼城会轻松取得联赛三连冠了。纽卡斯尔除了后腰吉马良斯,确实没有什么大牌。门将波普表现确实出色,他应该能进入英格兰世界杯美媒评斯蒂芬库里和魔术师约翰逊总决赛场均数据,谁更强?魔术师约翰逊是NBA历史上最伟大的控球后卫,他是这个位置的历史最佳。然而,自从斯蒂芬库里在202122赛季夺得总冠军后,不少人认为斯蒂芬库里已经超越了魔术师约翰逊,成为了控球后卫这
两败了!樊振东又输球,小黑马战胜上海直板名将北京时间2021年10月8日,乒超联赛第6天的争夺持续来袭,今天,樊振东林高远梁靖崑许昕孙颖莎陈梦等奥运冠军世界冠军都将悉数登场,比赛绝对精彩刺激。山东魏桥vs汕头明润首盘双打世界华为Mate50渲染图曝光麒麟9010震撼镜头,配备手写笔支持5G按照往年的节奏,今年的10月应该是华为发布Mate系列旗舰华为Mate50系列的时间点。然而,原因大家都知道,华为面临的卡脖子技术导致华为Mate50系列能否如约而至仍然是个谜。很大家不要被忽悠了,大衣哥儿子儿媳闹别扭纯属炒作最近几天,大衣哥儿子儿媳闹矛盾的消息传的沸沸扬扬,很多人都认为亚男已经变心,其实完全不是那么回事。我说这话你可能不以为然,因为种种迹象表明,大衣哥的儿媳亚男已经想甩掉小伟单飞,这种长津湖抛围巾女孩,用5秒钟惊艳观众,却因一场戏得罪尔冬升随着长津湖这部影片的热度越来越高,很多观众都开始发掘这部影片中的一些细节。大部分的关注点还是放在了主要演员的身上。但往往看完了影片之后意犹未尽,还要反过来从预告片中再去寻找惊喜。不965亿美金!快船大佬又霸榜,詹皇前东家老板1年狂赚234亿北京时间10月8日,福布斯杂志在近日公布了2021年美国400大富豪榜单。快船老板鲍尔默在全美所有富豪当中排名第九,同时在全美体育球队老板当中排名第一。这是鲍尔默连续第七年称霸体育3200亿英镑!纽卡新老板成足坛首富,资产是曼城老板的10多倍此前报道英超又要产生一豪门?沙特财团3亿英镑收购纽卡斯尔联英超纽卡斯尔联俱乐部官方宣布沙特公共投资公司收购了纽卡,随后纽卡球迷就沸腾了,许多球迷都开始畅想球队的下赛季。而纽卡新的高粤产剧夺金央视热播,总制片人刘军我们邀请了所有能想到的乒乓球国手文羊城晚报全媒体记者龚卫锋无论是东京奥运会乒乓球赛上中国队豪取四金,还是最近全运会乒乓球赛上的世界级对决,小小的乒乓球总能轻松点燃国人的激情。网友的评价朴实又振奋你可以永远相信中国许昕当官,马龙或接班刘国梁,刘诗雯将去向何处?刘国梁自有安排北京时间的10月3日,国际乒联对外宣布了一个重要的决定,国乒奥运冠军,名将许昕当选为为亚乒联副主席。说到许昕,很多网友和球迷都喜欢称呼他为人民艺术家,因为许昕在球场上经常能够为观众两场砍50分!一人完爆火箭双少,13顺位又出天才?难怪保罗换不来北京时间10月8日,NBA季前赛继续进行,今天火箭坐镇主场迎来了热火的挑战,作为休赛期人员变动较大的两支球队,这场比赛也是吸引了不少球迷的关注,热火在休赛期拿下了洛瑞塔克和大莫里斯榜眼20分惜败,黄蜂新秀连续爆发,灰熊两新秀表现差劲今天只有两场季前赛,火箭榜眼杰伦格林也有出场,并且表现出色,跟巴特勒同场竞技。榜眼秀面对热火队打出不俗的战绩,出场28分钟15中6得到20分5篮板2助攻3抢断,其中包括4个三分球,起诉维权车主后,疑似一辆特斯拉再发生自燃,旁边车辆又遭殃经历了刹车门事件后,对特斯拉的影响,确实也没有想象中的那么大。近几个月,从销量情况上来看,特斯拉确实有所下降。不过需要说明的是,特斯拉的批发量仍然是居高不下的。上海工厂所生产的车,