首页 文章 精选 留言 我的

精选列表

搜索[时间范围],共10000篇文章
优秀的个人博客,低调大师

Android Path Time ScrollBar(Path 时间轴)

版本号:1.0 日期:2014.4.22 版权:© 2014 kince 转载注明出处 这是仿Path2.0UI的一个demo的截图,我最早是在农民伯伯的这篇博客中看到的 【Andorid X 项目笔记】开源项目使用(6) ,他说这个程序是反编译Path的。可是这次我特地看了一下代码,发现事实上不是这种。原帖地址应该是这个: http://www.eoeandroid.com/forum.php?mod=viewthread&tid=187725 ,作者使用的是github上的一个开源项目: Android-ScrollBarPanel ,它实现的效果例如以下: 已经非常接近Path的效果了。还有墨迹天气的实景也是使用了这种效果: 并且,墨迹天气用的也是这个开源项目。效果什么基本都没改。所以以下重点说一下这个开源项目的实现。 在看它的代码之前先来分析一下这个效果该怎样实现,它就是在滚动栏(scrollbar)的旁边动态显示一个View。这个View里面显示的内容会随着滚动栏的位置变化而变化。一般像带滑动效果的容器控制都会有滚动栏,比方ScrollView、ListView、GeidView等。那这个滚动栏究竟是什么呢?它是一个View的属性,该属性是继承view的, 目的设置滚动栏显示。有以下设置none(隐藏)。horizontal(水平),vertical (垂直)。并非全部的view设置就有效果。 LinearLayout 设置也没有效果。 要想在超过一屏时拖动效果,在最外层加上ScrollView。并且能够自己定义滚动栏的样式和位置。但Path用的并非自己定义的滚动栏,它是在滚动栏旁边加的View。如图: 若是在滚动栏的旁边加入显示View,首先须要获取滚动栏的位置,当在滑动的时候在显示滚动栏的同一时候也让加入的View显示出来,也就是说它和滚动栏的显示是同步的。 那究竟怎样实现呢。带着这些疑问看一下源代码: package com.dafruits.android.library.widgets; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.os.Handler; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; import android.view.ViewConfiguration; import android.view.animation.Animation; import android.view.animation.Animation.AnimationListener; import android.view.animation.AnimationUtils; import android.widget.AbsListView; import android.widget.AbsListView.OnScrollListener; import android.widget.ListView; import com.dafruits.android.library.R; public class ExtendedListView extends ListView implements OnScrollListener { public static interface OnPositionChangedListener { public void onPositionChanged(ExtendedListView listView, int position, View scrollBarPanel); } private OnScrollListener mOnScrollListener = null; private View mScrollBarPanel = null; private int mScrollBarPanelPosition = 0; private OnPositionChangedListener mPositionChangedListener; private int mLastPosition = -1; private Animation mInAnimation = null; private Animation mOutAnimation = null; private final Handler mHandler = new Handler(); private final Runnable mScrollBarPanelFadeRunnable = new Runnable() { @Override public void run() { if (mOutAnimation != null) { mScrollBarPanel.startAnimation(mOutAnimation); } } }; /* * keep track of Measure Spec */ private int mWidthMeasureSpec; private int mHeightMeasureSpec; public ExtendedListView(Context context) { this(context, null); } public ExtendedListView(Context context, AttributeSet attrs) { this(context, attrs, android.R.attr.listViewStyle); } public ExtendedListView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); super.setOnScrollListener(this); final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ExtendedListView); final int scrollBarPanelLayoutId = a.getResourceId(R.styleable.ExtendedListView_scrollBarPanel, -1); final int scrollBarPanelInAnimation = a.getResourceId(R.styleable.ExtendedListView_scrollBarPanelInAnimation, R.anim.in_animation); final int scrollBarPanelOutAnimation = a.getResourceId(R.styleable.ExtendedListView_scrollBarPanelOutAnimation, R.anim.out_animation); a.recycle(); if (scrollBarPanelLayoutId != -1) { setScrollBarPanel(scrollBarPanelLayoutId); } final int scrollBarPanelFadeDuration = ViewConfiguration.getScrollBarFadeDuration(); if (scrollBarPanelInAnimation > 0) { mInAnimation = AnimationUtils.loadAnimation(getContext(), scrollBarPanelInAnimation); } if (scrollBarPanelOutAnimation > 0) { mOutAnimation = AnimationUtils.loadAnimation(getContext(), scrollBarPanelOutAnimation); mOutAnimation.setDuration(scrollBarPanelFadeDuration); mOutAnimation.setAnimationListener(new AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationRepeat(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { if (mScrollBarPanel != null) { mScrollBarPanel.setVisibility(View.GONE); } } }); } } @Override public void onScrollStateChanged(AbsListView view, int scrollState) { if (mOnScrollListener != null) { mOnScrollListener.onScrollStateChanged(view, scrollState); } } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { if (null != mPositionChangedListener && null != mScrollBarPanel) { // Don't do anything if there is no itemviews if (totalItemCount > 0) { /* * from android source code (ScrollBarDrawable.java) */ final int thickness = getVerticalScrollbarWidth(); int height = Math.round((float) getMeasuredHeight() * computeVerticalScrollExtent() / computeVerticalScrollRange()); int thumbOffset = Math.round((float) (getMeasuredHeight() - height) * computeVerticalScrollOffset() / (computeVerticalScrollRange() - computeVerticalScrollExtent())); final int minLength = thickness * 2; if (height < minLength) { height = minLength; } thumbOffset += height / 2; /* * find out which itemviews the center of thumb is on */ final int count = getChildCount(); for (int i = 0; i < count; ++i) { final View childView = getChildAt(i); if (childView != null) { if (thumbOffset > childView.getTop() && thumbOffset < childView.getBottom()) { /* * we have our candidate */ if (mLastPosition != firstVisibleItem + i) { mLastPosition = firstVisibleItem + i; /* * inform the position of the panel has changed */ mPositionChangedListener.onPositionChanged(this, mLastPosition, mScrollBarPanel); /* * measure panel right now since it has just changed * * INFO: quick hack to handle TextView has ScrollBarPanel (to wrap text in * case TextView's content has changed) */ measureChild(mScrollBarPanel, mWidthMeasureSpec, mHeightMeasureSpec); } break; } } } /* * update panel position */ mScrollBarPanelPosition = thumbOffset - mScrollBarPanel.getMeasuredHeight() / 2; final int x = getMeasuredWidth() - mScrollBarPanel.getMeasuredWidth() - getVerticalScrollbarWidth(); mScrollBarPanel.layout(x, mScrollBarPanelPosition, x + mScrollBarPanel.getMeasuredWidth(), mScrollBarPanelPosition + mScrollBarPanel.getMeasuredHeight()); } } if (mOnScrollListener != null) { mOnScrollListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount); } } public void setOnPositionChangedListener(OnPositionChangedListener onPositionChangedListener) { mPositionChangedListener = onPositionChangedListener; } @Override public void setOnScrollListener(OnScrollListener onScrollListener) { mOnScrollListener = onScrollListener; } public void setScrollBarPanel(View scrollBarPanel) { mScrollBarPanel = scrollBarPanel; mScrollBarPanel.setVisibility(View.GONE); requestLayout(); } public void setScrollBarPanel(int resId) { setScrollBarPanel(LayoutInflater.from(getContext()).inflate(resId, this, false)); } public View getScrollBarPanel() { return mScrollBarPanel; } @Override protected boolean awakenScrollBars(int startDelay, boolean invalidate) { final boolean isAnimationPlayed = super.awakenScrollBars(startDelay, invalidate); if (isAnimationPlayed == true && mScrollBarPanel != null) { if (mScrollBarPanel.getVisibility() == View.GONE) { mScrollBarPanel.setVisibility(View.VISIBLE); if (mInAnimation != null) { mScrollBarPanel.startAnimation(mInAnimation); } } mHandler.removeCallbacks(mScrollBarPanelFadeRunnable); mHandler.postAtTime(mScrollBarPanelFadeRunnable, AnimationUtils.currentAnimationTimeMillis() + startDelay); } return isAnimationPlayed; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); if (mScrollBarPanel != null && getAdapter() != null) { mWidthMeasureSpec = widthMeasureSpec; mHeightMeasureSpec = heightMeasureSpec; measureChild(mScrollBarPanel, widthMeasureSpec, heightMeasureSpec); } } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); if (mScrollBarPanel != null) { final int x = getMeasuredWidth() - mScrollBarPanel.getMeasuredWidth() - getVerticalScrollbarWidth(); mScrollBarPanel.layout(x, mScrollBarPanelPosition, x + mScrollBarPanel.getMeasuredWidth(), mScrollBarPanelPosition + mScrollBarPanel.getMeasuredHeight()); } } @Override protected void dispatchDraw(Canvas canvas) { super.dispatchDraw(canvas); if (mScrollBarPanel != null && mScrollBarPanel.getVisibility() == View.VISIBLE) { drawChild(canvas, mScrollBarPanel, getDrawingTime()); } } @Override public void onDetachedFromWindow() { super.onDetachedFromWindow(); mHandler.removeCallbacks(mScrollBarPanelFadeRunnable); } } 通过阅读源代码发现,这是一个自己定义的ListView,并且继承了OnScrollListener接口。这个接口是在AbsListView.java里面定义的。主要是负责滑动事件的处理,它的代码例如以下: /** * Interface definition for a callback to be invoked when the list or grid * has been scrolled. */ public interface OnScrollListener { /** * The view is not scrolling. Note navigating the list using the trackball counts as * being in the idle state since these transitions are not animated. */ public static int SCROLL_STATE_IDLE = 0; /** * The user is scrolling using touch, and their finger is still on the screen */ public static int SCROLL_STATE_TOUCH_SCROLL = 1; /** * The user had previously been scrolling using touch and had performed a fling. The * animation is now coasting to a stop */ public static int SCROLL_STATE_FLING = 2; /** * Callback method to be invoked while the list view or grid view is being scrolled. If the * view is being scrolled, this method will be called before the next frame of the scroll is * rendered. In particular, it will be called before any calls to * {@link Adapter#getView(int, View, ViewGroup)}. * * @param view The view whose scroll state is being reported * * @param scrollState The current scroll state. One of {@link #SCROLL_STATE_IDLE}, * {@link #SCROLL_STATE_TOUCH_SCROLL} or {@link #SCROLL_STATE_IDLE}. */ public void onScrollStateChanged(AbsListView view, int scrollState); /** * Callback method to be invoked when the list or grid has been scrolled. This will be * called after the scroll has completed * @param view The view whose scroll state is being reported * @param firstVisibleItem the index of the first visible cell (ignore if * visibleItemCount == 0) * @param visibleItemCount the number of visible cells * @param totalItemCount the number of items in the list adaptor */ public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount); } OnScrollListener定义了三个常量。分别表示当屏幕停止滚动时为0;当屏幕滚动且用户使用的触碰或手指还在屏幕上时为1;由于用户的操作。屏幕产生惯性滑动时为2。详细解释例如以下: new OnScrollListener() { boolean isLastRow = false; @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { //滚动时一直回调,直到停止滚动时才停止回调。单击时回调一次。 //firstVisibleItem:当前能看见的第一个列表项ID(从0開始) //visibleItemCount:当前能看见的列表项个数(小半个也算) //totalItemCount:列表项共数 //推断是否滚到最后一行 if (firstVisibleItem + visibleItemCount == totalItemCount && totalItemCount > 0) { isLastRow = true; } } @Override public void onScrollStateChanged(AbsListView view, int scrollState) { //正在滚动时回调,回调2-3次,手指没抛则回调2次。 scrollState = 2的这次不回调 //回调顺序例如以下 //第1次:scrollState = SCROLL_STATE_TOUCH_SCROLL(1) 正在滚动 //第2次:scrollState = SCROLL_STATE_FLING(2) 手指做了抛的动作(手指离开屏幕前,用力滑了一下) //第3次:scrollState = SCROLL_STATE_IDLE(0) 停止滚动 //当屏幕停止滚动时为0;当屏幕滚动且用户使用的触碰或手指还在屏幕上时为1。 //由于用户的操作,屏幕产生惯性滑动时为2 //当滚到最后一行且停止滚动时,运行载入 if (isLastRow && scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE) { //载入元素 ...... isLastRow = false; } } } 了解完OnScrollListener这个接口再回头看一下代码,首先定义了一个回调: public static interface OnPositionChangedListener { public void onPositionChanged(ExtendedListView listView, int position, View scrollBarPanel); } 这个用来在Activity中设置监听事件的,Activity的代码例如以下: package com.dafruits.android.samples; import android.app.Activity; import android.graphics.Color; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.TextView; import com.dafruits.android.library.widgets.ExtendedListView; import com.dafruits.android.library.widgets.ExtendedListView.OnPositionChangedListener; public class DemoScrollBarPanelActivity extends Activity implements OnPositionChangedListener { private ExtendedListView mListView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mListView = (ExtendedListView) findViewById(android.R.id.list); mListView.setAdapter(new DummyAdapter()); mListView.setCacheColorHint(Color.TRANSPARENT); mListView.setOnPositionChangedListener(this); } private class DummyAdapter extends BaseAdapter { private int mNumDummies = 100; @Override public int getCount() { return mNumDummies; } @Override public Object getItem(int position) { return position; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null) { convertView = LayoutInflater.from(DemoScrollBarPanelActivity.this).inflate(R.layout.list_item, parent, false); } TextView textView = (TextView) convertView; textView.setText("" + position); return convertView; } } @Override public void onPositionChanged(ExtendedListView listView, int firstVisiblePosition, View scrollBarPanel) { ((TextView) scrollBarPanel).setText("Position " + firstVisiblePosition); } } 接着看一下第三个构造方法,由于这个自己定义的ListView定义了自己的属性。所以须要从attrs文件里来取出这些属性。自己定义的属性包含三个部分,一是在ListView滑动时弹出的View,二是这个View弹出时的动画,三是这个View消失时的动画。然后開始设置这个弹出的View: if (scrollBarPanelLayoutId != -1) { setScrollBarPanel(scrollBarPanelLayoutId); } 看一下设置的方法。 public void setScrollBarPanel(View scrollBarPanel) { mScrollBarPanel = scrollBarPanel; mScrollBarPanel.setVisibility(View.GONE); requestLayout(); } public void setScrollBarPanel(int resId) { setScrollBarPanel(LayoutInflater.from(getContext()).inflate(resId, this, false)); } 先是调用以下这种方法。从xml文件里载入弹出View的布局,在这个地方须要说一下假设自己定义的View不须要手动绘制的话,那么就能够使用LayoutInflater去在xml中载入一个已经配置好的视图,本例中就是使用这个方式。这样mScrollBarPanel就储存了弹出的View。然后设置为不可见。使用requestLayout()刷新一下视图。再接着就是载入两个弹出的动画。特别的。在mOutAnimation动画中设置了监听器,在动画结束的时候设置弹出的View不可见。 回到第三个构造方法中,在第二行设置了super.setOnScrollListener(this),这种方法是效果实现的关键。为什么这么说。先看一下它的源代码。 它是在AbsListView中定义的。 /** * Set the listener that will receive notifications every time the list scrolls. * * @param l the scroll listener */ public void setOnScrollListener(OnScrollListener l) { mOnScrollListener = l; invokeOnItemScrollListener(); }设置这种方法后,会传递一个 OnScrollListener对象给 mOnScrollListener,然后调用 invokeOnItemScrollListener()方法,它的代码例如以下: /** * Notify our scroll listener (if there is one) of a change in scroll state */ void invokeOnItemScrollListener() { if (mFastScroller != null) { mFastScroller.onScroll(this, mFirstPosition, getChildCount(), mItemCount); } if (mOnScrollListener != null) { mOnScrollListener.onScroll(this, mFirstPosition, getChildCount(), mItemCount); } onScrollChanged(0, 0, 0, 0); // dummy values, View's implementation does not use these. } 假设mOnScrollListener不为空的话,就调用mOnScrollListener的onScroll方法。而onScroll方法正是OnScrollListener接口定义的抽象方法,由于我们在ListView中继承了OnScrollListener接口,重载了onScroll方法,所以将会调用我们自己实现的onScroll方法。就是这样一个流程。 然后看一下onScroll方法的实现, @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { Log.i("onScroll", "onScroll"); if (null != mPositionChangedListener && null != mScrollBarPanel) { // Don't do anything if there is no itemviews if (totalItemCount > 0) { /* * from android source code (ScrollBarDrawable.java) */ final int thickness = getVerticalScrollbarWidth(); int height = Math.round((float) getMeasuredHeight() * computeVerticalScrollExtent() / computeVerticalScrollRange()); int thumbOffset = Math .round((float) (getMeasuredHeight() - height) * computeVerticalScrollOffset() / (computeVerticalScrollRange() - computeVerticalScrollExtent())); final int minLength = thickness * 2; if (height < minLength) { height = minLength; } thumbOffset += height / 2; /* * find out which itemviews the center of thumb is on */ final int count = getChildCount(); for (int i = 0; i < count; ++i) { final View childView = getChildAt(i); if (childView != null) { if (thumbOffset > childView.getTop() && thumbOffset < childView.getBottom()) { /* * we have our candidate */ if (mLastPosition != firstVisibleItem + i) { mLastPosition = firstVisibleItem + i; /* * inform the position of the panel has changed */ mPositionChangedListener.onPositionChanged( this, mLastPosition, mScrollBarPanel); /* * measure panel right now since it has just * changed * * INFO: quick hack to handle TextView has * ScrollBarPanel (to wrap text in case * TextView's content has changed) */ measureChild(mScrollBarPanel, mWidthMeasureSpec, mHeightMeasureSpec); } break; } } } /* * update panel position */ mScrollBarPanelPosition = thumbOffset - mScrollBarPanel.getMeasuredHeight() / 2; final int x = getMeasuredWidth() - mScrollBarPanel.getMeasuredWidth() - getVerticalScrollbarWidth(); mScrollBarPanel.layout( x, mScrollBarPanelPosition, x + mScrollBarPanel.getMeasuredWidth(), mScrollBarPanelPosition + mScrollBarPanel.getMeasuredHeight()); } } if (mOnScrollListener != null) { mOnScrollListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount); } } 上面已经说到。这个onScroll是随着滑动而一直调用的,而我们的需求就是在滑动的时候弹出一个View来。所以这种方法正是处理问题的关键位置。能够在这里绘制弹出View的视图。从上面的代码也能够看出,就是在这里进行弹出View大小的计算以及位置的设定等。 最后就是之前说的自己定义ViewGroup的问题了。重载onMeasure()、onLayout()、ondispatchDraw()方法了,这个在本例中也是有所体现的,只是都比較简单,相信都看得懂。 可是这几个方法都是在View初始化的时候调用的,并且仅仅是调用一次。这样并不适合动态的绘制视图。所以这也是为什么本样例继承了OnScrollListener,然后在其onScroll方法中去绘制视图。由于onScroll方法在滑动的时候会调用,所以在滑动的时候就会绘制视图了。 因此也能够看出本例採用的是动态画图的方式,不是显示隐藏的方式。 本文转自mfrbuaa博客园博客,原文链接:http://www.cnblogs.com/mfrbuaa/p/5396685.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

