在mac下安装双系统,一台电脑顶两台使用。刚才看到了一个安装双系统的方法。转过来供大家学习一下。其实也容易操作的。
1、正常进入MacOS(以下简称mac),在桌面上点击前往→实用工具:
2、进入“Boot Camp 助理”:
3、进来之后是介绍,直接继续:
4、这一步需要详细说明一下,先见图:
由于我的截图是在安装完Win之后,所以会和安装之前有一些不同。
黄色部分:这部分没有不同,需要提供Win7的安装光盘的镜像(ISO文件)和U盘。
红色部分:这部分也没有不同,这个选项是从网上下载MacBook在Win7里的必要的驱动程序。
蓝色部分:也许这颜色更像紫色?好吧,不同的就是这块。在安装前,这里显示的肯定是“安装 Windows 7”,由于我截图的时候已经装完了,所以这里就变成了“移除
Windows 7” 。
一般来讲在安装Win7的时候三项都要选上,然后继续。
5、再往下一步我就没法截图了,借用一下从网上找来的图吧
到图片这个画面之前还有一步,是选择Win7的镜像文件和安装文件的存储位置(这里的意思实际上是Mac把Win7的镜像文件解开后放到U盘上并把U盘制作成可引导启动的U盘),注意这里的U盘需要FAT格式。然后图中这一步就是划分硬盘空间,也就是留多大地方给MacOS,分多大地方给Win。如果你打算经常使用Win的话,最好多分一些空间给Win。
6、之后就一带而过了,往后基本上就是自动的了:将Win7安装盘镜像文件的内容复制到U盘上→下载“Windows支持软件”(这个作用就是以前从网上找、需要下载刻盘的那个驱动包)→重启后从U盘启动进入Win7安装程序。
7、到了这里就需要手动了,常规的Win7安装程序。需要注意的是,在选择安装位置的时候,一定要选择卷宗是“BOOTCAMP”的那个分区,并且谨慎起见对比一下在第5步图片中分配给Win的空间大小和这里看到的“BOOTCAMP”分区的大小是否一致。然后格式化成NTFS格式,就可以继续了。
8、这个时候Win7应该安装好了,下面要做的就是安装驱动。
在第一次的时候我忘记了那个“Windows支持软件”这么个东西,于是把刚才用于安装的U盘格式化了,在Win7里用驱动精灵来下载安装驱动。大部分的驱动都没问题,有问题的是蓝牙和声卡。蓝牙是压根没装上,声卡的问题是设备运行状况显示正常,右下角里的喇叭图标也正常,在播放声音的时候甚至会有音量的显示,但就是没有声音。后来发现应该用那个“Windows支持软件”来安装驱动。无奈又回到了MacOS,Bootcamp助理中,这时候的步骤和上面的图就是一致的了(因为我就是在这个过程中截的图)。不同的从下面开始。
9、不要选择“创建Windows 7安装磁盘”和“移除Windows7”!
为什么不选就不多解释了….也就是只选择中间的“从 Apple 下载最新的 Windows 支持软件”,点继续。
10、将“最新的 Windows 支持软件”存放到U盘上
因为MBA没有光驱,这哥们也没买外置光驱,所以依旧用U盘(其实用U盘挺好的,方便快捷绿色环保…),注意这里的U盘依旧必须为FAT格式,继续到下一步。
11、选择存储位置,其实就是选择你插入的U盘
实在抱歉,截这张图的时候把U盘拔出去了…所以…其实U盘的位置就是绿色部分那里,选择即可。至于红色部分,就是U盘里这个“最新的
Windows 支持软件”的文件夹名称,不用改。继续。
12、OK,我发现截图到此为止了,之后就是自动的了,从网上下载,自动放到U盘里,完成后重启进入Win7,安装即可。
13、好吧,我最终还是拿出了那个U盘,这是下载后存进来的内容,总共683M。
里面有说明文档(Boot
Camp Installation & Setup Guide.pdf),英文的。不过实际上运行setup.exe就行了,一路下一步,到最后安装完成重启即可,文档没什么可看的。
为什么android中要使用多线程?
消息的注册到业务的实现
从接触呼叫业务的第一天起,我就一直琢磨代码里成群结队的registerXXXX方法跟notifyXXXX方法究竟是个怎么关系。
一个消息(Message)从注册到被处理(handleMessage)都经过了哪些步骤?为什么要通过这种设计来完成线程间通信?是什么决定哪些消息在哪些类中被处理?消息上报之后,framework层都完成了哪些工作?
诸如此类,一言难尽。
在过去的总结中,我倾向于通过业务层不同呼叫状态的实例含义来理解整个通话的过程,而不是专注于dial,hangup,rejectCall,acceptCall这类的具体通话流程。换句话说,我觉得,如果能掌握不断改变的通话状态与android系统所做的处理之间的联系,也就能明白呼叫业务、甚至是android通信流程的真正脉络。
而这个Register-Notify模型,恐怕就是理解它的钥匙之一。
当我们正在谈论注册(register)的时候,它们在干什么
所谓的registerXXX,简单的说就是在某个特定的泛型列表中添加一个新的泛型节点。
两个有趣的地方。
第一, 为什么要通过不同的泛型列表来搜集不同的消息?
第二, 添加的这个新的泛型节点都包括哪些内容?
首先来看第二个问题,一个新的泛型节点通常包含了以下三样东西:
Handler h, int what, Object obj
在一个注册方法被调用时,h代表了能处理这个消息,同时也继承了Hanlder类的线程名称,what代表了该消息标签名称,而obj代表了以基本对象为格式所封装的消息内容。
再来看一个新的Registrant泛型节点用这些参数都构成了什么。
public Registrant(Handler h, int what, Object obj) { refH = new WeakReference(h); this.what = what; userObj = obj; }
套用上一节发快递来理解Handler的思路,这个注册新节点,其实就是个对消息打包过程,我在一则消息中标注了它的收件人信息(refH),签名(what),以及消息本身(userObj)。
这时候再来看第一个问题,如果把同样的收件人(refH),同样签名(what)的消息放到同一个队列当中,维护这个队列实际上就维护了所有同类注册的消息。相对的,从这个队列中取出的每个节点也都有同样的属性,可以用一种方式进行处理。
那么,为什么我会在意这个问题?
因为android系统为了“更直观”地向用户表达变量的含义,通常会给代表同种类型事件的消息以相同名称的泛型列表来维护。
譬如说,就“通话状态发生变化”这个事件而言,android系统用相同名称的泛型列表mPreciseCallStateRegistrants来维护了不同的签名(what)的消息触发,代码结构上从下到上是这样的:
在CallManager.java中
phone.registerForPreciseCallStateChanged(mHandler,EVENT_PRECISE_CALL_STATE_CHANGED, null);
在PhoneUtils.java中
cm.registerForPreciseCallStateChanged(mConnectionHandler,PHONE_STATE_CHANGED, cm);
两者调用的形参,被引用的对象都不一样,只有方法名称是相同的。但就是这个相同的名称,在最开始把我弄的稀里糊涂,以为同一个泛型列表可以收录同种事件,但是内容不一样的消息,这是错误的。希望大家能够区分清楚这是两条不同的列表,只是代表的事件类型相同罢了。
当我们正在谈论通知(notify)的时候,它们在干什么
注册完一个消息,从某种意义上说,只是准备好了包裹而没有投递它。真正的投递过程是在notfiy过程完成的。
注意,我说的投递过程,而不是处理过程。
在一开始学习Register-Notify模型的时候,我一直想当然的以为那些处于handleMessage代码段中的notifyXXXX就是这个消息的处理。
但愿你不是这么想的,因为这是个直观但是错误的认知。
我们来看notifyXXXX实现了什么。
一段合格的notfiy代码,必然带着AsyncResult类型的形参一块被调用。追根溯源,其实调用的是RegistrantList.java里的这个方法:
private synchronized void internalNotifyRegistrants (Object result,Throwable exception) { for (int i = 0, s = registrants.size();i < s ; i++) { Registrant r = (Registrant) registrants.get(i); r.internalNotifyRegistrant(result,exception); } }
诸位见到了,Ar格式的形参数据,其实包含了一个结果消息result,以及封装在内的异常信息exception。
再来看Registrant.java类的这个方法:
/*package*/ void internalNotifyRegistrant (Object result,Throwable exception) { Handler h = getHandler(); if (h == null) { clear(); } else { Message msg = Message.obtain(); msg.what = what; msg.obj = new AsyncResult(userObj,result, exception); h.sendMessage(msg); } }
这下清楚了。它从我的收件人(refH)封装中取出对应的收件人信息(h=getHandler()),然后从消息池中挖出一个消息,把之前写在包裹上的标签(what)给标注在消息上,然后根据消息的内容(userObj),结果信息(result)以及异常信息(exception)重新打包为消息的内容。
接着把它发出去。就像上一节我们看到的sendMessage方法一样,把这个包裹扔到待处理的线程消息队列中去。
然后……然后就像上一节描述的那样样,系统的回调机制会分发这条消息,最终在指定的Handler对象的handleMessage方法中完成这个消息的处理。
这里可能有人要问,既然同样是消息内容,都可以为基本对象格式,那么result与UserObj内容有什么区别。
我是这么理解的。直观的看UserObj内容在消息注册时由register方法给定,而result内容则是消息在投递时由notify方法给定,两者的内容来源不同,设计者根据情况需要进行不同的消息设计。
当然,在实际运用中,由于消息触发的嵌套机制,A消息收到的UserObj内容可能就是B消息的result内容,这也是有可能的。
不算结束的总结
零零碎碎说了这么多,想起之前总结的内容,关于Register-Notify模型一节的内容,确实还有一些不恰当的地方,这里做一个修正,希望能够与诸位不断的深入理解android Handler机制。
其实,Register-Notify的模型这么画也许更合适:
当然,这只是个诸多消息回调中比较典型的一种罢了。
最后再补一句。
在android framework层并非所有的消息都是通过Handler回调机制来完成的。譬如跟RIL层接口的ril.java文件,尽管也用到了obtain和send方法来实现消息的产生与投递,但事实上它的收发机制是socket套接字的方式与RILD进行数据交互,所以对它的消息收发仍需要仔细研究代码才可以。