[转载]愤怒的小鸟的究竟有没有很高的技术含量?

mikel阅读(934)

[转载]愤怒的小鸟的究竟有没有很高的技术含量? – 助人为乐 – 博客园.

在 我第一次看到愤怒的小鸟这个游戏的时候,就对它物理模拟的效果赞叹不已。在一次园子中的评论中,几位园友对小鸟的技术不屑一顾。实在看不下去了,当时我谈 了一些自己的看法,但也没有深究下去。今天看到一条新闻,就顺藤摸瓜做了一下调查研究,下面把一些调查结果和大家分享一下。这是新闻的链接http://www.cnbeta.com/articles/136109.htm)
让我很吃惊的是,小鸟的物理引擎不是小鸟游戏开发公司的原创,而是一个开源的物理引擎,名叫Box2D

这个引擎起源于2006年的GDC大会上的一个物理碰撞的教程,随后发布为开源项目。最初的演示就是一堆箱子。(这里是一个项目原型的截图,http://www.box2d.org/screenshots.html)
看到这些图,我真的很吃惊,这几乎就是一个小鸟游戏的很粗略的示意图。难怪Box2D的作者会对小鸟公司表示不满。
在2008年3月6日,2.0版正式引入“持续碰撞检测”(continuous collision detection)。这是我最欣赏的一个特性,而小鸟游戏的开发是在2009年。也就是说这个2.0版本让小鸟游戏直接成为了可能。
同时这个引擎也被移植到了XNA平台,这样在Windows Phone 7上,小鸟也可以运行了。

下面是Box2D的全部特性。

(有几个个特性看上去非常有技术含量。我不是做游戏的,很多特性我也不知道什么意思)

Collision
* Continuous collision detection
* Contact callbacks: begin, end, pre-solve, post-solve(接触回调函数)
* Convex polyons and circles.
* Multiple shapes per body(多形状实体)
* One-shot contact manifolds (击打接触,是为小鸟设计的?)
* Dynamic tree broadphase
* Efficient pair management
* Fast broadphase AABB queries(这个是什么?)
* Collision groups and categories

Physics

* Continuous physics with time of impact solver
* Persistent body-joint-contact graph
* Island solution and sleep management
* Contact, friction, and restitution
* Stable stacking with a linear-time solver (这个是什么?)
* Revolute, prismatic, distance, pulley, gear, mouse joint, and other joint types
* Joint limits, motors, and friction
* Momentum decoupled position correction
* Fairly accurate reaction forces/impulses (比较精确的力反馈)

System

* Small block and stack allocators
* Centralized tuning parameters
* Highly portable C++ with no use of STL containers

结论:

1,愤怒的小鸟是一个非常有技术含量的游戏,不过这个技术含量更多来源于它的开源物理引擎,当然小鸟的创意也是成功非常重要的因素。
2,开源里面有大量等待发掘的金矿,只要我们勇于探索,也许有一天我们也能有非常有创意的产品出现。
3,虽然我是用我的经验和审美来直觉体验小鸟的深刻技术内涵,不过多一点调查总是有好处的。可以收获更多的知识和经验
4,如果我们使用了开源项目,应该表示出对原作者足够的尊重, 而愤怒的小鸟在这一个点上显然做得不够好。

[转载]Asp.NET MVC Widget开发 - ViewEngine

mikel阅读(2167)

[转载]Asp.NET MVC Widget开发 – ViewEngine – Creative dream – 博客园.

ASP.NET开发博客类系统,我们经常都会用到Widget,像在线好友、最近访问 好友、最新留言等,关于ASP.NET MVC与ASP.NET视图的差异,这里不再说了,大家可去查一下,接下来我以“我的好友”列表来要介绍在Asp.NET MVC实现这一功能以及结构设计。

  • 开发工具:VS 2010 EN
  • 开发语言:Visual C#
  • ASP.NET MVC 3
  1. Asp.NET MVC Widget – 设计
  2. Asp.NET MVC Widget – Controller控制器
  3. Asp.NET MVC Widget – ViewEngine
  4. Asp.NET MVC Widget – Mobile支持

关于ViewEngine这篇是Widgets实现的核心,这里需要自定义ASP.NET MVC的视图引擎,也就是让Asp.NET MVC视图引擎可以找到widgets中的文件。

直接访问会出现以下错误,提示找不到显示文件

由错误中也可以看到 Asp.NET MVC默认引擎搜索文件的目录

/Views/Widget/

/Views/Shared/

要寻找到”widgets”中的文件就必须要让视图引擎去”widgets”中搜索文件

如Friends: /widgets/Friends/

添加自定义视图引擎

1. 添加 “WidgetViewEngine.cs”,继承自BuildManagerViewEngine

using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace Widgets { public class WidgetViewEngine : BuildManagerViewEngine { internal static readonly string ViewStartFileName = "_ViewStart"; public WidgetViewEngine() : this(null) { } public WidgetViewEngine(IViewPageActivator viewPageActivator) : base(viewPageActivator) { AreaViewLocationFormats = new[] { "~/Areas/{2}/Views/{1}/{0}.cshtml", "~/Areas/{2}/Views/Shared/{0}.cshtml" }; AreaMasterLocationFormats = new[] { "~/Areas/{2}/Views/{1}/{0}.cshtml", "~/Areas/{2}/Views/Shared/{0}.cshtml" }; AreaPartialViewLocationFormats = new[] { "~/Areas/{2}/Views/{1}/{0}.cshtml", "~/Areas/{2}/Views/Shared/{0}.cshtml" }; ViewLocationFormats = new[] { "~/Views/{1}/{0}.cshtml", "~/Views/Shared/{0}.cshtml" }; MasterLocationFormats = new[] { "~/Views/{1}/{0}.cshtml", "~/Views/Shared/{0}.cshtml" }; PartialViewLocationFormats = new[] { "~/{1}s/{0}/Widget.cshtml", "~/Views/{1}/{0}.cshtml", "~/Views/Shared/{0}.cshtml" }; FileExtensions = new[] { "cshtml" }; } protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath) { return new RazorView(controllerContext, partialPath, layoutPath: null, runViewStartPages: false, viewStartFileExtensions: FileExtensions, viewPageActivator: ViewPageActivator); } protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath) { var view = new RazorView(controllerContext, viewPath, layoutPath: masterPath, runViewStartPages: true, viewStartFileExtensions: FileExtensions, viewPageActivator: ViewPageActivator); return view; } } }

2. 添加AppStart_Widgets.cs,修改默认视图引擎