黑科技揭秘:网红“天空物联网飞艇”服务范围为何能突破30公里

2018杭州云栖大会的网红飞艇,搭载LoRaWAN网关,与地面网关一起组成上天入地的天空物联网服务,获得众多关注。其最主要的核心是Link WAN物联网络管理平台,提供了网关管理与设备快数接入云端,使得飞艇挂载网关十分容易。 今年,阿里云IoT事业部宣布与浙江联通共同建设LoRaWAN城域网,采用了自主研发的Link WAN物联网络管理平台,这是阿里巴巴加入LoRa联盟后的产业链布局之一,Link WAN也成为了国内重要的LoRaWAN接入平台,既能兼容国际标准,也能支持大规模、高并发的接入需求。 LoRa技术是什么? 2012年Semtech收购了拥有LoRa IP的法国公司Cycleo,2013年8月,Semtech向业界发布了名为LoRa的一种新型Sub-1GHz频段的扩频通信芯片,最高接收灵敏度可达-148dBm,主攻远距离低功

优秀的个人博客,低调大师

高通发布三款低端手机芯片 蚕食联发科势力范围

美国高通和中国台湾联发科,是全球最大两家手机芯片厂商,高通和联发科分别控制高端和中低端市场,不过近年来,双方各自向对方的地盘渗透。日前,高通对外发布了三款入门级中低端手机系统芯片,或将对联发科造成一定压力。 虽然高通获得了PC时代英特尔的强势地位,但是从市场表现来看,全球智能手机增长最快的市场是发展中国家的安卓廉价机,增长最猛的是销售廉价安卓机的“中国高性价比军团”,而联发科也更为受益。 作为对比,因为骁龙810过热风波,高通在2015年遭遇低迷,股价暴跌,被迫实施大裁员。2016年,高通希望借助骁龙820高端芯片,重振旗鼓。 据国外科技新闻网站Digital Trends,高通同样在关注中低端手机芯片市场,日前发布三款整合型系统芯片骁龙625(中端),骁龙435和骁龙425(低端)。 除了廉价手机之外,这些处理器同样可以被用于新兴的虚拟现实头盔、增强现实头盔领域。 这三款廉价芯片均支持接入LTE网络,此外支持高通的“骁龙All Mode”的技术。在Wi-Fi联网方面,三款芯片支持802.11ac协议,以及MU-MIMO通讯模式。 据报道,这三款芯片能够支持谷歌最新的安卓6.0操作系统,另外通过整合的Hexagon DSP芯片,也能够支持高效的音频处理。 另外,在芯片引脚方面,骁龙435和骁龙425和过去的骁龙430芯片保持一致,这意味着低端手机的制造商,可以在不改变手机设计方案的条件下,升级使用这两款新处理器。 此外,三款芯片也能够实现更长的电池续航能力。 对于新版本的骁龙625,高通表示其在处理性能上有巨大提升,其中高通采用了14纳米FinFET半导体制造工艺,能够降低35%的电耗。 新版骁龙625系统芯片,采用八核心ARM Cortex-A53架构处理器,整合了X9 LTE通信芯片,支持4G+,另外上网速度也比过去的产品提高了三倍。 据报道,在2016年年中,高通将会把三款芯片的样品提供给手机制造商,而采用这些处理器的智能手机,有望在2016年的下半年上市。 传统的手机芯片市场格局,已经发生变化,新格局被行业形容为“联发科,上不去;高通,下不来”。不过,面对当前的一系列困境,高通必须彻底打通“下行管道”,开拓安卓中低端手机的庞大市场。 去年九月份,高通也曾经推出两款中低端芯片,分别是骁龙430和骁龙617。 在2015年,高通的移动芯片业务陷入了一场危机。华尔街和股东向高通施压,要求将已经成为“鸡肋”的芯片业务和利润丰厚的专利授权业务进行分拆剥离。 除了骁龙810成为“哑炮”之外,智能手机企业自行研发芯片,正在让高通成为可有可无的角色。比如三星电子在去年的旗舰手机中成功整合了自家处理器,华为的麒麟处理器也获得不错的行业评价。据称,小米也准备效仿三星、苹果和华为,研发ARM架构的处理器。 面对市场异动,高通已经开始考虑“下一步”,比如和中国地方政府合作,研发服务器处理器,另外开始布局无人机专用芯片、物联网芯片等。 本文转自d1net(转载)

