MVP怎么弄的,骂女生傻叼深刻意思都能当mvp了

谷歌官方MVP框架源码解析之 TODO-MVP - 简书
谷歌官方MVP框架源码解析之 TODO-MVP
这段时间在了解MVP的框架 网上也有一些示例写的也很好 正巧看到官方也推出了基于MVP的示例Demo 所以想试着了解下 顺便写下此笔记
其实网上也已经有对MVP进行了解析的文章说的也很好 但是关于M方面不是很理解 所以自己试着解析下
先上一张图MVP的结构图
什么是MVP ? 为什么使用MVP 他有什么优缺点 ? 这里我就不赘述了
想更多的是解释示例MVP的代码官方给出的示例MVP流程图
现在看着可能似懂非懂 这样我们先 Read the fucking source code 再回来看图!
项目在GitHub上面有 先看下目录结构
可以看出分包是根据模块进行的分包
首先是View 和 Presenter 的基类
定义start setPresenter 方法 什么作用下面说
接下来是Model 这个可能跟View 的基类什么的还不是太一样 因为接下来的所有的Presenter都用同时用到它
这里面谷歌还弄了一个叫做契约类的东东
是一个接口 定义内部接口继承View 和Persenter基类定义方法 到时候V 和 P 直接实现这里面的接口就可以了 并且有什么方法都会在这里 确实是看方法的时候简洁明了
那么下面我们就开始首先是进入主TasksActivity 我们只看主要代码其他初始化控件什么的就不看了
可以看到 onCreate方法里面 显示直接创建TasksFragment对象 并且添加到了Activity并且TasksFragment 是直接实现的契约类的TasksContract.View基类
接下来创建TasksPresenter对象 并且传入了TasksFragment对象和 Model对象 这里的Model先这么记得 因为它里面并不是那么简单小总结:1实现类并不是直接实现的基类 而是创建了一个契约类来实现 来更好的管理实现类中的方法2 这里面的Activity并不是我们MVP中对应的V 而是Fragment Activity只是负责管理创建 V P M 的对象使他们相互关联 从而达到相互调用既然TasksFragment 和 TasksPresenter 对象都已经创建了 我们就进去看看里面是怎么实现的TasksPresenter
实现TasksContract.Presenter契约类接口 在构造里面接受 Model 和 View 的对象,并且调用了View 的setPresenter方法 并且把自己的引用传了进去 这就是上面基类定义的方法,这样Presenter就有了View的引用 View也有了Presenter的引用。
还可以看到下面 实现了start方法 并且调用了 loadTasks方法 这个方法其实是用来加载数据使用的 一会在说是谁调用他的 和他的调用时机。TasksFragment
我们在回头看TasksFragment的实现
可以看到onResume方法里面调用了Presenter的start方法 就是当界面可见并且运行起来的时候 调用start方法 在调用刚才上面说的loadTasks加载数据还可以看到我们实现的setPresenter 接受了Persneter引用小总结:1 Presenter 拿到View引用
调用setPresenter传入自己的引用, View在拿到Presenter引用 在生命周期方法onResume中调用start方法加载数据 接下来我们在看loadTasks方法的实现 因为屏幕小截图不够一张 原谅我多截几张(手动调皮脸)
调用了TasksRepository的getTasks 方法 那么现在我们就要说一下这个TasksRepository的引用是怎么回事了还记得刚开始的时候 我们通过构造传入进来的TasksRepository对象是怎么生成的么
其实是调用了上面这个的类的方法
并在再返回的时候 创建了 TasksRepository 的对象 并传入了
FakeTasksRemoteDataSource 和 TasksLocalDataSource 的引用 才返回的 那么我们进入去看看
这个里面引用到底是什么
搞清了他 一会我们在看getTasks 方法的时候才能看懂再看下Data的目录结构
可以看到 这两个引用 和我们的Model对象都是实现了 我们刚开始定义的Model基类 现在可以说明的一点就是这几个类都是提供数据的 并且这些类都实现了 getTask方法FakeTasksRemoteDataSource 类描述 :Implementation of a remote data source with static access to the data for easy testing.
大概的意思就是 用来实现静态的远程数据访问测试哦 跟咱们猜的差不多 提供数据的
但是他是提供远程数据源的
也就是模拟我们在网上获取数据的
只是获取数据的一种方式getTask方法
从一个Map中获取数据
TasksLocalDataSource类描述:Concrete implementation of a data source as a db.哦
又猜的一样
是一个基于数据库的数据源
又是一种获取数据的方法这里面的getTask也是一样获取数据 代码太多 就不贴了那么我们现在搞明白了这两个引用分别都是以不同方式来模拟获取数据的 并且还传入到了TasksRepository中 那这时候我们就来看看TasksRepository的getTask是怎么实现的
接受LoadTasksCallback 对象 这个其实是刚开始声明在Model基类中的 内部接口声明了两个方法
其实就相当于我们的 请求数据成功和失败一样
然后判断缓存是否存在 和缓存是否可用
如果都可用 那么回掉接口方法 并且把缓存的数据全部取出来返回然后判断缓存是否可用 不可用 调用getTasksFromRemoteDataSource 方法可以看到里面调用了 上面我们传入给TasksRepository中的 远程数据获取的引用 并且调用了getTask方法 获取数据
如果获取成功 添加缓存 并且添加本地 在回掉成功 传入数据
如果可用 会调用获取 本地数据源引用的getTask方法 加载数据 成功的话在添加到缓存 然后成功回掉这时候 我们看他会调成功后 循环 根据任务类型进行添加数据 最后调用 processTasks 方法 传入数据 如果数据没问题 就调用TasksFragment的showTasks方法 展示数据到此为止 这个流程就是走完了
这时候 我们在来看看 上面官方给出的图 右边 首先是由Activity管理 View也就是Fragment
和Presenter 的创建和关联
然后再让Model和 Perstnter相互引用
左边 可以看到Model本身有缓存机制
并且分别创建了 本地数据源 和远程数据源 最后其实官方的示例中还涉及到了测设部分 因为不太了解 就不做重点了解了 其实官方给我们 只是一种示例 我们不一定非要用Framgent当View
也不一定非要把Model写成这种模式 但是这种方法感觉也还是值得借鉴的
我们也可以根据我们项目的自身需求 来编写不同写法 希望大家不要被具体的代码所困住
本篇到此就结束了
总的来说代码还是很简单的 不过还是要多多使用才能更加深刻的理解MVP 好了 希望大家不喜勿喷 有错误的地方还请多指教 再见
欢迎关注我的GitHub16123人阅读
Android MVP(1)
转载请标明出处:
中我简单的介绍了mvp,以及怎么写mvp。我自己也将mvp运用到了项目中,其实mvp并没有固定的写法,正确的去理解架构的思想,都可以有自己独特的mvp写法。git上也有很多例子,比如google的,simple哥的Android 源码设计模式解析与实战中也有mvp的讨论。这里参考了simple哥做了一个通用版的mvp,并对google的MVP做了一点自己的解析。
关于presenter一直持有Activity对象导致的内存泄漏问题
只要用过mvp这个问题可能很多人都知道。写mvp的时候,presenter会持有view,如果presenter有后台异步的长时间的动作,比如网络请求,这时如果返回退出了Activity,后台异步的动作不会立即停止,这里就会有内存泄漏的隐患,所以会在presenter中加入一个销毁view的方法。现在就在之前的项目中做一下修改
public void onDestroy(){
mvpView = null;
protected void onDestroy() {
mvpPresenter.onDestroy();
super.onDestroy();
presenter中增加了类似的生命周期的方法,用来在退出Activity的时候取消持有Activity。
但是在销毁后需要思考一点,后台的延时操作返回时,这个时候view被销毁了,如果接着去调用view的方法就
会抛出空指针异常。所以在后台的延时操作中需要考虑到这种可能产生空指针的情况,尤其是网络请求。
BasePresenter
如果每一个Activity都需要做绑定和解绑操作就太麻烦了,现在我希望可以有一个通用的presenter来为我们添加view的绑定与销毁。
public abstract class BasePresenter&T& {
public T mV
public void attach(T mView) {
this.mView = mV
public void dettach() {
mView = null;
因为不能限定死传入的View,所以使用泛型来代替传入的对象。通过这个通用的presenter我就可以把原来的简化成下面的样子
public class NewMvpPresenter extends BasePresenter&NewMvpView& {
private RequestBiz requestB
private Handler mH
public NewMvpPresenter() {
requestBiz = new RequestBiziml();
mHandler = new Handler(Looper.getMainLooper());
public void onResume(){
requestBiz.requestForData(new OnRequestListener() {
public void onSuccess(final List&String& data) {
mHandler.post(new Runnable() {
public void run() {
mView.hideLoading();
mView.setListItem(data);
public void onFailed() {
mView.showMessage("请求失败");
public void onItemClick(int position){
mView.showMessage("点击了item"+position);
界面需要提供的UI方法中会有很多类似的UI方法,可以把它们提取到一个公共的父类接口中。比如提取显示loading界面和隐藏loading界面的方法,其他的view层接口就可以直接继承BaseView接口,不必重复的写显示和隐藏loading界面方法。
public interface BaseView {
void showLoading();
void hideLoading();
BaseMvpActivity
presenter绑定到activity和View的绑定和解绑操作是每个Activity都会去做的,同样这里我也希望能有一个父类来完成这个统一的操作。
public abstract class BaseMvpActivity&V,T extends BasePresenter&V&& extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
presenter = initPresenter();
protected void onResume() {
super.onResume();
presenter.attach((V)this);
protected void onDestroy() {
presenter.dettach();
super.onDestroy();
public abstract T initPresenter();
同样使用泛型来提取通用的逻辑,presenter的初始化,以及view的绑定和解绑操作都提取到父类Activity中。向外部提供了一个 initPresenter(); 方法用来初始化presenter,如果想创建不同参数的构造函数都可以随意去创建。
更加通用的例子
通过上面的base父类,对之前的例子进行优化,写一个更加好用的例子。
NewMvpView
继承BaseView接口,添加自己的初始化ListView和Toast信息方法
public interface NewMvpView extends BaseView {
void setListItem(List&String& data);
void showMessage(String message);
NewMvpPresenter 继承BasePresenter类,增加网络请求和处理点击事件的方法
public class NewMvpPresenter extends BasePresenter&NewMvpView& {
private RequestBiz requestB
private Handler mH
public NewMvpPresenter() {
requestBiz = new RequestBiziml();
mHandler = new Handler(Looper.getMainLooper());
public void onResume(){
requestBiz.requestForData(new OnRequestListener() {
public void onSuccess(final List&String& data) {
mHandler.post(new Runnable() {
public void run() {
mView.hideLoading();
mView.setListItem(data);
public void onFailed() {
mView.showMessage("请求失败");
public void onItemClick(int position){
mView.showMessage("点击了item"+position);
NewMvpActivity
public class NewMvpActivity extends BaseMvpActivity&NewMvpView,NewMvpPresenter& implements NewMvpView,AdapterView.OnItemClickListener{
ListView mvpListV
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mvp);
mvpListView = (ListView)findViewById(R.id.mvp_listview);
mvpListView.setOnItemClickListener(this);
pb = (ProgressBar) findViewById(R.id.mvp_loading);
protected void onResume() {
super.onResume();
presenter.onResume();
public NewMvpPresenter initPresenter() {
return new NewMvpPresenter();
public void onItemClick(AdapterView&?& parent, View view, int position, long id) {
presenter.onItemClick(position);
public void setListItem(List&String& data) {
ArrayAdapter adapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1,data);
mvpListView.setAdapter(adapter);
public void showMessage(String message) {
Toast.makeText(this,message,Toast.LENGTH_SHORT).show();
public void showLoading() {
pb.setVisibility(View.VISIBLE);
public void hideLoading() {
pb.setVisibility(View.GONE);
最终的成果,我们只需要在Acitivity中传入泛型对象,并写好initPresenter() Presenter的初始化的方法就可以直接去使用presenter,当然View的接口还是要自己去实现。
以上的方法只是一些比较简单的封装,下面来看看官方的MVP架构是怎么写的。
官方的MVP架构
先来看看官方的代码目录(这里只是功能模块的目录,不包括测试模块,毕竟这里分析的是官方的实现代码)
谷歌的todomvp工程实现了一个类似记事本的功能,整体的目录结构:
tasks 包可以显示任务列表
taskdetail包显示任务详情
addedittask包添加和编辑任务
statistics包用来显示任务的完成情况
data包数据模块对应mvp的M
Util包就是通用的方法。
这里todomvp也有BasePresenter和BaseView2个基类,不过看的出来这2个都是接口。先来看看这2个接口
public interface BasePresenter {
void start();
public interface BaseView&T& {
void setPresenter(T presenter);
各自简单的声明了一个方法,start()方法用来给Presenter做一些初始化的操作不用特别在意,BaseView声明的方法就很有意思了,setPresenter(T presenter) 很明显是给View绑定Presenter,而前文我们使用的方式给Presenter传入View的方式来完成View和Presenter绑定的操作,这里谷歌采用了相反的方式来操作,为什么呢?
先把这个问题留下,看看单个模块的具体的文件结构。
有Activity,Fragment,Presenter,View哪里去了? 其实谷歌的mvp是将Fragment作为View层来实现的,这一点在官方的Readme中也有说明,为什么要用Fragment?
官方认为Fragement和Activity相比更像是MVP中的的View层,刚好可以满足MVP的View层的要求,Activity则作为最高指挥官用来创建和联系View和Presenter。
Fragment在平板或者屏幕上有多个View时更有优势
Activity只作为创建和联系View和PresenterView而存在,将Fragment作为显示UI而存在。Activity主指挥,Fragment主显示。这也是谷歌的sample中的一贯做法。
View的问题解释完了,再看看TaskDetailContract 这种**Contract 接口,这也是官方独有的管理方法
google的todomvp 工程中每个模块都会有一个 **Contract 接口,来看看他的代码
public interface TaskDetailContract {
interface View extends BaseView&Presenter& {
void setLoadingIndicator(boolean active);
void showMissingTask();
void hideTitle();
void showTitle(String title);
void hideDescription();
void showDescription(String description);
void showCompletionStatus(boolean complete);
void showEditTask(String taskId);
void showTaskDeleted();
void showTaskMarkedComplete();
void showTaskMarkedActive();
boolean isActive();
interface Presenter extends BasePresenter {
void editTask();
void deleteTask();
void completeTask();
void activateTask();
Contract其实就是一个包涵了Presenter和View的接口,Presenter实现的逻辑层方法,View实现的UI层的方法都能在Contract接口中一目了然的看明白,具体的Presenter和View的实现类都是通过实现Contract接口来完成。这种方式既方便了管理和维护,也给开发点了一个导航灯。
下面来看看Presenter如何引用到Fragment中以及View如何与Presenter建立联系
TaskDetailActivity
* Displays task details screen.
public class TaskDetailActivity extends AppCompatActivity {
public static final String EXTRA_TASK_ID = "TASK_ID";
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.taskdetail_act);
String taskId = getIntent().getStringExtra(EXTRA_TASK_ID);
TaskDetailFragment taskDetailFragment = (TaskDetailFragment) getSupportFragmentManager()
.findFragmentById(R.id.contentFrame);
if (taskDetailFragment == null) {
taskDetailFragment = TaskDetailFragment.newInstance(taskId);
ActivityUtils.addFragmentToActivity(getSupportFragmentManager(),
taskDetailFragment, R.id.contentFrame);
new TaskDetailPresenter(taskId,Injection.provideTasksRepository(getApplicationContext()),
taskDetailFragment);
..... 省去不重要代码
TaskDetailActivity主要做了taskDetailFragment 初始化和TaskDetailPresenter的初始化操作,在做TaskDetailPresenter初始化时直接将taskDetailFragment作为参数传入,因为taskDetailFragment实现了View层的接口,看到这里有一个疑问,new TaskDetailPresenter()可以实例化一个Presenter,但是怎么传入到taskDetailFragment中呢?为了解开疑惑我查看了TaskDetailPresenterde 构造方法
public class TaskDetailPresenter implements TaskDetailContract.Presenter {
public TaskDetailPresenter(@Nullable String taskId,
@NonNull TasksRepository tasksRepository,
@NonNull TaskDetailContract.View taskDetailView) {
this.mTaskId = taskId;
mTasksRepository = checkNotNull(tasksRepository, "tasksRepository cannot be null!");
mTaskDetailView = checkNotNull(taskDetailView, "taskDetailView cannot be null!");
mTaskDetailView.setPresenter(this);
关键方法就是在BaseView中声明的void setPresenter(T presenter); 方法实现的绑定,当然这里只是调用View的方法,具体的绑定还要追踪到实体类中,来看TaskDetailFragment
TaskDetailFragment
public class TaskDetailFragment extends Fragment implements TaskDetailContract.View {
......省去不重要代码
private TaskDetailContract.Presenter mP
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.taskdetail_frag, container, false);
....省去初始化代码
public void setPresenter(@NonNull TaskDetailContract.Presenter presenter) {
mPresenter = checkNotNull(presenter);
TaskDetailFragment 实现了TaskDetailContract接口中的View接口,这样在TaskDetailPresenter 构造方法中调用mTaskDetailView.setPresenter(this)方法后,TaskDetailFragment 的setPresenter也会调用,TaskDetailPresenter 就成功绑定到了TaskDetailFragment 中。
这种绑定方式也解释了上文提到的问题,为什么谷歌采用了相反的方式操作,就是为了这后面的绑定操作。
Acitivity对象内存泄漏的问题
谷歌的项目同样会有当有后台异步任务时可能导致Acitivity内存泄漏的问题。谷歌也有自己的处理方法,上面提到的TaskDetailContract 接口有声明一个方法 isActive()
public interface TaskDetailContract {
interface View extends BaseView&Presenter& {
....省去其他的方法
boolean isActive();
看看这方法的具体实现类
public class TaskDetailFragment extends Fragment implements TaskDetailContract.View {
public boolean isActive() {
return isAdded();
isAdded()方法如果返回true代表Fragment添加到了Activity,false代表没有添加,通过调用isActive()方法就可以给后台异步任务添加判断避免内存泄漏。
到这里整体的架构就已经清楚了配上这张UML图可以更好的理解。
Activity最外层负责Presenter和View的创建和联系。
Fragment实现了View的接口并与Presenter绑定
Presenter从数据层中获取数据与View进行交互
google的todomvp不光给了我们一个mvp的架构演示,还附带了一个测试模块,整体的架构非常适合用来开发。强烈建议大家去github上下载源码来看看,效果更佳
&&相关文章推荐
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:50712次
排名:千里之外
原创:20篇
评论:47条
(2)(1)(2)(1)(1)(7)(1)(5)Posts - 150,
Articles - 12,
Comments - 1234
(SQL Server & MySQL) DBA
10:46 by 听风吹雨, ... 阅读,
一.本文所涉及的内容(Contents)
  搞微软技术的,大家或多或少都有听说过微软的&最有价值专家&(MVP),网上也有不少资料对这个称谓做了介绍,但是都是一些大体的描述,并没有更加细节方面的,比如申请成为MVP的流程,成为MVP有那些资料需要填写、在哪里填写等等,所以我才萌发了以一个过来人的身份写一份关于微软MVP的攻略手册,希望能为想成为MVP的你提供指引。
三.什么是微软MVP?
  MVP(Most Valuable Professionals,最有价值专家)是指具备一种或多种微软技术专业知识,并且积极参与在线或离线的社群活动,经常与其他专业人士分享知识和专业技能,受人尊敬、信任,而且平易近人的专家。微软对上述专家在技术社群专业贡献的一种正式认同。
  MVP正是这样一群拥有丰富知识和实际经验并乐于分享所学知识的微软技术专家。他们不是微软的员工,但是非常乐于通过在线或离线社区的方式帮助技术人士。
  在全球90多个国家拥有接近4000多位最有价值专家,而中国大概有200位,这个是以一年为任期的人数,包括成功连任的和新当选的MVP人数,也称为活跃MVP人数,一年有4次申请MVP的机会,所以平均下来,在中国每一期MVP人数大概为50人左右(包括连任的新当选的),其中大部分都是连任的(我那期只有5位是新当选),所以第一次申请的同学需要加倍努力。
四.成为微软MVP的条件?
微软技术社区&最有价值专家&奖项选拔的条件如下:
1. 以微软技术为主题的作家、讲师、培训师;
2. IT业界的业内知名专业人士,通过印刷媒体、blog或其它形式分享经验和观点;
3. 参与和微软技术有关的项目,担任主要角色的技术和管理人员;
4. 建立讨论微软技术的技术网站,担任主要角色的技术和管理人员;
5. 参与微软中文技术论坛,积极地帮助论坛用户解决疑难问题的技术论坛高手;
6. 参与其他第三方与微软技术相关的论坛,积极地帮助论坛用户解决疑难问题的技术论坛高手;
7. 技术开发人员、作者、微软产品支持者、教育界、资讯决策者、IT 工程师、企业界等等。
五.如何成为微软MVP?
  了解那么多之后,如果你想成为微软MVP大家庭里面的一员,你先要经过提名,在提名期间,微软将成员在过去一年中对技术社区的贡献与其候选人所做的贡献进行比较。再经过审核,最后确定获奖者。可以通过微软员工、微软中文技术论坛、博客园、CSDN等论坛为你做推荐。
  微软MVP的申请流程,如Figure1所示:
(Figure1:微软MVP申请流程图)
(一) 申请时间划分
1月前递交申请表格,申请的是4月份的MVP,4月初就能收到是否获奖的邮件;
4月前递交申请表格,申请的是7月份的MVP,同上类推;
7月前递交申请表格,申请的是10月份的MVP,同上类推;
10月前递交申请表格,申请的是来年1月份的MVP,同上类推;
(二) 前期准备
  在申请MVP之前你必须根据选拔的条件做好准备,这个准备的时间会比较久,也许是1年,比如写博客,要写出高质量的博客文章,不是一天两天就能写出几十篇的,本人在社区中最主要的贡献就是博客。
  2009年12月是个很个值得纪念的月份,因为我正式开启了博客园的博客之旅,在长达4年多的旅程中我主要分享了关于SQL Server的一些知识,我一直坚持着每个月都分享自己学到的知识,令我庆幸的是,这个分享从开始一直到现在都未曾间断过一个月,同时这些坚持也得到博客园的肯定,我的博客在博客园的推荐博客排位为91(申请MVP的时候,现在已经升至72了),直到2013年底,我才有些底气去申请这个MVP;当然还有常用的混论坛,为大家解决问题,但是我个人比较倾向于写博客。(注意:12个月内的博客文章才能作为贡献数据填写到申请表格当中)
  我的博客(听风吹雨)地址
(三) 下载/填写申请表格
  这里提供两个主要下载MVP申请表格的地址
  下载了这份WORD文档之后,按照里面的提示进行填写,建议最好找现任的MVP作为推荐人,或者微软员工、微软中文技术论坛、博客园、CSDN等论坛推荐。
  接着就是填写最重要的共享值,下面是我填写的主要博客共享,内容如Figure2所示:
(Figure2:博客文章共享列表)
  当然还需要根据表格填写更多的共享值,这个得根据个人实际情况进行填写,这里就不罗列了;
(四) 申请MVP
  填写好申请表之后,你可以直接发给微软,不过我建议发给你博客所在的门户,我当时是发送给博客园的,这样可以让他们统一转发,避免丢失。
(Figure3:发送邮件给博客园申请MVP)
(五) 各种资料的填写
  我是日发送的邮件,经过漫长接近4个月的等待,终于在日收到候选人的邮件通知,这个邮件的目的是跟你确认一下地址,作为新当选/连任时收取MVP大礼包的地址,这并不代表一定能当选,只能再继续等待下一封邮件的通知。
(Figure4:MVP确认信息)
  又是一个漫长的等待,于日收到新当选微软MVP的邮件了,当时的第一个反应就是这会不会是一个玩笑,因为今天刚好是愚人节。里面主要包括了一个网址:,按照其中提供的一次性密码登录之后,按照页面指示逐步操作,其中有需要的同意NDA协议的电子版,有一步就是将您的个人信箱与MVP身份相关联,另外还有激活MSDN订阅等内容。
(Figure5:成为MVP)
  接着你会收到一封关于MVP大礼包和DNA协议的邮件,需要注意的是,这个大礼包是由美国微软总部通过FedEx联邦快递公司发往中国的,在包裹过关海关的有可能需要您提供这个包裹物品的清单,您可直接将此清单发送给他们,我是大概2天后收到海关的确认电话的。
(Figure6:MVP包裹邮件)
(Figure7:MVP大礼包物品清单)
  当你收到大礼包之后,里面包含了2份纸质的NDA保密协议,你需要签署这两份协议,一份自己留着,一份可以寄到这份邮件中提到的上海微软办公室,地址如下图所示:
(Figure8:MVP的NDA收件地址)
  接着就是满怀期待你的大礼包吧,我于日收到某快递公司的包裹,是由FedEx联邦快递公司委托的,注意接受包裹你是不需要出任何费用的,如果快递公司向你索取,可以拒收,再跟微软的人联系,下面是我的微软MVP证书和奖杯,奖杯需要注意,只有新当选才有奖杯,如果是连任,就只有一个代表年份的圆圈。
(Figure9:MVP证书)
(Figure10:MVP奖杯)
六.微软MVP奖项及权益包括什么?
微软技术社区&最有价值专家&(MVP)奖项及权益包括:
微软总部授予的全球统一的微软MVP证书;
微软全球统一的&MVP&标志的大礼包;
受邀参加在美国微软总部西雅图举办的微软全球MVP年会;
一年免费订阅的MSDN Premium或TechNet Plus(如选择订阅eSku版本,可享受一年免费的MSDN 和TechNet plus 的订阅),并拥有微软大部分产品的密钥;地址如:
还可以免费申请Azure帐号,地址如:
合作伙伴级别的知识库访问权限;
一年内指定微软活动的免费入场券;
150美金美国微软电子商店购物金币;
仅向MVP开放的专有技术网站、专有新闻组,含有丰富的技术资源;
与微软中国技术社区专业人士、微软产品组员工、微软美国总部的无限沟通机会;
MVP LOGO的使用权利;
(Figure11:MVP LOGO 横版)
(Figure12:MVP LOGO 竖版)
(Figure13:MSDN订阅)
七.成为微软MVP之后
  成为微软MVP之后,你可以上去设置自己的MyProfile,设置为公开之后,让更多的人可以找到你进行技术上交流。我的个人档案地址:
(Figure14:MVP档案)
  为了更多的交流,微软会发很多的交流信息到你的邮箱,你也可以通过MVP月刊让跟多的MVP了解你的最新动态。
(Figure15:MVP邮件)
(Figure16:MVP月刊)
  为了了解更多的资讯,你可以在微博上关注&微软中国MVP项目组&,如果它偶尔转发了你的微博之后,你的微博阅读数将如下图所示(1.7W的阅读量):
(Figure17:我的微博动态)
八.个人建议
  个人觉得微软MVP的称号是微软对大家无私付出的一种肯定,它只是一个附加值,不应该成为你写技术博客、论坛解决问题的目的,我们本应该以&分享是快乐的&作为出发来分享学到的知识和经验,如果太功利了,快乐就没有了。
九.互动资讯
&微软中国MVP项目组&的微博地址:
我的微博地址:
推荐几个微软MVP的博客:、、,勉强加上我自己吧:}

我要回帖

更多关于 男生为什么叫你傻叼 的文章

更多推荐

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

点击添加站长微信