using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using Widgets; [assembly: PreApplicationStartMethod(typeof(AppStart_Widgets), "Start")] namespace Widgets { public class AppStart_Widgets { public static void Start() { // Clear system default view engines ViewEngines.Engines.Clear(); ViewEngines.Engines.Add(new WidgetViewEngine()); } } }

3. 添加Friend实体及测试数据

using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace Widgets.Models { public class Friend { public int Id { get; set; } public string Name { get; set; } } public class FriendsContext { public FriendsContext() { Friends = new List<Friend>() { new Friend{Id=1,Name="zhang san"}, new Friend{Id=2,Name="li si"}, new Friend{Id=3,Name="wang wu"} }; } public IEnumerable<Friend> Friends { get; private set; } } }

4. 更改widgets/Friends/Widget.cshtml

@model IEnumerable<Widgets.Models.Friend> @{ Layout = "~/widgets/_Layout.cshtml"; ViewBag.Title = "My friends"; } <div class="newsletter"> <ul> @foreach (var item in Model) { <li>@item.Name</li> } </ul> </div>

项目结构

其它代码详见源码中。

再次访问,便出现要的结果。

源码下载

[转载]Asp.NET MVC Widget开发 - Mobile支持

mikel阅读(1993)

[转载]Asp.NET MVC Widget开发 – Mobile支持 – Creative dream – 博客园.

ASP.NET开发博客类系统,我们经常都会用到Widget,像在线好友、最近访问 好友、最新留言等,关于ASP.NET MVC与Asp.NET视图的差异,这里不再说了,大家可去查一下,接下来我以“我的好友”列表来要介绍在Asp.NET MVC实现这一功能以及结构设计。

  • 开发工具:VS 2010 EN
  • 开发语言:Visual C#
  • ASP.NET MVC 3
  • Windows Phone 7 Emulator
    1. Asp.NET MVC Widget – 设计
    2. Asp.NET MVC Widget – Controller控制器
    3. Asp.NET MVC Widget – ViewEngine
    4. Asp.NET MVC Widget – Mobile支持

      前3篇中已经讲了Widget实现方法,并用“我的好友”实例做了演示,接下来将要支持Mobile了。

      1. 先来贴下”widgets”的目录结构

      /Mobile                                                存放Mobile支持的页面文件

      /Mobile/Widget.cshtml                          通用的Mobile显示页面,即任何手机客户端未找到情况下,调用此显示

      /Mobile/iPhone/                                    存放针对iPhone类型文件

      /Mobile/iPhone/Widget.cshtml                iPhone主页面文件

      /Mobile/WindowsMobile                         存放针对WindowsMobile类型文件

      /Mobile/WindowsMobile/Widget.cshtml    WindowsMobile主页面文件

      2. 修改视图引擎以支持Mobile

      打开我们之前添加的WidgetViewEngine.cs,添加对Mobile支持

      • 添加public StringDictionary Devices { get; set; },存储设备对应的目录
      • 重载FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache)方法
      using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using System.Collections.Specialized; namespace Widgets { public class WidgetViewEngine : BuildManagerViewEngine { internal static readonly string ViewStartFileName = "_ViewStart"; public StringDictionary Devices { get; set; } public WidgetViewEngine() : this(null) { } public WidgetViewEngine(IViewPageActivator viewPageActivator) : base(viewPageActivator) { AreaViewLocationFormats = new[] { "~/Areas/{2}/Views/{1}/{0}.cshtml", "~/Areas/{2}/Views/Shared/{0}.cshtml" }; AreaMasterLocationFormats = new[] { "~/Areas/{2}/Views/{1}/{0}.cshtml", "~/Areas/{2}/Views/Shared/{0}.cshtml" }; AreaPartialViewLocationFormats = new[] { "~/Areas/{2}/Views/{1}/{0}.cshtml", "~/Areas/{2}/Views/Shared/{0}.cshtml" }; ViewLocationFormats = new[] { "~/Views/{1}/{0}.cshtml", "~/Views/Shared/{0}.cshtml" }; MasterLocationFormats = new[] { "~/Views/{1}/{0}.cshtml", "~/Views/Shared/{0}.cshtml" }; PartialViewLocationFormats = new[] { "~/{1}s/{0}/Widget.cshtml", "~/Views/{1}/{0}.cshtml", "~/Views/Shared/{0}.cshtml" }; // 初使化Mobile对应文件目录 Devices = new StringDictionary { {"IEMobile","WindowsMobile"}, {"Pocket IE","WindowsMobile"}, {"AppleMAC-Safari","iPhone"} }; FileExtensions = new[] { "cshtml" }; } protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath) { return new RazorView(controllerContext, partialPath, layoutPath: null, runViewStartPages: false, viewStartFileExtensions: FileExtensions, viewPageActivator: ViewPageActivator); } protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath) { var view = new RazorView(controllerContext, viewPath, layoutPath: masterPath, runViewStartPages: true, viewStartFileExtensions: FileExtensions, viewPageActivator: ViewPageActivator); return view; } public override ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache) { ViewEngineResult result = null; var request = controllerContext.HttpContext.Request; var isMobile = request.Browser.IsMobileDevice; if (isMobile && controllerContext.IsChildAction) { var device = request.Browser.Browser; result = base.FindPartialView( controllerContext, string.Format("{1}/Mobile/{0}", Devices[device], partialViewName), useCache); if ((result == null || result.View == null) && isMobile) result = base.FindPartialView( controllerContext, string.Format("{0}/Mobile", partialViewName), useCache); } if (result == null || result.View == null) result = base.FindPartialView(controllerContext, partialViewName, useCache); return result; } public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache) { ViewEngineResult result = null; var request = controllerContext.HttpContext.Request; var isMobile = request.Browser.IsMobileDevice; if (isMobile) { var device = request.Browser.Browser; result = base.FindView( controllerContext, string.Format("Mobile/{0}/{1}", Devices[device], viewName), masterName, useCache); if ((result == null || result.View == null) && isMobile) result = base.FindView( controllerContext, string.Format("Mobile/{0}", viewName), masterName, useCache); } if (result == null || result.View == null) result = base.FindView(controllerContext, viewName, masterName, useCache); return result; } } }

      3. 更改显示页面

      /Mobile/Widget.cshtml

      @model IEnumerable<Widgets.Models.Friend> @{ Layout = "~/widgets/_Layout.cshtml"; ViewBag.Title = "My friends"; } <div class="newsletter"> <ul> @foreach (var item in Model) { <li>@item.Name</li> } </ul> </div>

      /Mobile/iPhone/Widget.cshtml

      @model IEnumerable<Widgets.Models.Friend> @{ Layout = "~/widgets/_Layout.cshtml"; ViewBag.Title = "My friends"; } <div class="newsletter"> <ul> @foreach (var item in Model) { <li>@item.Name</li> } </ul> <span>来自iPhone手机客户端</span> </div>

      /Mobile/WindowsMobile/Widget.cshtml

      @model IEnumerable<Widgets.Models.Friend> @{ Layout = "~/widgets/_Layout.cshtml"; ViewBag.Title = "My friends"; } <div class="newsletter"> <ul> @foreach (var item in Model) { <li>@item.Name</li> } </ul> <span>来自windows mobile手机客户端</span> </div>

      4. 使用Windows Phone 7 Emulator打开页面

      [转载]Android新手入门基本知识(三)

      mikel阅读(1045)

      第二十一讲:几个小方法解决手机烧流量问题

      不少刚刚使用 Android 手机的朋友都反映手机有烧流量的问题,为此也付出了惨痛的代价,有的朋友被烧走了几百块啊~

      究其原因就是因为 Android 系统的众多服务都是基于网络的,所以手机系统经常要通过网络和服务器进行通信,还有电信运营商的高价收费问题,当然这个问题我解决不了,我只能为大家解决第一个问题。

      方法一、APN开关

      首先可以通过“APN开关”来解决这个问题,一般刷新了论坛里的简体中文系统就都内置了这个软件,使用它就可以完全关闭 GPRS 数据通讯了,需要上网的时候可以再打开。缺点就是有些麻烦,而且一旦关闭了也就无法接收彩信息了。
      但是一旦使用既可保证在你不需要网络的情况下绝对不会流走一分钱的流量。

      Android, android, USA, Google, 应用软件 - Android新手入门基本知识

      方法二、关闭自动同步

      还有一个造成流量偷跑的原因可能就是系统自动同步了,我们可以通过关闭自动同步解决这一问题,在需要同步时进行手动同步即可。

      在设置中找到该选项。

      Android, android, USA, Google, 应用软件 - Android新手入门基本知识

      点击同步数据

      Android, android, USA, Google, 应用软件 - Android新手入门基本知识

      取消同步数据

      Android, android, USA, Google, 应用软件 - Android新手入门基本知识

      需要同步时手动点击需要同步的项即可。

      方法三、节约使用流量

      除了以上方法我们还可以在平时的操作中节约流量。

      Android, android, USA, Google, 应用软件 - Android新手入门基本知识

      平时使用手机上网观看一些新闻时可以关闭浏览器的图片显示,这一项就可以大大节约流量。

      使用 GOOGLE 地图时将地图模式切换为更加节省流量的“地图”模式。其实现在有了“凯立德”导航软件,看地图导航的话完全可以使用“凯立德”了。

      Android, android, USA, Google, 应用软件 - Android新手入门基本知识

      如果十分在意流量的话,还可以注意关闭天气预报软件的更新,不过这类软件的一般所消耗的数据量较小。

      方法四、大容量包月套餐!

      虽然使用以上方法可以保证减少流量的流失不过对于Android这样一个需要云计算的系统来说,用起来会非常的不爽。所以建议大家还是换一个流量更大的套 餐吧! 我现在就用的是250MB的套餐,一直开着各类自动更新,自由上网,也不会超过,这样用G1 不是更潇洒!当然最好是无限流量的包月卡!

      第二十二讲:android手机怎样通过蓝牙传输文件

      其实通过蓝牙传输文件这项功能也是最近才实现的,之前ANDROID的蓝牙功能是比较尴尬的,因为只能连接蓝牙耳机,现在有了一款名为 Bluex 的软件解决了蓝牙传输这一问题。

      一、蓝牙文件的发送

      1.首先下载安装 BLUEX 这个软件
      打开此选项就可以发送蓝牙文件了。
      进入文件管理器选择需要发送的文件。
      我就选择一张照片好了。
      正在搜寻设备
      找到了周边的蓝牙设备,选择发送即可。
      正在通过蓝牙发送文件。

      二、接收蓝牙文件

      说过发送蓝牙文件了,再来介绍一下如何接受蓝牙文件。
      打开 Enable sever 这个选项,就可以开启接收蓝牙文件的服务。
      我用另一部 NOKIA 手机给 G1 发送文件,G1很快就接收到了。
      正在接收文件,速度很快。
      还可以在“Directories”选项下选择接收文件放置的文件夹。
      接收到的文件会被默认放置到SD卡的这个文件夹内。
      找到了我刚刚接收的图片。
      有了这个软件我的 G1 再也不会被朋友笑称为脑残机了!终于可以无线发送数据了~

      第二十三讲:如何清空android G1手机里的系统垃圾

      手机使用时间长了,难免会有一些系统垃圾数据出现,G1的可用内存本就不大,如果空间在被这些垃圾文件蚕食了,唉 我们的可用空间就更小了!
      所以今天我们就要对垃圾数据宣战! 清理垃圾数据!
      ANDROID 系统的垃圾数据主要来源于缓存,而缓存中占据最多的就是浏览器缓存和 MARKET 网络商店缓存。

      Android, android, USA, Google, 应用软件 - Android新手入门基本知识

      首先咱们查看下 手机可用空间是多少?我的G1上 可用空间现在时37M

      Android, android, USA, Google, 应用软件 - Android新手入门基本知识

      下面我们开始清理垃圾数据:

      进入设置——应用程序——管理应用程序

      找到浏览器这一项,点击进入

      Android, android, USA, Google, 应用软件 - Android新手入门基本知识

      选择清楚缓存  后推出 然后在进入 MARKET 也就是电子市场 也是一样的办法 清除下缓存

      Android, android, USA, Google, 应用软件 - Android新手入门基本知识

      Android, android, USA, Google, 应用软件 - Android新手入门基本知识

      最后咱们来看下是不是管用了很多  可用空间增长到了45M了!

      Android, android, USA, Google, 应用软件 - Android新手入门基本知识

      第二十四讲:轻轻松松为你的手机截图

      好多人问我 你的手机截屏是怎么弄上去的?看来大家都不知道这个问题 其实超EASY的!
      我是下了91助手 FOR android 系统
      首先把91手机助理下载到你的电脑上 然后用数据线连接手机 (没有驱动的91会在你的第一次连接前帮你下好驱动)然后点击媒体娱乐

      Android, android, USA, Google, 应用软件 - Android新手入门基本知识

      点击“咔嚓”手机截屏  然后刷新下 点击截图

      Android, android, USA, Google, 应用软件 - Android新手入门基本知识

      这样截图的文件出会出现在 你设定的文件夹里了

      Android, android, USA, Google, 应用软件 - Android新手入门基本知识

      第二十五讲:怎样快速更新已安装的软件?

      不少朋友都在手机中安装了各类软件,而且数量都不少,最多时我的G1里就安装了41个软件,内存基本都被占满了。

      相信“软件达人”都会十分在乎自己的软件是不是最新版本的。那么这么多软件我们怎样及时的更新他们呢? 这就需要一款软件了,呵呵~ 又是软件。

      进入软件会首先搜索你已经安装过的程序。

      我大概安装了27个,按下“Version Tracking”就可以联网检索你的软件是否有更新了。一定要保证你的手机已经联网了,建议用WIFI,用GPRS的话是又慢又浪费流量。

      27个软件中,有两个软件需要更新!有八个软件我选择了不更新,因为都是收费软件,无法更新。
      选择不更新的话还可以提高检索速度。

      这两个软件需要更新,点击软件即可开始更新。

      这个软件是从MARKET进行更新的,所以有些收费软件是无法更新的,好在免费软件都可以更新。

      此时就切换到了MARKET程序。

      确认进行安装。

      这款软件同时还可以备份你的软件列表。

      可以将软件目录以TXT文档的形式备份到SD卡里。

      第二十六讲:什么是SPL?与非SPL的区别

      SPL,Second Program Loader,实际就是android的bootloader,用来引导系统的,(和pc的BIOS有点类似。)
      除了用来加载android 系统外,它还有其他的一些功能,包括恢复模式,Fastboot(刷系统),HBoot(???)。
      最终SPL就是用来读写flash rom的。除此之外,SPL还会检查要刷的数据文件是否正确。
      当前大多数SPL,可以让我们刷写完整的系统rom,但是无法刷写recovery rom和boot image,因为spl会检查recovery 和boot img的签名。不过有高人(Haykuro)修改了SPL,移除check功能,这就是Engineering SPL,
      SPL如此重要,在刷SPL时,要加倍小心。因为一旦刷坏了SPL,没有专门的设备和技术,是无法恢复spl的。

      ——————————–
      所以论坛里说的,spl和非spl 是不明确的,其实大家所说的刷spl是刷修改过的spl
      —————————
      原文:

      So what is an SPL anyway? What does it do?

      The SPL, or Second Program Loader, is essentially the Android bootloader. It’s job is more than just loading the Android OS – it also offers several other boot options, including Recovery mode, Fastboot, and HBOOT modes, and ultimately it’s the SPL that allows manipulation of the flash nand on your device. Part of the SPL’s job is to ensure that the data flashed to the device is correct. Most of the current shipping SPLs (apart from the “erfect SPL’s) let us flash a complete ROM image, but don’t let us flash a recovery rom or boot image as it checks the verification signature. Haykuro has modified the SPL’s available to remove this check and this is what the Engineering SPL’s available offer. As the SPL is so crucial to the handset though, you have to be very careful when flashing it as if it’s updated incorrectly then you may be incapable of restoring it without specialised hardware and knowledge. You essentially have a very expensive brick 😉
      from:http://wiki.xda-developers.com/i … TC_Sapphire_Hacking
      xda-developers.com 是国外比较著名的HTC手机论坛,英文好的,可以在这个论坛和他的wiki 淘到好的东西,

      这里是Original SPL list : (from:http://forum.xda-developers.com/showthread.php?t=529019
      Please update us on any new SPL’s so we can include them in this list.

      – HBOOT-1.33.0004 (SAPP10000) : Sapphire PVT 32B SHIP S-ON G : CPLD-10 (Voldafone NL + UK + Australia)
      – HBOOT-1.33.0008 (SAPP10000) : Sapphire PVT 32A SHIP S-ON H : CPLD-12 (TIM (Italian))
      – HBOOT-1.3300.0009 (SAPP10000) : Sapphire PVT 32A SHIP S-ON H : CPLD-12 (Nordic Magic A6161)
      – HBOOT-1.33.0009 (SAPP10000) : Sapphire PVT 32A SHIP S-OFF H : CPLD-12 (Belgian HTC)
      – HBOOT-1.33.0009 (SAPP10000) : Sapphire PVT 32A SHIP S-ON H : CPLD-12 (Greek)
      – HBOOT-1.33.0009 (SAPP50000) : Sapphire PVT 32A SHIP S-OFF H : CPLD-11 (Rogers)
      – HBOOT-1.33.0009 (SAPP50000) : Sapphire PVT 32A SHIP S-ON H : CPLD-12 (Rogers)
      – HBOOT-1.33.0010 (SAPP10000) : Sapphire PVT 32A SHIP S-ON H : CPLD-12
      – HBOOT-1.33.3004 (SAPP30000) : Sapphire PVT 32B DEV S-ON G : CPLD-10 (ION)
      – HBOOT-1.33.3005 from the Japanese ION

      Haykuro quote : “T-Mobile myTouch : 1.33.0006 and 1.33.0010 is the dreaded “perfected” SPL”.
      This means that it’s currently not possible to run “fastboot boot image” on these SPL’s, so don’t try to flash them.
      ==(1.33.0006 and 1.33.0010 目前还没被破解,就不能刷fastboot boot image”)

      SPL Info
      – The G or H at the end identify if it’s a Google or HTC SPL
      – ENG : Engineering version
      – SHIP : Shipment version
      – DEV : Development version (ION)
      – S-off and S-on : Security on and off (writing directly to nand or not) , most probably not SPL linked.
      – PVT 32A (HTC branded) : 288MB RAM / Qualcomm MSM7200a           ==(主板类型)
      – PVT 32B (Google branded) : 192MB RAM / Qualcomm MSM7201a
      – CPLD XX : What does this mean?

      ——————————————————————————————————————-
      SPL就是负责装载 OS 操作系统到 RAM 中。另外 SPL 还包括许多系统命令,如 mtty 中使用的命令等。 SPL 损坏了还可以用烧录器重写。SPL 一般提供这几部分功能:检测手机硬件、寻找系统启动分区、启动操作系统为系统的基本维护提供操作界面,可以通过数据线与操作终端(如 PC )建立连接,并接受和执行相应命令。它里面包含许多命令,像 r2sd, l, doctest (危险命令,他会擦除 gsmdata )等。我们常说的三色屏就是由 SPL 驱动的。检测 SD 卡,当你把一些特殊制作的 SD 卡插入后,SPL 可以在启动时校验并根据 SD 卡内容刷机或执行一些命令。这有点类似于 PC 的从软驱启动。

      由于 G1 的存储空间较少,无法满足一部分用户的日常使用,所以才会出现通过刷新 SPL 文件来增加 G1 的存储空间。因此,SPL 版比非 SPL 版多出了 15M 的可用储存空间。但是,除此之外,在日常使用过程中,两者几乎没有差别。

      说明白点.,.SPL就像电脑的BIOS ,非SPL就是用的是原版的BIOS ,SPL就是要刷自制的BIOS..唯一的区别就是SPL比非SPL系统内存大..

      第二十七讲:如何辨别你的android G1手机是否刷新SPL?

      不少朋友为了更大的可用空间都给G1刷了SPL文件,我在这里说明一下怎样查看SPL文件是否刷新成功,使用这一方法也可以确定自己的手机是否已经刷新过SPL文件,从而判断需要刷新什么版本的ROM,也可以避免重复刷新SPL的问题。

      需要的软件就是“超级终端”了,系统里都自带这个软件了,使用过LINUX系统的朋友想必都对“超级终端”十分熟悉了。
      没有这款软件的话可以去软件区下载

      安装之后选择超级终端 进入类似DOS的界面

      进入后输入 DL 然后按回车

      我们分别看了两台机器 此图是非SPL的 大小为DATA数值为 76544 这说明是没刷过

      这台机器 DATA的数值为 91904 说明已经刷新过SPL了

      其实就是如此的简单

      [转载]Android新手入门基本知识(二)

      mikel阅读(1160)

      第十一讲:Android手机添加删除桌面图标和插件,设置壁纸

      为了更方便 很多人会选择吧自己常用的应用软件放在手机桌面上。那么怎么把你想要用的图标放到桌面上呢?其实很简单
      下面我们就手把手教你如何把应用程序放到桌面上 还有如何删除桌面的图标和插件
      首先我们找一个自己经常使用的软件 用手点击它 然后画面就会跳转到主屏幕的界面上 把手松开就行了

      Android, android, USA, Google, 应用软件 - Android新手入门基本知识

      Android, android, USA, Google, 应用软件 - Android新手入门基本知识

      是不是很简单呢?其实删除桌面的图标和插件 也一样 长按该应用程序 直到出现震动的感觉  桌边上就出现了以垃圾桶的图标 点击它 图标或者是插件就消失了

      Android, android, USA, Google, 应用软件 - Android新手入门基本知识

      Android, android, USA, Google, 应用软件 - Android新手入门基本知识

      Android, android, USA, Google, 应用软件 - Android新手入门基本知识

      第十二讲:如何导入删除联系人

      导入联系人:
      进入“联系人”——“MENU”——“导入联系人”——“MENU”——“全部导入”——”Device” 就把所有SIM上联系人导入到设备上了。

      Android, android, USA, Google, 应用软件 - Android新手入门基本知识

      删除联系人:
      单个删除:选定要删除的联系人按住不放点击删除即可。
      全部删除:设置——应用程序——管理应用程序——联系人储存——清除资料

      第十三讲:Android G1蓝牙与无线网络,APN接入点设置

      G1的蓝牙现在只支持蓝牙耳机(支持蓝牙立体声),和刚出道的iphone一样,G1不支持蓝牙数据传输和同步,只能等待系统的升级了。
      G1的无线比较强大,现在最新的5.0.2Hr3版本ROM下已经支持到54M了。

      打开设置无线和蓝牙:

      设置——无线网络控制——WIFI,进入WIFI设置按下“MENU”可以扫描WIFI接入点,点击“高级”可以“管理网域” ,查看MAC地址,使用静态IP。
      设置——无线网络控制——蓝牙

      Android, android, USA, Google, 应用软件 - Android新手入门基本知识

      关于APN接入点:

      APN接入点其实就是用来设置GPRS的接入点,G1是支持WAP接入的,不过G1上的特殊应用,比如GMAIL,GOOGLE TALK,还有“地图”都需要通过WIFI或者NET接入,并不支持WAP,WAP接入点只可以浏览一些网页。
      APN开关下载(可以关闭APN连接,帮你省钱省流量)
      APN接入点设置:

      第一个:(上网)
      name:cmcc
      apn:cmwap
      proxy:010.000.000.172
      port:80
      apn type: default
      其他留空

      第二个:(彩信接入)
      name:cmcc mms
      apn:cmwap
      proxy:010.000.000.172
      port:80
      mmsc:http://mmsc.monternet.com
      mms proxy:010.000.000.172
      mms port:80
      apn type:mms
      其他留空

      第三个:(net上网)
      name:cmnet
      apn:cmnet
      其他留空

      第十四讲:android手机如何设置个性短信和来电铃声

      方法一:

      设置个性来电铃声:
      先在SD卡上拷贝好你的铃声,之后进入G1的音乐播放器,收听刚才的铃声,按下“MENU”点击“设成铃声”,这样这个铃声就自动设置为你的来电铃声了, 当然你也可以用这个方法添加更多的铃声。进入设置——音效与显示——来电铃声,就可以看到自己的铃声列表了,点击“手机震动”就可以开启来电振动了。

      Android, android, USA, Google, 应用软件 - Android新手入门基本知识

      Android, android, USA, Google, 应用软件 - Android新手入门基本知识

      Android, android, USA, Google, 应用软件 - Android新手入门基本知识

      设置个性短信铃声:
      设置个性短信铃声需要使用到一个软件“短信提示器”,添加自己个性铃声到铃声列表的方式和“设置个性来电铃声”是一样的,选择好自己需要的铃声之后,就可 以进入短信提示器这个软件了,点击“短信设置”——点击“启用通知”,在“提示音”中选择铃声列表中自己的个性铃声。“振动选项”中选择启用震动,另外还 可以选择振动方式和LED灯提示选项,可以说这款软件的功能还是很齐全的,选好之后还可以点击“检查提示功能”看看设置好了没有。

      Android, android, USA, Google, 应用软件 - Android新手入门基本知识

      Android, android, USA, Google, 应用软件 - Android新手入门基本知识

      Android, android, USA, Google, 应用软件 - Android新手入门基本知识

      Android, android, USA, Google, 应用软件 - Android新手入门基本知识

      方法二:

      在sd卡里建立 “ringtones”(来电铃声)”alarms”(闹钟铃声) “notifications”(短信通知铃声),把你不同用途的铃声放到不同的文件夹下手机就可以自动找到。

      用这个方法设置短信铃声的话需要,进入“短信”——MENU——通知设置,选择通知,选取自己的个性铃声,打开振动。


      第十五讲:教你如何使用任务管理器以及分享小窍门


      大家可能注意到了G1上的程序绝大多数没有退出的选项,我们一般是按下“返回”或“HOME”这两个按键退出程序回到桌面的。那么这些程序都到哪里去了呢?他们到底有没有关闭呢?

      其实G1每次最多可以打开6个程序,你每新打开一个程序,这六个程序中的最后一个就会自动关闭,如果要查看正在后台运行的6个程序,可以按住“HOME”按键不放,即可查看和切换程序。

      如果你想关闭单一胡所有程序的话,就要靠第三方软件了,这里推荐论坛汉化的“高级任务管理”这个软件可以方便的切换和关闭后台程序。


      第十六讲:关于G1的GPS软件介绍及打开GPS模块方法

      我们还是以 G1为例 G1 是带有硬件 GPS 芯片的,不过 G1 现在配合 GPS 可用的地图大都不支持离线地图库,也就是说你必须保证有 CMNET 或 WIFI 连接才可以使用 GPS 。这一点是很不符合我国国情的,CMNET 速度比较慢,而且价格比较贵,WIFI 热点在中国又比较少。

      现在比较大众的 GPS 的软件有两个,一个就是手机内置的 GOOGLE MAP 了,不支持离线地图需要通过网络即时下载地图文件,地图资料更新比较快,还有卫星视图。点击下载最新版的GOOGLE MAP for android 3.12 APK文件

      另一个真正的 GPS 离线导航软件就是 国内的 凯立德了,有全国的地图数据可以保存在 SD 卡上,详情请看 G1上真正可用的凯立德CARELAND导航软件,GPS绝对可用。

      使用这两款软件前请先确认手机的GPS模块已经打开,打开GPS模块方法:设置——安全性和位置——启用GPS卫星设置

      第十七讲:将G1内的SIM卡联系人导入到GMAIL的联系人中

      具体方法是:进入联系人——按下“MENU”键——导入联系人——按下“MENU”键——“全部导入”——“Contact type”下选择“Google”。这样你的SIM联系人就可以导入到你的设备中了(联系人后会有“Google”的标识),并且首次同步时联系人会自动 导入到你的GMAIL联系人中。

      Android, android, USA, Google, 应用软件 - Android新手入门基本知识

      Android, android, USA, Google, 应用软件 - Android新手入门基本知识

      Android, android, USA, Google, 应用软件 - Android新手入门基本知识

      Android, android, USA, Google, 应用软件 - Android新手入门基本知识

      注意:在联系人下——按下“MENU”键——“编辑同步处理群组”时选择“同步处理所有联系人”

      第十八讲:android手机如何**信息

      最近在论坛上看到不少朋友都在问有关于短信**的问题,其实大家不需要安装任何软件。

      具体方法很简单,首先进入“短信”,之后再按下“MENU”即可看到以下菜单。只要点击“**”即可进入短信**状态。

      Android, android, USA, Google, 应用软件 - Android新手入门基本知识

      按下 menu键 会下面会出现 4个窗口  然后点**

      Android, android, USA, Google, 应用软件 - Android新手入门基本知识

      出来多个联系人后 接着按下 menu 出现5个框框  根据自己的需要选择一下 收件人

      Android, android, USA, Google, 应用软件 - Android新手入门基本知识

      接着就是编辑信息内容了 和发信息一样

      第十九讲:手机彩信图片如何储存

      首先你需要下载彩信附件保存软件[彩信存储],大家可以去软件区搜索下载。

      2.正常情况下拟接收到一条彩信只可以查看无法保存。

      Android, android, USA, Google, 应用软件 - Android新手入门基本知识

      安装好“彩信存储”这款软件之后,就可以保存短信附件内容了。

      Android, android, USA, Google, 应用软件 - Android新手入门基本知识

      选择好刚才接收到的软件,按下轨迹球。

      Android, android, USA, Google, 应用软件 - Android新手入门基本知识

      弹出保存的提示框

      Android, android, USA, Google, 应用软件 - Android新手入门基本知识

      保存即可

      Android, android, USA, Google, 应用软件 - Android新手入门基本知识

      第二十讲:android手机连接PC后怎样切换为U 盘模式

      之前已经发过关于 APK文件怎样安装程序到手机上  已经介绍过了怎样通过手机与 PC 的连接将软件安装至手机。这一次的课程再来讲解一下怎样将你的手机变为“U盘”和电脑进行连接。

      请注意手机变为 U 盘模式后,无法使用 PC 端的 APK 安装器安装软件。

      先将手机和电脑通过 USB 线连接,滑动屏幕顶端的状态栏,看到以下界面,并点击 “USB 已连接”这个通知。

      Android, android, USA, Google, 应用软件 - Android新手入门基本知识

      点击USB已连接

      Android, android, USA, Google, 应用软件 - Android新手入门基本知识

      [转载]Asp.NET MVC Widget开发

      mikel阅读(1955)

      [转载]Asp.NET MVC Widget开发 – 设计 – Creative dream – 博客园.

      ASP.NET开发博客类系统,我们经常都会用到Widget,像在线好友、最近访问 好友、最新留言等,关于ASP.NET MVC与Asp.NET视图的差异,这里不再说了,大家可去查一下,接下来我以“我的好友”列表来要介绍在Asp.NET MVC实现这一功能以及结构设计。

      • 开发工具:VS 2010 EN
      • 开发语言:Visual C#
      • ASP.NET MVC 3
        1. Asp.NET MVC Widget – 设计
        2. Asp.NET MVC Widget – Controller控制器
        3. Asp.NET MVC Widget – ViewEngine
        4. Asp.NET MVC Widget – Mobile支持

          首先,创建ASP.NET MVC 3 Web程序,这里命名为 “Widgets”

          结构设计

          接下来创建”Widgets”目录结构,如下图:

          /widgets                           存放”Widgets”功能,所有文件

          /widgets/WidgetController.cs                      响应所有Widget访问请求

          /widgets/Web.config            此文件从Views中复制,以实现视图引擎

          /widgets/Friends                                此目录存放Friends Widget设计文件

          /widgets/Friends/Widget.cshtml       为Friends Widget显示页面

          /widgets/_Layout.cshtml          为Widgets的母版页

          流程设计

          Widgets符合Asp.NET MVC http请求响应模式

          所有请求和响应对应WidgetController.cs中一个Action,由Action调用指定Widget的视图,简单以图示。

          例:请求Friends Widget,由Widget Controller寻找指定的视图(widgets/Friends/Widget.cshtml),并返回

          设计就到这里。

          [转载]Asp.NET MVC Widget开发 - Controller控制器

          mikel阅读(1937)

          [转载]Asp.NET MVC Widget开发 – Controller控制器 – Creative dream – 博客园.

          ASP.NET开发博客类系统,我们经常都会用到Widget,像在线好友、最近访问 好友、最新留言等,关于ASP.NET MVC与Asp.NET视图的差异,这里不再说了,大家可去查一下,接下来我以“我的好友”列表来要介绍在Asp.NET MVC实现这一功能以及结构设计。

          • 开发工具:VS 2010 EN
          • 开发语言:Visual C#
          • ASP.NET MVC 3
            1. Asp.NET MVC Widget – 设计
            2. Asp.NET MVC Widget – Controller控制器
            3. Asp.NET MVC Widget – ViewEngine
            4. Asp.NET MVC Widget – Mobile支持

              首先发布一下Controller的代码

              如上图中代码,关于控制器几个需要注意

              • 必须使用[ChildActionOnly]属性,不允许直接访问
              • 返回PartialView
              • 其它部分无区别

              当然,我们可加入更多的Action,只要符合以上规定

              [转载]Android新手入门基本知识(一)

              mikel阅读(951)

              关于Android

              Android一词的本义指“机器人”,同时也是Google于2007年11月5日宣布的基于Linux平台的开源手机操作系统的名称,该平台由操作系统、中间件、用户界面和应用软件组成,号称是首个为移动终端打造的真正开放和完整的移动软件。
              2008年9月22日,美国运营商T-Mobile USA在纽约正式发布第一款Google手机——T-Mobile G1。该款手机为台湾宏达电代工制造,是世界上第一部使用Android操作系统的手机,支持WCDMA/HSPA网络,理论下载速率7.2Mbps,并支持Wi-Fi。
              Android 是Google开发的基于Linux平台的开源手机操作系统。它包括操作系统、用户界面和应用程序 —— 移动电话工作所需的全部软件,而且不存在任何以往阻碍移动产业创新的专有权障碍。Google与开放手机联盟合作开发了 Android,这个联盟由包括中国移动、摩托罗拉、高通、宏达电和 T-Mobile 在内的 30 多家技术和无线应用的领军企业组成。Google通过与运营商、设备制造商、开发商和其他有关各方结成深层次的合作伙伴关系,希望借助建立标准化、开放式的移动电话软件平台,在移动产业内形成一个开放式的生态系统。
              Android 作为谷歌企业战略的重要组成部分,将进一步推进”随时随地为每个人提供信息”这一企业目标的实现。我们发现,全球为数众多的移动电话用户从未使用过任何基 于 Android 的电话。谷歌的目标是让(移动通讯)不依赖于设备甚至平台。出于这个目的,Android 将补充,而不会替代谷歌长期以来奉行的移动发展战略:通过与全球各地的手机制造商和移动运营商结成合作伙伴,开发既有用又有吸引力的移动服务,并推广这些 产品。
              开放手机联盟的成立和 Android 的推出是对现状的重大改变,在带来初步效益之前,还需要不小的耐心和高昂的投入。但是,我们认为全球移动用户从中能获得的潜在利益是值得付出这些努力的。如果你也是一个开发者,并对我们的想法感兴趣,就请再给我们一星期的时间, 届时谷歌便能提供 SDK 了。如果你是一名移动用户,只需再等一段时间,我们的一些合作伙伴计划在 2008 年下半年推出基于 Android 平台的电话产品。如果你已经拥有一部你了解并喜爱的电话,请登录 mobile.google.com ,确保你已经安装谷歌手机地图、Gmail 以及其他一些专为你的手机开发的精彩应用。谷歌将继续努力,让这些服务变得更好,同时也将添加更有吸引力的特性、应用和服务。


              目录

              第  一  讲:android专有名词介绍 不明白的进来
              第  二  讲:android是什么?android现有成员有哪些?
              第  三  讲:手把手教你给android手机设置WIFI无线网络
              第  四  讲:关于CMWAP,CMNET,GPRS,EDGE问题集合
              第  五  讲:查询android手机详细地址方法
              第  六  讲:android手机如何用CMWAP上网?
              第  七  讲:什么是APK文件?他和android手机是什么关系?
              第  八  讲:TF/MicroSD卡的SDHC标准与Class速度等级详解
              第  九  讲:如何安装APK文件到自己的android手机里?
              第  十  讲:如何卸载自己手机上的APK文件程序
              第 十一 讲:android手机添加删除桌面图标和插件,设置壁纸
              第 十二 讲:如何导入删除联系人
              第 十三 讲:android G1蓝牙与无线网络,APN接入点设置
              第 十四 讲:android手机如何设置个性短信和来电铃声
              第 十五 讲:教你如何使用任务管理器以及分享小窍门
              第 十六 讲:关于G1的GPS软件介绍及打开GPS模块方法
              第 十七 讲:将G1内的SIM卡联系人导入到GMAIL的联系人中
              第 十八 讲:android手机如何**信息
              第 十九 讲:手机彩信图片如何储存
              第 二十 讲:android手机连接PC后怎样切换为U 盘模式
              第二十一讲:几个小方法解决手机烧流量问题
              第二十二讲:android手机怎样通过蓝牙传输文件
              第二十三讲:如何清空android G1手机里的系统垃圾
              第二十四讲:轻轻松松为你的手机截图
              第二十五讲:怎样快速更新已安装的软件?
              第二十六讲:什么是SPL?与非SPL的区别
              第二十七讲:如何辨别你的android G1手机是否刷新SPL?



              具体内容


              第一讲:android专有名词介绍 不明白的进来

              1.  固件…………操作系统

              所谓的固件就是将操作系统固定在手机中的一个固定的位置(硬件上),平时不随意改动,活动的数据另外单独放一边。
              这样做的目的在于保护内层的系统程序不受文件操作的影响,提高了稳定性。
              但相对的,如果想要升级系统,就必然涉及对固件的读写更新工作。
              谷歌的Android系统就被写入在了固件中,即使想要查看也要专门的软件和权限。

              2.  刷固件…………安装(or 重装)操作系统

              正是因为固件固定的原因,在我们想要更新系统的时候。就需要将原固件的文件删掉,将新的文件拷进去。
              于是就有了刷固件这么一回事。
              就像Windows安装系统一样,把安装盘放进去就可以直接安装。
              A系统毕竟还没满一岁(从开始用算),还没有什么直接安装系统的软件。(以后肯定有!)
              所以让我们自己动手安装吧。

              3.  ROM(包)…………系统的安装盘

              这个东西就是A系统的打包。我们刷机的时候就是将这个东西刷进固件的。
              当然,由于A系统的开源性质,我们可以自由的改动这个包。
              涉及高端知识。回避这个问题。

              像经常提到的RC XX,G2 Rom,还有x.x.x的之类的东西,都是指的包的版本。
              就是被改动成各式各样的包。

              4.  固件版本

              由于是谷歌公司在专门开发这个系统,官方放出的话必然是所有G友手机升级的风向标。
              固件版本就是官方制定的基础系统,所有的改包都会从官方的包开始改。
              所以官方的一次升级必然会影响整个手机系统的使用情况。
              就像现在大家都在用XP,微软放出了一个补丁包,于是大家都去升级了。
              目前RC33的固件版本是1.4。。(有G友指出这个版本是1.1。。没有仔细研究)
              但Cupcake和G2ROM都是1.5的固件版本,有了很大的更新。

              5.  ROOT

              Root是一个你使用系统的权限,是最高的,有了root权限就可以更改内部系统的文件了。
              为了防止软件更改系统文件(病毒?),A系统隐藏了root权限,也就是一般情况下不能修改系统文件。
              但是。。我们要刷机。所以我们就要取得Root权限

              6.  JF自制固件

              JF自制固件是某达人改的固件的一个,主要特点就是它有自制的recovery恢复模式。可以刷写你自己的包
              我们就用JF的固件作为刷机的基础,开始无穷无尽的刷机(汗)。

              7.何为 Radio 包

              无线通信模块的驱动程序,ROM 是系统程序 Radio 负责网络通信,ROM 和 Radio 可以分开刷,互不影响。如果你的手机刷新了 ROM 后有通讯方面的问题可以刷新 RADIO 试一试。

              8.ROM 的分类

              一般分为两大类,一种是出自手机制造商官方的原版ROM,特点是稳定,功能上 随厂商定制而各有不同;另一种是开发爱好者利用 GOOLGE 官方发布的源代码自主编译的原生 ROM(如啊兴编译的安卓网友协作 ROM 、国外的 CM 系列等等),特点是根据用户具体需求进行调整,使 ROM 更符合不同地区用户的使用习惯,如 啊兴的安卓系列 ROM 就是专门针对中文用户制作,CM 系列的 ROM 则更加适合国外用户。

              另外还有一些热心网友自己进行美化或修改的 ROM ,一般都是基于原生 ROM 制作,也很受大家欢迎。

              9.ROM 的选择

              不同版本的 ROM 有不同的特点,稳定型,速度型,美观型,自己喜欢什么就选择什么,正所谓萝卜青菜各有所爱。
              需要注意的是,同学们在刷机之前,要认真地查阅 此版本 ROM 的注意事项,个别情况下会出现不同 ROM 之间互不兼容的现象。

              10.刷机方法的种类

              1. 恢复模式,用“update.zip”文件;
              2. 进入工程模式,刷新“.NBH”文件;
              3. 使用开发版的工程模式,进行 fastboot 刷机。


              第二讲:android是什么?android现有成员有哪些?

              一:Android是什么?

              android一词的本义指“机器人”,同时也是Google于2007年11月5日宣布的基于Linux平台的开源手机操作系统的名称, 该平台由操作系统、中间件、用户界面和应用软件组成,号称是首个为移动终端打造的真正开放和完整的移动软件。它包括操作系统、用户界面和应用程序 —— 移动电话工作所需的全部软件,而且不存在任何以往阻碍移动产业创新的专有权障碍。Google与开放手机联盟合作开发了 Android,这个联盟由包括中国移动、摩托罗拉、高通、宏达电和 T-Mobile 在内的 30 多家技术和无线应用的领军企业组成。Google通过与运营商、设备制造商、开发商和其他有关各方结成深层次的合作伙伴关系,希望借助建立标准化、开放式 的移动电话软件平台,在移动产业内形成一个开放式的生态系统。

              二:Android团队成员有哪些?

              Android平台的研发队伍阵容强大,包括Google、HTC(宏达电)、T-Mobile、高通、魅族、摩托罗拉、三星、 LG以 及中国移动在内的34家企业都将基于该平台开发手机的新型业务,应用之间的通用性和互联性将在最大程度上得到保持。“开放手机联盟”表示,Android 平台可以促使移动设备的创新,让用户体验到最优越的移动服务,同时,开发商也将得到一个新的开放级别,更方便的进行协同合作,从而保障新型移动设备的研发 速度。

              三:android在中国

              android在中国的前景十分广阔,首先是有成熟的消费者,在国内,android社区十分红火比如androidin.net,这些社区为 android在中国的普及做了很好的推广作用。国内厂商和运营商也纷纷加入了android阵营,包括魅族,中国移动,中国联通,华为通讯,联想等大企 业。我们公司不大,但也花费了一部分精力在android项目的研究上,包括项目思路android的发展前景等····

              第三讲:手把手教你给android手机设置WIFI无线网络

              大家都知道WIFI是一个好东西,简单的来说它就是可以免费再有热点的地方上网,搭载Android系统的G1内置了WiFi,通过WiFi你可以使用YouTube观看网上视频、使用Browser浏览网页、使用Market来下载免费软件、使用IM上MSN进行聊天、使用Gmail来收发邮件,使用……当然,还有很多很多,就不一一举例了。

              下面我们就来叫你如何给你的android手机设置WIFI无线网络

              1.设置WIFI前,首先你要去一个有WIFI热点的地,最平常的地方比如麦当劳、肯德基、星巴克等。
              在主菜单上找到设置一项

              本帖最后由 mycrown 于 2010-10-3 01:18 编辑
              【小白课堂】手把手教你给android手机设置WIFI无线网络
              大家都知道WIFI是一个好东西,简单的来说它就是可以免费再有热点的地方上网,搭载Android系统的G1内置了WiFi,通过WiFi你可以使用 YouTube观看网上视频、使用Browser浏览网页、使用Market来下载免费软件、使用IM上MSN进行聊天、使用Gmail来收发邮件,使 用……当然,还有很多很多,就不一一举例了。

              下面我们就来叫你如何给你的android手机设置WIFI无线网络
              1.设置WIFI前,首先你要去一个有WIFI热点的地,最平常的地方比如麦当劳、肯德基、星巴克等。
              在主菜单上找到设置一项


              Android, android, USA, Google, 应用软件 - Android新手入门基本知识

              然后点击进入设置,接着点击无线控件这一项

              Android, android, USA, Google, 应用软件 - Android新手入门基本知识

              进入无线控件你就会看到关于wifi设置 点击进入

              Android, android, USA, Google, 应用软件 - Android新手入门基本知识

              接着你打开网络 搜索你所在的地点的无线网络

              Android, android, USA, Google, 应用软件 - Android新手入门基本知识

              点击一无线网络进入 然后输入密码

              Android, android, USA, Google, 应用软件 - Android新手入门基本知识

              Android, android, USA, Google, 应用软件 - Android新手入门基本知识

              接着就是等待几十秒钟 然后它会提示你已连接 之后你可以点击浏览器 它就会直接上网了

              Android, android, USA, Google, 应用软件 - Android新手入门基本知识



              第四讲:关于CMWAP,CMNET,GPRS,EDGE问题集合

              1,我知道GPRS,那为啥我设置好的GPRS,G1上面图标显示个E,又看到某些教程说可以上EDGE,这和GPRS啥关系啊

              答:GPRS是通用分组无线业务(General Packet Radio Service)的简称,它是GSM移动电话用户可用的一种移动数据业务。 它经常被描述成“2.5G”,也就是说这项技术位于第二代(2G)和第三代(3G)移动通讯技术之间
              EDGE是英文Enhanced Data Rate for GSM Evolution 的缩写,即增强型数据速率GSM演进技术。EDGE是一种从GSM到3G的过渡技术,说的简单点就是,GPRS是一种上网方式,应用与2G的GSM网络上 的,我们叫2.5G,而EDGE其实也是通过GPRS上,不过就是加强版的GPRS,我们叫2.75GEDGE的速度比GPRS快,北京这里我平均能达到30多K每秒,峰值也达到过40K多。以上是本人亲自测试的。
              一句话:显示EDGE其实就是上了GPRS,而且是加强版的GPRS,速度更快。

              2,什么是CMNET,什么是CMWAP啊

              答:CMWAP和CMNET只是中国移动为其划分的两个GPRS接入方式。中国移动对CMWAP作了一定的限制,主要表现在CMWAP接入时只能访问 GPRS网络内的IP(10.*.*.*),而无法通过路由访问Internet,我们用CMWAP浏览Internet上的网页就是通过WAP网关协议 或它提供的HTTP代理服务实现的。 因此,只有满足以下两个条件的应用才能在中国移动的CMWAP接入方式下正常工作:
              1.应用程序的网络请求基于HTTP协议。
              2.应用程序支持HTTP代理协议或WAP网关协议。
              这也就是为什么我们的G1无法正常用CMWAP的原因。
              一句话:CMWAP是移动限制的,理论上只能上WAP网,而CMNET可以用GPRS浏览WWW。

              3,看那么多我头都大了,你痛快点,G1能不能上中国移动的GPRS

              答:G1的理念就是与网络的完美结合,主打就是上WWW网,而且也并没有行货,CMWAP这个概念只存在与中国移动,国外是没有这概念的所以,如果我们上GPRS,就要设置CMNET。
              一句话:用CMNET方式通过EDGE可以上网

              4,啊,那上CMNET,这资费,是不是比CMWAP贵啊?

              答:因为本人并没有周游世界,所以我也不太清楚其他地区的资费,还希望网友们可以多多提供当地资费政策,方便用户。但是我可以说北京的非包月用户的 CMNET和CMWAP是不区分的,资费一样,也就说假如我动感地带用户定了5元30M,那我用G1上CMNET就可以享受这个资费套餐。包月的是区分资 费的。
              一句话:根据当地运营商政策而定,可以电询当地10086

              5,哦,那我还想问,能不能接受彩信啊?

              答:根据之前写过的教程,有测试成功的,但是,依然有很多用户测试失败,而且即使接受成功了播放时间不能控制。这基本上还是因为CMWAP的原因。所以还是等待有没有更好的教程。
              一句话:按照教程再试试,不行的话,还是再等待下看看有没有更好的方法。

              第五讲:查询android手机详细地址方法

              通过该官方页面我们可以查询我们纤细的手机信息,对买家有很大帮助

              EU:就是欧盟/German:德国/T Mobile (UK):英国;

              Pure Black:全黑/Pure White:全白;

              w/oSIM:表示有无锁卡;

              按键排序:QWERTZ(键位倒置ZY)/QWERTY(键位正常);

              HSUPA :enable(支持)

              第六讲:android手机如何用CMWAP上网?

              在 设置-无线控件-移动网络设置-接入点名称-中国移动WAP设置下
              按Menu -New APN
              按照下面格式填入

              name cmwap
              apn cmwap
              proxy 10.0.0.172
              port 80
              username 空
              pasword 空
              mmsc http://mmsc.monternet.com
              mms proxy 010.000.000.172
              port80

              如图:

              Android, android, USA, Google, 应用软件 - Android新手入门基本知识

              Android, android, USA, Google, 应用软件 - Android新手入门基本知识

              Android, android, USA, Google, 应用软件 - Android新手入门基本知识

              第七讲:什么是APK文件?他和android手机是什么关系?


              APK是Android Package的缩写,即Android安装包。APK是类似Symbian Sis或Sisx的文件格式。通过将APK文件直接传到Android模拟器或Android手机中执行即可安装。

              APK文件其实是zip格式,但后缀名被修改为apk,通过UnZip解压后,可以看到Dex文件,Dex是Dalvik VM executes的全称,即Android Dalvik执行程序,并非Java ME的字节码而是Dalvik字节码。

              一个APK文件结构为:
              mete-INF\   Jar文件中常可以看到
              res\ 存放资源文件的目录
              AndroidManifest.xml  程序全局配置文件
              classes.dex Dalvik字节码
              resources.arsc 编译后的二进制资源文件

              总结下我们发现Android在运行一个程序时首先需要UnZip,然后类似Symbian那样直接,和Windows Mobile中的PE文件有区别,这样做对于程序的保密性和可靠性不是很高,通过dexdump命令可以反编译,但这样做符合发展规律,微软的 Windows Gadgets或者说WPF也采用了这种构架方式。

              在Android平台中dalvik vm的执行文件被打包为apk格式,最终运行时加载器会解压然后获取编译后的androidmanifest.xml文件中的permission分支相 关的安全访问,但仍然存在很多安全限制,如果你将apk文件传到/system/app文件夹下会发现执行是不受限制的。最终我们平时安装的文件可能不是 这个文件夹,而在android rom中系统的apk文件默认会放入这个文件夹,它们拥有着root权限。

              第八讲:TF/MicroSD卡的SDHC标准与Class速度等级详解

              什么是SDHC标准?


              Android, android, USA, Google, 应用软件 - Android新手入门基本知识

              SDHC是“High Capacity SD Memory Card”的缩写,即“高容量SD存储卡”。2006年5月SD协会发布了最新版的SD 2.0的系统规范,在其中规定SDHC是符合新的规范、且容量大于2GB小于等于32GB的SD卡。

              SDHC最大的特点就是高容量(2GB-32GB)。另外,SD协会规定SDHC必须采用FAT32 文件系统,这是因为之前在SD卡中使用的FAT16文件系统所支持的最大容量为2GB,并不能满足SDHC的要求。

              SDHC标志如下图:

              Android, android, USA, Google, 应用软件 - Android新手入门基本知识

              所有大于2G容量的SD卡必须符合SDHC规范,规范中指出SDHC至少需符合Class 2的速度等级,并且在卡片上必须有SDHC标志和速度等级标志。

              Class传输等级:

              Class 0:包括低于Class 2和未标注Speed Class的情况;
              Class 2:能满足观看普通MPEG4 MPEG2 的电影、SDTV、数码摄像机拍摄
              Class 4:可以流畅播放高清电视(HDTV),数码相机连拍等需求;
              Class 6:满足单反相机连拍和专业设备的使用要求;

              购买总结:

              1、市场上常见的2GB以下存储卡(含2GB)都不属于SDHC卡,其等级为Class0.
              2、并不是所有的4GB卡都是Class4,也有Class2的,不同品牌和规格也是有分类和区别的.
              3、4GB Class4还是可以值得考虑的.
              4、认清TF卡上SDHC以及Class等级标识.根据自己的实际需要购卡.不要盲目追求高速度和高容量.目前市场上常用的还是以Kingston,Sandisk,Kingmax为主,各品牌之间存在一定的差异.电脑测试并不完全体现存储卡的性质和特点.卡是要装到手机里的,你电脑里飞速20+,在手机里运行也许只有2+,选卡要选择适合自己需要的,装几首MP3非赶个潮流装个8GB,到时候受折磨的不仅仅是自己,影响更重的是手机的CPU,还有电池的续航时间,要知道,卡的容量越大,会导致文件的寻址时间增加,电池就是这样被消耗和损伤的!

              第九讲:如何安装APK文件到自己的android手机里?

              很多朋友刚拿到G1的时候大概首先就是要往里面装软件了,在ANDROID平台下安装文件的后缀名为“.apk”,就好像PC上的安装文件的后缀名为“.exe”塞班平台安装文件的后缀名为“.sis”一样,所以我们一般称ANDROID平台下安装文件为“APK”。

              手机上首先要进行一些设置,设置——应用程序——勾选“未知源”
              设置——应用程序——开发——勾选“USB 调试”

              方法一
              运用APK安装器,就是将APK文件安装到手机上的一个PC端软件,我们首先需要下载一个USB驱动,在PC上安装好“APK安装器”,这 个软件会自动关联你的APK程序,只要双击一下APK程序就可以自动安装到你的手机里了。    点击下载APK安装器(HiAPK Installer)1.0版正式发

              大家可能问 我们的手机和电脑连不上怎么办?那说明你没有安装驱动?驱动在哪下?其实不用下驱动 在这里我们推荐一个软件 就是91助理FOR android系统的。

              你把你的android手机和电脑连接后打开91 for android手机助理 然后他就会自动帮你下载驱动 同时会连接手机。

              Android, android, USA, Google, 应用软件 - Android新手入门基本知识


              Android, android, USA, Google, 应用软件 - Android新手入门基本知识

              界面上显示我的G1和电脑已连接

              方法二

              大家需要先下载一个资源管理器软件,可以通过网络在 MARKET 中下载一个资源管理器,这里推荐 ASTRO。你也可以直接下载
              过方法一把资源管理器安装好,之后再安装软件只要把 “.APK”的安装文件拷贝到 SD 卡里,之后使用资源管理器软件在SD卡下打开 “.APK”的安装文件,直接安装即可.

              然后把在电脑上下载好了的APK文件 丢到电脑上SD移动设备 Android, android, USA, Google, 应用软件 - Android新手入门基本知识

              然后从手机的资源管理器上找到该文件 安装就行

              方法三

              设置——应用程序——APK安装器
              只要把APK程序都放到SD卡上,就可以直接在这个内置的APK安装器上进行软件的安装与卸载。

              Android, android, USA, Google, 应用软件 - Android新手入门基本知识

              选择应用程序

              Android, android, USA, Google, 应用软件 - Android新手入门基本知识

              点击APK安装器

              Android, android, USA, Google, 应用软件 - Android新手入门基本知识

              然后他就会自动扫描SDCARD上的文件

              Android, android, USA, Google, 应用软件 - Android新手入门基本知识

              显示该文件

              Android, android, USA, Google, 应用软件 - Android新手入门基本知识

              点击安装即可 然后再从你的菜单里面找到该文件 安装成功!

              第十讲:如何卸载自己手机上的APK文件程序


              其实方法很简单,如果你刷新简体版系统的话就更容易找到删除的方法了。

              桌面状态下按下“MENU”——“设置”——“应用程序”——“管理应用程序”——找到你要删除的应用程序,点击卸载。

              Android, android, USA, Google, 应用软件 - Android新手入门基本知识

              点击应用程序进入下一级菜单

              Android, android, USA, Google, 应用软件 - Android新手入门基本知识

              然后点击管理应用程序

              Android, android, USA, Google, 应用软件 - Android新手入门基本知识

              找到你想卸载的应用程序

              Android, android, USA, Google, 应用软件 - Android新手入门基本知识

              点击卸载

              Android, android, USA, Google, 应用软件 - Android新手入门基本知识

              再按确定就OK了

              卸载其实就是这么简单!

              [转载]新浪微博布局学习——妙用Android组件TabHost

              mikel阅读(1017)

              [转载]新浪微博布局学习——妙用TabHost – 农民伯伯 – 博客园.

              前言

              为了更好的开发Android应用程序,除了熟练掌握基本的UI组件和API外,还需要掌握一些技巧,而这些技巧可以通过阅读一些代码来提高,本系列将与大家分享一些新浪微博布局方面的收获,欢迎交流!

              声明

              欢迎转载,但请保留文章原始出处:)

              博客园:http://www.cnblogs.com

              农民伯伯: http://www.cnblogs.com/over140

              版本

              新浪微博 weibo_10235010.apk

              正文

              一、效果图

              红色部分是本文要实现的目标。

              二、实现

              maintabs.xml

              <?xml version=”1.0″ encoding=”UTF-8″?>
              <TabHost Android:id=”@android:id/tabhost” android:layout_width=”fill_parent” android:layout_height=”fill_parent”
              xmlns:android
              =”http://schemas.android.com/apk/res/android”>
              <LinearLayout android:orientation=”vertical” android:layout_width=”fill_parent” android:layout_height=”fill_parent”>
              <FrameLayout android:id=”@android:id/tabcontent” android:layout_width=”fill_parent” android:layout_height=”0.0dip” android:layout_weight=”1.0″ />
              <TabWidget android:id=”@android:id/tabs” android:visibility=”gone” android:layout_width=”fill_parent” android:layout_height=”wrap_content” android:layout_weight=”0.0″ />
              <RadioGroup android:gravity=”center_vertical” android:layout_gravity=”bottom” android:orientation=”horizontal” android:id=”@id/main_radio” android:background=”@drawable/maintab_toolbar_bg” android:layout_width=”fill_parent” android:layout_height=”wrap_content”>
              <RadioButton android:text=”@string/main_home” android:checked=”true” android:id=”@+id/radio_button0″ android:layout_marginTop=”2.0dip” android:drawableTop=”@drawable/icon_1_n” style=”@style/main_tab_bottom” />
              <RadioButton android:id=”@+id/radio_button1″ android:layout_marginTop=”2.0dip” android:text=”@string/main_news” android:drawableTop=”@drawable/icon_2_n” style=”@style/main_tab_bottom” />
              <RadioButton android:id=”@+id/radio_button2″ android:layout_marginTop=”2.0dip” android:text=”@string/main_my_info” android:drawableTop=”@drawable/icon_3_n” style=”@style/main_tab_bottom” />
              <RadioButton android:id=”@+id/radio_button3″ android:layout_marginTop=”2.0dip” android:text=”@string/menu_search” android:drawableTop=”@drawable/icon_4_n” style=”@style/main_tab_bottom” />
              <RadioButton android:id=”@+id/radio_button4″ android:layout_marginTop=”2.0dip” android:text=”@string/more” android:drawableTop=”@drawable/icon_5_n” style=”@style/main_tab_bottom” />
              </RadioGroup>
              </LinearLayout>
              </TabHost>

              styles.xml

              <style name=”main_tab_bottom”>
              <item name=”android:textSize”>@dimen/bottom_tab_font_size</item>
              <item name=”android:textColor”>#ffffffff</item>
              <item name=”android:ellipsize”>marquee</item>
              <item name=”android:gravity”>center_horizontal</item>
              <item name=”android:background”>@drawable/home_btn_bg</item>
              <item name=”android:paddingTop”>@dimen/bottom_tab_padding_up</item>
              <item name=”android:layout_width”>fill_parent</item>
              <item name=”android:layout_height”>wrap_content</item>
              <item name=”android:button”>@null</item>
              <item name=”android:singleLine”>true</item>
              <item name=”android:drawablePadding”>@dimen/bottom_tab_padding_drawable</item>
              <item name=”android:layout_weight”>1.0</item>
              </style>

              home_btn_bg.xml

              <selector
              xmlns:android=”http://schemas.android.com/apk/res/android”>
              <item android:state_focused=”true” android:state_enabled=”true” android:state_pressed=”false” android:drawable=”@drawable/home_btn_bg_s” />
              <item android:state_enabled=”true” android:state_pressed=”true” android:drawable=”@drawable/home_btn_bg_s” />
              <item android:state_enabled=”true” android:state_checked=”true” android:drawable=”@drawable/home_btn_bg_d” />
              <item android:drawable=”@drawable/transparent” />
              </selector>

              代码说明:

              1.  需要注意的是他这里把TabWidget的Visibility设置成了gone!也就是默认难看的风格不见了:,取而代之的是5个带风格的单选按钮.

              2.  注意为单选按钮设置的style,其中最重要的是为其background设置了home_btn_bg.xml,也就是自定义了选中效果。

              Java文件

              public class MainTabActivity extends TabActivity implements
              OnCheckedChangeListener {

              private TabHost mHost;
              private Intent mMBlogIntent;
              private Intent mMoreIntent;
              private Intent mInfoIntent;
              private Intent mSearchIntent;
              private Intent mUserInfoIntent;

              @Override
              protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              requestWindowFeature(Window.FEATURE_NO_TITLE);
              setContentView(R.layout.maintabs);

              // ~~~~~~~~~~~~ 初始化
              this.mMBlogIntent = new Intent(this, HomeListActivity.class);
              this.mSearchIntent = new Intent(this, SearchSquareActivity.class);
              this.mInfoIntent = new Intent(this, MessageGroup.class);
              this.mUserInfoIntent = new Intent(this, MyInfoActivity.class);
              this.mMoreIntent = new Intent(this, MoreItemsActivity.class);

              initRadios();

              setupIntent();
              }

              /**
              * 初始化底部按钮
              */
              private void initRadios() {
              ((RadioButton) findViewById(R.id.radio_button0)).setOnCheckedChangeListener(
              this);
              ((RadioButton) findViewById(R.id.radio_button1)).setOnCheckedChangeListener(
              this);
              ((RadioButton) findViewById(R.id.radio_button2)).setOnCheckedChangeListener(
              this);
              ((RadioButton) findViewById(R.id.radio_button3)).setOnCheckedChangeListener(
              this);
              ((RadioButton) findViewById(R.id.radio_button4)).setOnCheckedChangeListener(
              this);
              }

              /**
              * 切换模块
              */
              @Override
              public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
              if (isChecked) {
              switch (buttonView.getId()) {
              case R.id.radio_button0:
              this.mHost.setCurrentTabByTag(mblog_tab);
              break;
              case R.id.radio_button1:
              this.mHost.setCurrentTabByTag(message_tab);
              break;
              case R.id.radio_button2:
              this.mHost.setCurrentTabByTag(userinfo_tab);
              break;
              case R.id.radio_button3:
              this.mHost.setCurrentTabByTag(search_tab);
              break;
              case R.id.radio_button4:
              this.mHost.setCurrentTabByTag(more_tab);
              break;
              }
              }
              }

              private void setupIntent() {
              this.mHost = getTabHost();
              TabHost localTabHost
              = this.mHost;

              localTabHost.addTab(buildTabSpec(mblog_tab, R.string.main_home,
              R.drawable.icon_1_n,
              this.mMBlogIntent));

              localTabHost.addTab(buildTabSpec(message_tab, R.string.main_news,
              R.drawable.icon_2_n,
              this.mInfoIntent));

              localTabHost.addTab(buildTabSpec(userinfo_tab, R.string.main_my_info,
              R.drawable.icon_3_n,
              this.mUserInfoIntent));

              localTabHost.addTab(buildTabSpec(search_tab, R.string.menu_search,
              R.drawable.icon_4_n,
              this.mSearchIntent));

              localTabHost.addTab(buildTabSpec(more_tab, R.string.more,
              R.drawable.icon_5_n,
              this.mMoreIntent));

              }

              private TabHost.TabSpec buildTabSpec(String tag, int resLabel, int resIcon,
              final Intent content) {
              return this.mHost
              .newTabSpec(tag)
              .setIndicator(getString(resLabel),
              getResources().getDrawable(resIcon))
              .setContent(content);
              }

              代码说明

              1.  由于TabWidget被隐藏,所以相关的事件也会无效,这里取巧用RadioGroup与RadioButton的特性来处理切换,然后监听事件调用setCurrentTabByTag来切换Activity。

              2.  注意即使TabWidget被隐藏,也要为其设置indicator,否则会保持。

              三、总结

              在这之前如果要做这种效果我恐怕第一时间就会想到用ActivityGroup来做,主要是因为TabHost的TabWidget非常难看,用起 来也不方便。其实从源码可以看出,TabHost也是继承自ActivityGroup,这里结合了单选按钮和TabHost,各取其长,有时间可以专门 写一个这样的自定义控件:)

              四、相关文章

              [Android]使用ActivityGroup来切换Activity和Layout

              结束

              本文中使用的资源均反编译自apk文件,这里主要是讲思路,欢迎大家交流。

              [转载]ASP.NET MVC中的Json Binding和Validate

              mikel阅读(1311)

              [转载]ASP.NET MVC中的Json Binding和Validate – 迭戈 – 博客园.

              引子:电子商务网站支付功能页面往往会有很多信息,对于这些信息的保存,往往是分步完成的,那么使用Ajax最合适不过了,比如其中的收货人信息模块。这些信息的新建和编辑保存都是用Ajax来完成的。那么有几种方式完成这个操作呢,我想到如下几种。

              先来看看该功能的截图:

              一般情况下这些信息会对应一个实体类,就命名为:ReceiverInfo,简单起见,我定义ReceiverInfo如下:


              1、将需要的值拼接成json文本,再Action里面处理

              首先您需要将要保存的值拼接成一个json文本,类似:

              var test = "{ ReceiverId: 5, ReceiverName: 'will', Sex: 'F', CreateDate: '2011-02-21' }";

              然后用JQuery保存到数据库,代码如下:

              $.ajax({ url: "/Home/test1", type: "post", cache: false, data: test });

              然后您在Action里面这样操作:

              StreamReader reader = new StreamReader(Request.InputStream); string bodyText = reader.ReadToEnd(); JavaScriptSerializer js = new JavaScriptSerializer(); ReceiverInfo receiver = js.Deserialize<ReceiverInfo>(bodyText); //保存。。。


              2、利用自定义的ModelBinder实现

              JsonBinder

              1 public class JsonBinder<T> : IModelBinder 2 { 3 public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 4 { 5 StreamReader reader = new StreamReader(controllerContext.HttpContext.Request.InputStream); 6 string json = reader.ReadToEnd(); 7 8 if (string.IsNullOrEmpty(json)) 9 return json; 10 11 JavaScriptSerializer serializer = new JavaScriptSerializer(); 12 object jsonData = serializer.DeserializeObject(json); 13 return serializer.Deserialize<T>(json); 14 } 15 }

              我们继承IModelBinder接口,实现其 方法:

              public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)

              即可。我们可以在Action里面这样使用:

              public ActionResult Test1([ModelBinder(typeof(JsonBinder<ReceiverInfo>))] ReceiverInfo receiverInfo)

              这样我们自定义的 IModelBinder就会取代DefaultModelBinder完成数据绑定。


              3、直接传递一个Json对象

              上面两种方法并没有利用MVC的System.ComponentModel.DataAnnotations进行有效的数据验证。您可能需要自己手动验证,无疑增加了工作量。

              我们试试这种方式。

              前端的写法:

              var b = { ReceiverId: 5, ReceiverName: "will", Sex: "F", CreateDate: "2011-02-21" }; $.ajax({ url: "/Home/test1", type: "post", cache: false, data: b, success: function(data) { alert(data.message); }, error: function(xhr, a, b) { alert(xhr.responseText); } });

              Action的写法:

              public ActionResult Test1(ReceiverInfo receiverInfo)

              我们能正常的得到绑定后的数据。而且我们还能利用System.ComponentModel.DataAnnotations进行数据验证。我们为ReceiverInfo做如下改动:

              [System.ComponentModel.DataAnnotations.Required(ErrorMessage = "收货人必须填写")] public string ReceiverName { get; set; }

              并在前端为ReceiverName赋值为空字符串,再次执行,得到提示:

              很好,不过我们有新的要求了,那就是传递更复杂的对象,比如对象套嵌对象,对象有集合属性,这种方式不能胜任了。


              4、利用MvcFutures的JsonValueProviderFactory

              每一版的MVC都有一个MvcFutures,里面会有一些额外的功能,这些功能有些会加入下一个版本中,而这些功能在某些时候很有用处。我查看了 里面的类,发现有一个类JsonValueProviderFactory正是处理复杂对象的提交和数据验证。由于json对象需要特定解析才能使用默认 的DefaultModelBinder,而这个解析过程需要在ValueProvider阶段完成,所以需要实现特定的ValueProvider给 DefaultModelBinder。我们需要实现一个ValueProviderFactory和IValueProvider,而MVC里面的 DictionaryValueProvider<TValue>(继承了IValueProvider)已经足够使用了,所以只需要继承 ValueProviderFactory实现其方法:public override IValueProvider GetValueProvider(ControllerContext controllerContext)即可,具体代码您可以看JsonValueProviderFactory。

              我们定义另一个类:

              ReceiverInfoChild

              public class ReceiverInfoChild { [System.ComponentModel.DataAnnotations.Required(ErrorMessage = "ChildId必须填写")] public string ChildId { get; set; } }

              并为类ReceiverInfo增加一个属性public List<ReceiverInfoChild> ReceiverInfoChild { get; set; }我们把JsonValueProviderFactory拿出来放在项目里面,然后在Global.asax里面注册一下,就可以使用了。

              protected void Application_Start() { AreaRegistration.RegisterAllAreas(); RegisterRoutes(RouteTable.Routes); ValueProviderFactories.Factories.Add(new JsonValueProviderFactory()); }

              因为JsonValueProviderFactory中有:if (!controllerContext.HttpContext.Request.ContentType.StartsWith(“application/json”, StringComparison.OrdinalIgnoreCase))来判断进来的请求是不是json对象,所以我们提交数据的时候需要这样写:

              var ReceiverInfo = [ { ReceiverInfoChild: [{ ChildId: "1" }, { ChildId: "11"}], ReceiverId: 5, ReceiverName: "will", Sex: "F", CreateDate: "2011-02-21" }, { ReceiverInfoChild: [{ ChildId: "2" }, { ChildId: "22"}], ReceiverId: 5, ReceiverName: "will", Sex: "F", CreateDate: "2011-02-21" } ]; $.ajax({ url: "/Home/test1", type: "post", cache: false, contentType: "application/json;charset=utf-8", data: JSON.stringify(ReceiverInfo), success: function(data) { alert(data.message); }, error: function(xhr, a, b) { alert(xhr.responseText); } });

              其中JSON.stringify(ReceiverInfo)是将json对象转换成字符串,您可以到这里下载该类库。

              在Action里面,我们这样写就可以了:

              public ActionResult Test1(List<ReceiverInfo> receiverInfo)

              看一下调试的结果:

              完全正常绑定了值。我们再看看数据验证:


              至此,我们实验了四种方案:

              第一种方案,最麻烦,而且容易出错(可能跟我个人不喜欢拼接字符串有关系);

              第二种方案,有一定的通用性,但是不利于数据验证;

              第三种方案,通用,可以进行有效的数据验证,应对一般的需求够用了,但是处理更复杂的对象不行;

              第四种方案,几乎可以处理我们遇到的所有情况

              另外,这是在ASP.NET MVC2中的使用,到了ASP.NET MVC3,微软已经把JsonValueProviderFactory作为内置的功能了。