优秀的个人博客,低调大师

SpaceX高管称Starlink可以扩大服务范围 为3000万美国人提供服务

根据太空探索技术公司(SpaceX)卫星政策总监David Goldman先生本月早些时候向联邦通信委员会提交的报告,该公司的卫星互联网服务Starlink不会完全排除在城市地区提供覆盖,尽管它旨在优化农村和服务不足地区的服务。 在最新的文稿中,SpaceX的高管向委员会概述了互联网服务可以扩大运营规模,向目前完全没有互联网覆盖或没有得到服务的3000万美国人提供数据连接。他还批评了RS Access等公司有关卫星通信的研究,称其对卫星互联网做了过度的限制性假设,采用了"偷梁换柱"的信息并使用不代表现实世界性能的数据。Starlink公司声称,MVDDS许可证持有者是"频谱囤积者",不提供有用的消费者服务。 Goldman的言论是以本月初与委员会官员会面时提出的演讲形式出现的。在这份报告中,这位SpaceX高管将枪口对准了RS Access提交的、由RKF Engineering Solutions进行的一项研究。该研究旨在证明多频道视频数据分配(MVDDS)服务提供商和非对地固定卫星服务(NGSO FSS)提供商可以使用12GHz频段,而不会严重影响彼此的服务。 这项研究旨在反驳DISH公司几年前提交的一份研究报告,该报告声称卫星公司无法在12GHz频段与其他公司共存。然而,Goldman认为,它在几个方面存在缺陷,因为它依赖于偷梁换柱的数据,虚假的农村和城市的划分,不准确的假设,最终描述了MVDDS供应商对卫星互联网用户的重大干扰。 针对RS Access的研究,SpaceX的高德曼表示,该报告严重低估了未来对卫星互联网的需求 RKF研究中使用的一个假设是,即使Starlink采用了250万个用户终端,来自MVDDS 5G供应商的干扰也会很小,因为卫星终端将服务于农村地区,而5G终端将位于城市地区。 在对该研究的详细反驳中,SpaceX的高德曼反驳了这一假设,他说:在模型设置的250万个用户终端中(一个不完全准确的较低估算),只有14600个被放置在"大都市"农村数字机会基金地区,其余的都在"非大都市"和农村地区,研究报告和RS Access、DISH以及其他MVDDS许可证持有者都承认他们永远不会打算部署这些终端。也就是说,研究报告假设99.4%的NGSO FSS用户终端将部署在这种农村地区。这根本不能反映现实。虽然SpaceX的Starlink系统将为数百万美国人带来服务,这些人目前没有得到现有的宽带服务或服务不足,包括在MVDDS持牌人显然无意服务的农村地区。鉴于他们的历史,这本身就是一个可疑的命题:SpaceX被授权提供并正在提供面向整个美国的竞争宽带服务,这肯定会与任何理论上的地面建设重叠。事实上,SpaceX现有的Starlink订单中已经有很大一部分来自城市地区。 RKF研究报告中关于分配Starlink用户终端的理由,第3行显示了SpaceX没有赢得资金但还是部署了服务的地区的Starlink终端 此外,Goldman在演讲中还表示,Starlink可以扩大服务规模,为没有服务和服务不足的美国人提供互联网连接。据他说,全美国大约有3000万人缺乏足够的互联网覆盖,"Starlink的架构可以扩展到支持美国未得到服务和服务不足的人口,包括农村、郊区和城市。" 此外,他还抨击了Brattle集团与RKF的技术研究一起提交的经济研究,这项研究声称,开放12GHz频段供5G使用可以提供价值1万亿美元的经济效益。 Starlink公司目前正在准备发射其第一阶段Starlink卫星的第二批,第一阶段由大约4400个航天器组成,其中大部分位于较低的倾角。

资源下载

更多资源
Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册