<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:clearspace="http://www.jivesoftware.com/xmlns/clearspace/rss" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>Main : Document List - Java ME &amp; Capuchin</title>
    <link>http://developer.sonyericsson.com/community/community/chinese_forums/java_me?view=documents</link>
    <description>Latest Documents in Java ME &amp; Capuchin</description>
    <language>en</language>
    <pubDate>Fri, 20 Nov 2009 11:47:48 GMT</pubDate>
    <generator>Clearspace 2.5.7 (http://jivesoftware.com/products/clearspace/)</generator>
    <dc:date>2009-11-20T11:47:48Z</dc:date>
    <dc:language>en</dc:language>
    <item>
      <title>转 [J2ME] MMAPI的Cannot parse this type of AMR异常之讨论</title>
      <link>http://developer.sonyericsson.com/community/docs/DOC-3332</link>
      <description>&lt;!-- [DocumentBodyStart:16b1bb67-9af6-4587-bba0-5bee8508c4e5] --&gt;&lt;div class='jive-rendered-content'&gt;&lt;p&gt;&lt;h2&gt;&lt;h1 class="title_txt"&gt;&lt;span style="font-weight: normal;"&gt;&lt;span style="font-size: 10pt;"&gt;转自&lt;/span&gt;&lt;/span&gt;&lt;a class="jive-link-external-small" href="http://blog.csdn.net/zhengyun_ustc"&gt;&lt;span style="font-weight: normal;"&gt;&lt;span style="font-size: 10pt;"&gt;旁观者 - 郑昀&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style="font-weight: normal;"&gt;&lt;span style="font-size: 10pt;"&gt;的博客 &lt;strong style="background-color: #fcfaf4;"&gt;&lt;a class="jive-link-external-small" href="http://blog.csdn.net/zhengyun_ustc/archive/2006/04/17/666696.aspx"&gt;&lt;span style="font-weight: normal;"&gt;&lt;span style="font-size: 10pt;"&gt;http://blog.csdn.net/zhengyun_ustc/archive/2006/04/17/666696.aspx&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;&lt;/h2&gt;&lt;h2&gt;&lt;span lang="EN-US"&gt;[J2ME] MMAPI&lt;/span&gt;&lt;span&gt;的&lt;/span&gt;&lt;span lang="EN-US"&gt;Cannot parse this type of AMR&lt;/span&gt;&lt;span&gt;异常之讨论&lt;/span&gt;&lt;/h2&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-size: 12pt;"&gt;&lt;span&gt;郑昀&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt; &lt;/span&gt;&lt;span&gt;草拟&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family: 'Times New Roman';"&gt; 20060417&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;h3&gt;&lt;span style="font-size: 18pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;[&lt;/span&gt;&lt;/span&gt;&lt;span&gt;现象&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-size: 12pt;"&gt;&lt;span&gt;首先，我们假设遇到这种错误的人们了解如何使用&lt;/span&gt;&lt;span lang="EN-US"&gt;MMAPI&lt;/span&gt;&lt;span&gt;，从而排除代码使用不当问题。&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-size: 12pt;"&gt;&lt;span&gt;那么在播放&lt;/span&gt;&lt;span lang="EN-US"&gt;3gp&lt;/span&gt;&lt;span&gt;媒体文件时遇到&lt;/span&gt;&lt;span lang="EN-US"&gt;“&lt;strong&gt;java.lang.Exception: Cannot parse this type of AMR&lt;/strong&gt;”&lt;/span&gt;&lt;span&gt;的异常错误，如果怀疑是&lt;/span&gt;&lt;span lang="EN-US"&gt;ffmpeg&lt;/span&gt;&lt;span&gt;或者其他&lt;/span&gt;&lt;span&gt;转换程序造成的话，那么你可以把&lt;/span&gt;&lt;span lang="EN-US"&gt;Nokia&lt;/span&gt;&lt;span&gt;手机自己拍摄的录像传到&lt;/span&gt;&lt;span lang="EN-US"&gt;PC&lt;/span&gt;&lt;span&gt;机上，这种文件格式就是&lt;/span&gt;&lt;span lang="EN-US"&gt;3gp&lt;/span&gt;&lt;span&gt;的，而且肯定是&lt;/span&gt;&lt;span lang="EN-US"&gt;Nokia&lt;/span&gt;&lt;span&gt;自己的手机程序能播放的。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-size: 12pt;"&gt;&lt;span&gt;但是，我用&lt;/span&gt;&lt;span lang="EN-US"&gt;mmapi&lt;/span&gt;&lt;span&gt;在&lt;/span&gt;&lt;span lang="EN-US"&gt;Nokia S60&lt;/span&gt;&lt;span&gt;模拟器（Nokia Developer's Suite 3.0 for J2ME所携带的模拟器）上播放这种Nokia手机生成的3gp文件时依然得到&lt;/span&gt;&lt;span lang="EN-US"&gt;“&lt;strong&gt;java.lang.Exception: Cannot parse this type of AMR&lt;/strong&gt;”&lt;/span&gt;&lt;span&gt;错误，没有声音，只有视频。&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size: 12pt;"&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-size: 12pt;"&gt;&lt;span&gt;我用下面的命令行：&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;table border="1" cellpadding="0" cellspacing="0" class="MsoNormalTable" width="94%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td valign="top" width="540"&gt;&lt;p align="center" class="MsoNormal"&gt;&lt;span style="font-size: 12pt;"&gt;&lt;strong&gt;Ffmpeg&lt;/strong&gt;&lt;strong&gt;转换命令&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top" width="540"&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size: 12pt;"&gt;ffmpeg -y -i test.mpeg -bitexact -vcodec h263 -b 128 -r 15 -s 176x144 -acodec aac -ac 2 -ar 22500 -ab 24 -f 3gp test.3gp&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top" width="540"&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-size: 12pt;"&gt;&lt;span&gt;或者&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size: 12pt;"&gt;ffmpeg -y -i test.mpeg -ac 1 -acodec amr_nb -ar 8000 -s 176x144 -b 128 -r 15 test.3gp&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-size: 12pt;"&gt;&lt;span&gt;转换出来的&lt;/span&gt;&lt;span lang="EN-US"&gt;3gp&lt;/span&gt;&lt;span&gt;文件，都只能够在&lt;/span&gt;&lt;span lang="EN-US"&gt;Nokia S60&lt;/span&gt;&lt;span&gt;模拟器（Nokia Developer's Suite 3.0 for J2ME所携带的模拟器）上播放视频，但没有声音，也得到了大量的&lt;/span&gt;&lt;strong&gt;java.lang.Exception: Cannot parse this type of AMR&lt;/strong&gt;&lt;span&gt;错误提示。&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size: 12pt;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-size: 12pt;"&gt;&lt;span&gt;我为什么要怀疑仅仅是&lt;/span&gt;&lt;span lang="EN-US"&gt;S60&lt;/span&gt;&lt;span&gt;模拟器的问题呢。因为我把转换好的&lt;/span&gt;&lt;span lang="EN-US"&gt;3gp&lt;/span&gt;&lt;span&gt;文件放在我的服务器上，用&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;table border="1" cellpadding="0" cellspacing="0" class="MsoNormalTable" width="94%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td valign="top" width="540"&gt;&lt;p align="center" class="MsoNormal"&gt;&lt;span style="font-size: 12pt;"&gt;&lt;strong&gt;简单的播放代码&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top" width="540"&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size: 12pt;"&gt;player = Manager.createPlayer(url);&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size: 12pt;"&gt;player.realize();&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-size: 12pt;"&gt;&lt;span lang="EN-US"&gt;player.prefetch();&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-size: 12pt;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;     &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;这种代码在&lt;/span&gt;&lt;strong&gt;Nokia7610&lt;/strong&gt;&lt;strong&gt;真机&lt;/strong&gt;&lt;span&gt;上运行播放这个远端资源&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;a class="jive-link-external-small" href="http://218.249.90.118/toodou/test.3gp"&gt;http://218.249.90.118/toodou/test.3gp&lt;/a&gt; &lt;/span&gt;&lt;span&gt;，结果正常地播放了，&lt;strong&gt;有声音，有图像&lt;/strong&gt;！&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-size: 12pt;"&gt;&lt;span&gt;所以说明&lt;/span&gt;&lt;span lang="EN-US"&gt;Nokia 7610&lt;/span&gt;&lt;span&gt;真机的&lt;/span&gt;&lt;span lang="EN-US"&gt;MMAPI&lt;/span&gt;&lt;span&gt;对于&lt;/span&gt;&lt;span lang="EN-US"&gt;3gp&lt;/span&gt;&lt;span&gt;文件中的音频解析是没问题的。出问题的是&lt;/span&gt;&lt;span lang="EN-US"&gt;S60&lt;/span&gt;&lt;span&gt;模拟器（Nokia Developer's Suite 3.0 for J2ME所携带的模拟器）&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/p&gt;&lt;/div&gt;&lt;!-- [DocumentBodyEnd:16b1bb67-9af6-4587-bba0-5bee8508c4e5] --&gt;</description>
      <pubDate>Fri, 20 Nov 2009 11:46:19 GMT</pubDate>
      <author>developerworldwatch@kpi-consulting.net</author>
      <guid>http://developer.sonyericsson.com/community/docs/DOC-3332</guid>
      <dc:date>2009-11-20T11:46:19Z</dc:date>
      <clearspace:dateToText>1 day, 20 hours ago</clearspace:dateToText>
    </item>
    <item>
      <title>转 [J2ME]手机流媒体之实作[附源码][与RTSP/MMS协议无关]</title>
      <link>http://developer.sonyericsson.com/community/docs/DOC-3331</link>
      <description>&lt;!-- [DocumentBodyStart:bfcf5df4-d624-4c74-96f4-c845fda59a7b] --&gt;&lt;div class='jive-rendered-content'&gt;&lt;p&gt;&lt;h1 class="title_txt"&gt;&lt;span style="font-weight: normal;"&gt;&lt;span style="font-size: 10pt;"&gt;转自&lt;a class="jive-link-external-small" href="http://blog.csdn.net/zhengyun_ustc"&gt;旁观者 - 郑昀&lt;/a&gt;的博客&lt;a class="jive-link-external-small" href="http://blog.csdn.net/zhengyun_ustc/archive/2006/03/28/641991.aspx"&gt;&lt;span&gt;&lt;span&gt;http://blog.csdn.net/zhengyun_ustc/archive/2006/03/28/641991.aspx&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;&lt;h1 class="title_txt"&gt;  [J2ME]手机流媒体之实作[附源码][与RTSP/MMS协议无关]&lt;cite class="fav_csdnstylebykimi"&gt;&lt;/cite&gt;&lt;/h1&gt;&lt;div class="blogstory"&gt;&lt;table border="1" cellpadding="0" cellspacing="0" class="MsoNormalTable" width="93%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td valign="top" width="348"&gt;&lt;p align="center" class="MsoNormal"&gt;&lt;span style="font-size: 12pt;"&gt;&lt;strong&gt;郑昀@ultrapower&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td valign="top" width="147"&gt;&lt;p align="center" class="MsoNormal"&gt;&lt;span style="font-size: 12pt;"&gt;&lt;strong&gt;产品名称&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td valign="top" width="121"&gt;&lt;p align="center" class="MsoNormal"&gt;&lt;strong&gt;产品版本&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top" width="348"&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size: 12pt;"&gt;Keyword: JavaME Streaming Audio MMAPI&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td valign="top" width="147"&gt;&lt;p align="center" class="MsoNormal"&gt;&lt;span style="font-size: 12pt;"&gt;&lt;strong&gt;StreamingDemo&lt;/strong&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td valign="top" width="121"&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size: 12pt;"&gt;1.0.13&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p align="right" class="MsoNormal"&gt;&lt;strong&gt; [J2ME]现行环境下&lt;/strong&gt;&lt;strong&gt;手机&lt;/strong&gt;&lt;/p&gt;&lt;p align="right" class="MsoNormal"&gt;&lt;strong&gt;实现网络媒体的流畅实时播放&lt;/strong&gt;&lt;/p&gt;&lt;p align="right" class="MsoNormal"&gt;&lt;strong&gt;之简单演示&lt;/strong&gt;&lt;/p&gt;&lt;p align="right" class="MsoNormal"&gt;&lt;strong&gt;(StreamingDemo)&lt;/strong&gt;&lt;/p&gt;&lt;p align="right" class="MsoNormal"&gt;&lt;strong&gt;说明&lt;/strong&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family: 'Times New Roman'; font-size: 12pt;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;strong&gt;我的资源：&lt;/strong&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;a class="jive-link-external-small" href="http://www.cnblogs.com/Files/zhengyun_ustc/StreamingDemo-src-1.0.13.rar"&gt;&lt;span style="font-family: 'Times New Roman'; font-size: 12pt;"&gt;http://www.cnblogs.com/Files/zhengyun_ustc/StreamingDemo-src-1.0.13.rar&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: 'Times New Roman'; font-size: 12pt;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-size: 12pt;"&gt;&lt;span&gt;这个&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;1.0.13&lt;/span&gt;&lt;/span&gt;&lt;span&gt;版本是&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;j2me&lt;/span&gt;&lt;/span&gt;&lt;span&gt;流媒体播放思路的简单演示软件，并不是对现有的RTSP/MMS流媒体服务器的客户端实现，而是自定义算法下载来保证实时播放，可以在&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;Nokia 7610&lt;/span&gt;&lt;/span&gt;&lt;span&gt;手机上真实运行。在手机上使用，请在选择连接点时选择“移动梦网”连接点。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-size: 12pt;"&gt;&lt;span&gt;如果修改源代码中&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;CommandResources.java&lt;/span&gt;&lt;/span&gt;&lt;span&gt;中的&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;m_bCMWAPProxy&lt;/span&gt;&lt;/span&gt;&lt;span&gt;标志使之走&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;CMNET&lt;/span&gt;&lt;/span&gt;&lt;span&gt;通道，那么能够在&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;Nokia S60&lt;/span&gt;&lt;/span&gt;&lt;span&gt;的模拟器上运行。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-size: 12pt;"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span&gt;&lt;span style="font-size: 12pt;"&gt;本源代码的大致思路来自于我上次写的三篇讨论稿&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;a class="jive-link-external-small" href="http://blog.csdn.net/zhengyun_ustc/archive/2006/01/12/577347.aspx"&gt;&lt;span style="font-size: 12pt;"&gt;J2me&lt;span lang="EN-US"&gt;&lt;span lang="EN-US"&gt;流媒体技术实现讨论&lt;/span&gt;&lt;/span&gt;[1]&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;a class="jive-link-external-small" href="http://blog.csdn.net/zhengyun_ustc/archive/2006/01/15/580084.aspx"&gt;&lt;span style="font-size: 12pt;"&gt;J2me&lt;span lang="EN-US"&gt;&lt;span lang="EN-US"&gt;流媒体技术实现讨论&lt;/span&gt;&lt;/span&gt;[2]&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;a class="jive-link-external-small" href="http://blog.csdn.net/zhengyun_ustc/archive/2006/01/17/582121.aspx"&gt;&lt;span style="font-size: 12pt;"&gt;J2me&lt;span lang="EN-US"&gt;&lt;span lang="EN-US"&gt;流媒体技术实现讨论&lt;/span&gt;&lt;/span&gt;[3] &lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span style="font-size: 12pt;"&gt;&lt;span&gt;，&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;StreamingDemo&lt;/span&gt;&lt;/span&gt;&lt;span&gt;的代码你可以借鉴，但不得用于商业用途，除非得到我的授权。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-size: 12pt;"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-size: 12pt;"&gt;&lt;span&gt;手机jar安装包下载： &lt;br/&gt;&lt;a class="jive-link-external-small" href="http://www.cnblogs.com/Files/zhengyun_ustc/StreamingDemo-deployed.rar"&gt;http://www.cnblogs.com/Files/zhengyun_ustc/StreamingDemo-deployed.rar&lt;/a&gt;&lt;span&gt; &lt;/span&gt;&lt;br/&gt;可以将这个包中的StreamingDemo.jar传到您的手机上进行安装。 &lt;br/&gt;使用时，请选择移动梦网连接点。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-size: 12pt;"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span&gt;&lt;span style="font-size: 12pt;"&gt;如果你想使用劈分好的媒体文件，请从&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;a class="jive-link-external-small" href="http://www.cnblogs.com/Files/zhengyun_ustc/StreamingDemo-src-1.0.13.rar"&gt;&lt;span style="font-family: 'Times New Roman'; font-size: 12pt;"&gt;http://www.cnblogs.com/Files/zhengyun_ustc/changjin.split.rar&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="font-size: 12pt;"&gt;下载。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family: 'Times New Roman'; font-size: 12pt;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;h1&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;span&gt;背景、功能&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/h1&gt;&lt;p class="MsoNormalIndent"&gt;&lt;strong&gt;摘要&lt;/strong&gt;&lt;span&gt;：本章&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;简单描述&lt;/span&gt;&lt;strong&gt;StreamingDemo&lt;/strong&gt;&lt;span&gt;的背景、功能。&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormalIndent"&gt;&lt;span lang="EN-US"&gt; &lt;/span&gt;&lt;/p&gt;&lt;h2&gt;&lt;span lang="EN-US"&gt;1.1. &lt;/span&gt;&lt;span&gt;手机上的流媒体&lt;/span&gt;&lt;/h2&gt;&lt;p class="MsoNormalIndent"&gt;&lt;span&gt;很多人都在&lt;/span&gt;&lt;span lang="EN-US"&gt;j2medev.com&lt;/span&gt;&lt;span&gt;上讨论过流媒体的实现方式。&lt;/span&gt;&lt;span&gt;国外有一个人提出一种思路，并且号称在&lt;/span&gt;&lt;strong&gt;Nokia6260&lt;/strong&gt;&lt;span lang="EN-US"&gt;[&lt;/span&gt;&lt;em&gt;相关数据：诺基亚&lt;/em&gt;&lt;em&gt; 6260 Nokia62602.0 (3.0436.0) SymbianOS7.0s Series602.1 ProfileMIDP-2.0 ConfigurationCLDC-1.0&lt;/em&gt;&lt;span lang="EN-US"&gt;]&lt;/span&gt;&lt;span&gt;运行了。&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormalIndent"&gt;&lt;strong&gt;当然我们这里说的不是对RTSP/MMS这种主流的流媒体服务器的客户端实现，因为现在中国市场的很多很多手机的Java环境都不支持这两个协议，只有新出的某些手机才内置支持这一功能。&lt;/strong&gt;&lt;/p&gt;&lt;p class="MsoNormalIndent"&gt;&lt;strong&gt;我们这次讲的是，在现有GPRS环境下，在现有的一两千块钱的手机条件下，如何做到流媒体实时播放呢，而且还能做到较为流畅呢？&lt;/strong&gt;&lt;/p&gt;&lt;p class="MsoNormalIndent"&gt;&lt;span lang="EN-US"&gt;2006&lt;/span&gt;&lt;span&gt;年&lt;/span&gt;&lt;span lang="EN-US"&gt;1&lt;/span&gt;&lt;span&gt;月份，我&lt;/span&gt;恰巧看到了&lt;/p&gt;&lt;p class="MsoNormalIndent"&gt;&lt;span&gt;就此思路和诸位高手讨论了一下，并且写了三篇讨论稿，有了大致的思路。但一直都没有时间去测试这个思路是否可行。&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormalIndent"&gt;&lt;span&gt;今天索性抽出了一两个小时，把这个思路写出来放在真实手机&lt;/span&gt;&lt;span lang="EN-US"&gt;/GPRS&lt;/span&gt;&lt;span&gt;网络上测试，不敢独享，遂开放代码，希望借此抛砖引玉。&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-size: 12pt;"&gt;&lt;span&gt;这里给出&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;StreamingDemo&lt;/span&gt;&lt;/span&gt;&lt;span&gt;的界面，很简单，主要的线程操作和消息处理都在后台：&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-size: 12pt;"&gt;&lt;span&gt;&lt;a href="http://blog.csdn.net/images/blog_csdn_net/zhengyun_ustc/187902/r_Streaming.HttpConnection.JPG"&gt;&lt;img alt="Streaming.HttpConnection" id="ViewPicture.ascx_GalleryImage" src="http://blog.csdn.net/images/blog_csdn_net/zhengyun_ustc/187902/r_Streaming.HttpConnection.JPG"/&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style="font-size: 12pt;"&gt;&lt;span&gt;&lt;h2&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family: Arial;"&gt;1.2. &lt;/span&gt;&lt;/span&gt;&lt;span&gt;我所谓流媒体的功能&lt;/span&gt;&lt;/h2&gt;&lt;p class="MsoNormal"&gt;&lt;span&gt;以前我们谈过：&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span&gt;第一步：&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;br/&gt;&lt;/span&gt;&lt;span&gt;声明两个&lt;/span&gt;&lt;span lang="EN-US"&gt;Player&lt;/span&gt;&lt;span&gt;，分别由两个独立的线程掌控着；&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;br/&gt;&lt;br/&gt;&lt;/span&gt;&lt;span&gt;第二步：&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;br/&gt;HttpConnection&lt;/span&gt;&lt;span&gt;开始向服务器请求该&lt;/span&gt;&lt;span lang="EN-US"&gt;audio&lt;/span&gt;&lt;span&gt;文件的第一部分字节，我们定这次读取的字节数为&lt;/span&gt;&lt;span lang="EN-US"&gt;18KB&lt;/span&gt;&lt;span&gt;；&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;br/&gt;&lt;br/&gt;&lt;/span&gt;&lt;span&gt;第三步：&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;br/&gt;&lt;/span&gt;&lt;span&gt;等第一部分数据到位后，&lt;/span&gt;&lt;span lang="EN-US"&gt;Player A&lt;/span&gt;&lt;span&gt;开始&lt;/span&gt;&lt;span lang="EN-US"&gt;realize&lt;/span&gt;&lt;span&gt;和&lt;/span&gt;&lt;span lang="EN-US"&gt;prefetch&lt;/span&gt;&lt;span&gt;，并开始播放；&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;br/&gt;&lt;br/&gt;&lt;/span&gt;&lt;span&gt;第四步：&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;br/&gt;&lt;/span&gt;&lt;span&gt;在&lt;/span&gt;&lt;span lang="EN-US"&gt;Player A&lt;/span&gt;&lt;span&gt;播放同时，&lt;/span&gt;&lt;span lang="EN-US"&gt;(18KB&lt;/span&gt;&lt;span&gt;的&lt;/span&gt;&lt;span lang="EN-US"&gt;amr&lt;/span&gt;&lt;span&gt;数据可以播放&lt;/span&gt;&lt;span lang="EN-US"&gt;10&lt;/span&gt;&lt;span&gt;秒钟&lt;/span&gt;&lt;span lang="EN-US"&gt;)&lt;/span&gt;&lt;span&gt;，&lt;/span&gt;&lt;span lang="EN-US"&gt;HttpConnection&lt;/span&gt;&lt;span&gt;继续请求第二部分数据&lt;/span&gt;&lt;span lang="EN-US"&gt;(&lt;/span&gt;&lt;span&gt;假设&lt;/span&gt;&lt;span lang="EN-US"&gt;GPRS&lt;/span&gt;&lt;span&gt;每秒钟传输&lt;/span&gt;&lt;span lang="EN-US"&gt;3KB&lt;/span&gt;&lt;span&gt;，那么&lt;/span&gt;&lt;span lang="EN-US"&gt;18KB&lt;/span&gt;&lt;span&gt;需要传输&lt;/span&gt;&lt;span lang="EN-US"&gt;6&lt;/span&gt;&lt;span&gt;秒，算上前后通讯损失的时间，应该不会超过&lt;/span&gt;&lt;span lang="EN-US"&gt;10&lt;/span&gt;&lt;span&gt;秒钟&lt;/span&gt;&lt;span lang="EN-US"&gt;)&lt;/span&gt;&lt;span&gt;；&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;br/&gt;&lt;br/&gt;&lt;/span&gt;&lt;span&gt;第五步：&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;br/&gt;&lt;/span&gt;&lt;span&gt;第二部分数据到位后，假设&lt;/span&gt;&lt;span lang="EN-US"&gt;Player A&lt;/span&gt;&lt;span&gt;还没有播放完&lt;/span&gt;&lt;span lang="EN-US"&gt;(&lt;/span&gt;&lt;span&gt;这需要调整你的每一部份数据字节数来使得假设成立&lt;/span&gt;&lt;span lang="EN-US"&gt;)&lt;/span&gt;&lt;span&gt;，那么将数据喂给&lt;/span&gt;&lt;span lang="EN-US"&gt;Player B&lt;/span&gt;&lt;span&gt;让它&lt;/span&gt;&lt;span lang="EN-US"&gt;realize&lt;/span&gt;&lt;span&gt;和&lt;/span&gt;&lt;span lang="EN-US"&gt;prefetch&lt;/span&gt;&lt;span&gt;；&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;br/&gt;&lt;br/&gt;&lt;/span&gt;&lt;span&gt;第六步：&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;br/&gt;Player A&lt;/span&gt;&lt;span&gt;播放完后，得到事件通知，于是让&lt;/span&gt;&lt;span lang="EN-US"&gt;Player B&lt;/span&gt;&lt;span&gt;开始播放。&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;br/&gt;&lt;br/&gt;&lt;/span&gt;&lt;span&gt;如此往复。&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;br/&gt;&lt;br/&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;大致的思路就是这样。&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span&gt;这次，我们起了两个线程，一个叫做“&lt;/span&gt;&lt;span lang="EN-US"&gt;Main(&lt;/span&gt;&lt;span&gt;主&lt;/span&gt;&lt;span lang="EN-US"&gt;) &lt;/span&gt;&lt;span&gt;”，一个叫做“&lt;/span&gt;&lt;span lang="EN-US"&gt;Secondary(&lt;/span&gt;&lt;span&gt;从属&lt;/span&gt;&lt;span lang="EN-US"&gt;)&lt;/span&gt;&lt;span&gt;”，他们都掌握着一个&lt;/span&gt;&lt;span lang="EN-US"&gt;Player&lt;/span&gt;&lt;span&gt;，同样一个是&lt;/span&gt;&lt;span lang="EN-US"&gt;Main Player&lt;/span&gt;&lt;span&gt;，一个是&lt;/span&gt;&lt;span lang="EN-US"&gt;Secondary Player&lt;/span&gt;&lt;span&gt;。这两个&lt;/span&gt;&lt;span lang="EN-US"&gt;Player&lt;/span&gt;&lt;span&gt;的操作实际上都被&lt;/span&gt;&lt;span lang="EN-US"&gt;Audio.java&lt;/span&gt;&lt;span&gt;类完全封装好了。线程里面仅仅是调用&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;strong&gt;Audio.prefetchSound(m_form,&lt;/strong&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;strong&gt;                                             m_isInputMusic,&lt;/strong&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;strong&gt;                                             m_Sequence);&lt;/strong&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span&gt;啦，&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;strong&gt;Audio.playSound(m_Sequence);&lt;/strong&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span&gt;啦，这样就可以把媒体资源预先运算以及播放了。&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt; &lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span&gt;同时，还必须用到&lt;/span&gt;&lt;span lang="EN-US"&gt;PlayerListener&lt;/span&gt;&lt;span&gt;接口，来得到播放器的各种事件通知，我们需要得知每一个播放器的播放结束消息，以便作出下一步选择：是让从属线程开始播放呢，还是让主线程开始播放呢。&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;PlayerListener&lt;/span&gt;&lt;span&gt;的播放结束消息&lt;/span&gt;&lt;span lang="EN-US"&gt;(&lt;strong&gt;PlayerListener.END_OF_MEDIA&lt;/strong&gt;)&lt;/span&gt;&lt;span&gt;的处理中，我们还必须用到&lt;/span&gt;&lt;span lang="EN-US"&gt;MVC&lt;/span&gt;&lt;span&gt;模式中的&lt;/span&gt;&lt;span lang="EN-US"&gt;Controller&lt;/span&gt;&lt;span&gt;，它是代码中的&lt;/span&gt;&lt;span lang="EN-US"&gt;GUIController.java&lt;/span&gt;&lt;span&gt;，它负责处理几个消息：&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;span&gt;l&lt;span&gt;         &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;strong&gt;EventID.EVENT_MAIN_DownloadCompleted&lt;/strong&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;span&gt;l&lt;span&gt;         &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;strong&gt;EventID.EVENT_Main_BeginToPlay&lt;/strong&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;span&gt;l&lt;span&gt;         &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;strong&gt;EventID.EVENT_SECONDARY_BeginToPlay&lt;/strong&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt; &lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span&gt;怎么综合使用这些消息和事件呢？&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span&gt;比如说，当主线程的媒体文件下载完毕后，就应该通知&lt;/span&gt;&lt;span lang="EN-US"&gt;GUIController&lt;/span&gt;&lt;span&gt;让从属线程也开始下载并加载媒体文件。&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span&gt;当主线程的媒体文件播放完毕了，这时候照理说从属线程的&lt;/span&gt;&lt;span lang="EN-US"&gt;Player&lt;/span&gt;&lt;span&gt;也已经预先加载好了下一个要播放的媒体文件&lt;/span&gt;&lt;span lang="EN-US"&gt;(&lt;/span&gt;&lt;span&gt;如果不行的话就应该调整媒体文件的大小了以使得下载时间和播放时间差不多&lt;/span&gt;&lt;span lang="EN-US"&gt;)&lt;/span&gt;&lt;span&gt;，就应该在&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;public void playerUpdate(Player player, String event, Object data)&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span&gt;的函数处理中，让&lt;/span&gt;&lt;span lang="EN-US"&gt;Secondary Player&lt;/span&gt;&lt;span&gt;播放了。&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt; &lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span&gt;这次我们直接将媒体文件用讨论稿中谈及的&lt;/span&gt;&lt;span lang="EN-US"&gt;ffmpeg&lt;/span&gt;&lt;span&gt;自动切分的办法，已经辟成&lt;/span&gt;&lt;span lang="EN-US"&gt;11&lt;/span&gt;&lt;span&gt;小段的&lt;/span&gt;&lt;span lang="EN-US"&gt;AMR&lt;/span&gt;&lt;span&gt;文件了，每一个&lt;/span&gt;&lt;span lang="EN-US"&gt;AMR&lt;/span&gt;&lt;span&gt;文件都可以独立播放，连起来就是一首完整的《大长今》乐曲。&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;PlayerA&lt;/span&gt;&lt;span&gt;和&lt;/span&gt;&lt;span lang="EN-US"&gt;PlayerB&lt;/span&gt;&lt;span&gt;只是周而复始的下载、预运算、播放他们罢了。只不过掌控着&lt;/span&gt;&lt;span lang="EN-US"&gt;Player&lt;/span&gt;&lt;span&gt;的两个线程和主控制器，会选择时机来让这些操作次第展开。&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt; &lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span&gt;上面所说的逻辑，可以用下图表示：&lt;/span&gt;&lt;/p&gt;&lt;span&gt;&lt;/span&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;a href="http://static.flickr.com/48/119270221_22b37c5793.jpg"&gt;&lt;img src="http://static.flickr.com/48/119270221_22b37c5793.jpg"/&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;span lang="EN-US"&gt;&lt;h1&gt;&lt;span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;2 &lt;/span&gt;使用感受&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/h1&gt;&lt;p class="MsoNormalIndent"&gt;&lt;strong&gt;摘要&lt;/strong&gt;&lt;span&gt;：本章&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;简单描述&lt;/span&gt;&lt;strong&gt;StreamingDemo&lt;/strong&gt;&lt;strong&gt;在真实&lt;/strong&gt;&lt;strong&gt;GPRS&lt;/strong&gt;&lt;strong&gt;环境下&lt;/strong&gt;&lt;span&gt;的使用感受。&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormalIndent"&gt;&lt;span lang="EN-US"&gt; &lt;/span&gt;&lt;/p&gt;&lt;h2&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family: Arial;"&gt;2.1. Nokia7610&lt;/span&gt;&lt;/span&gt;&lt;span&gt;手机上的设置&lt;/span&gt;&lt;/h2&gt;&lt;p class="MsoNormal"&gt;&lt;span&gt;如果你真的要在手机上用到这种功能，那么请申请开通你的&lt;/span&gt;&lt;span lang="EN-US"&gt;GPRS&lt;/span&gt;&lt;span&gt;包月套餐，那样&lt;/span&gt;&lt;span lang="EN-US"&gt;20&lt;/span&gt;&lt;span&gt;块钱就可以使用&lt;/span&gt;&lt;span lang="EN-US"&gt;50MB&lt;/span&gt;&lt;span&gt;流量的&lt;/span&gt;&lt;span lang="EN-US"&gt;GPRS&lt;/span&gt;&lt;span&gt;了。&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span&gt;如果你的手机是&lt;/span&gt;&lt;strong&gt;Nokia&lt;/strong&gt;&lt;span&gt;的&lt;/span&gt;&lt;span lang="EN-US"&gt;S60&lt;/span&gt;&lt;span&gt;系列手机，建议用&lt;/span&gt;&lt;strong&gt;Nokia&lt;/strong&gt;&lt;strong&gt;程序管理器&lt;/strong&gt;&lt;span&gt;设置这个应用配置一个参数：&lt;strong&gt;在连接网络时第一次询问&lt;/strong&gt;。否则你会屡屡被网络连接警告框打断的。&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;h2&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family: Arial;"&gt;2.2. Nokia7610&lt;/span&gt;&lt;/span&gt;&lt;span&gt;手机上的使用感受&lt;/span&gt;&lt;/h2&gt;&lt;p class="MsoNormal"&gt;&lt;span&gt;这种流媒体的播放，还是取决于使用时&lt;/span&gt;&lt;span lang="EN-US"&gt;GPRS&lt;/span&gt;&lt;span&gt;网络的好坏。&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span&gt;我在晚上&lt;/span&gt;&lt;span lang="EN-US"&gt;19&lt;/span&gt;&lt;span&gt;点使用了一下，感觉比较流畅，甚至超乎我的预期，不认真听，甚至感觉不到在哪里停顿的。&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormalIndent"&gt;&lt;span&gt;但是在晚上&lt;/span&gt;&lt;span lang="EN-US"&gt;20&lt;/span&gt;&lt;span&gt;点又用了一下，就有点拖拖拉拉的，延迟较为明显。&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormalIndent"&gt;&lt;span&gt;可见现行的&lt;/span&gt;&lt;span lang="EN-US"&gt;GPRS&lt;/span&gt;&lt;span&gt;网络环境还是容易出现拥挤的。&lt;/span&gt;&lt;/p&gt;&lt;/span&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;h1&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;3 &lt;/span&gt;&lt;/span&gt;&lt;span&gt;开源版权声明&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/h1&gt;&lt;p class="MsoNormal"&gt;&lt;span&gt;由于这个&lt;strong&gt;手机流媒体简单演示&lt;/strong&gt;的&lt;/span&gt;&lt;span&gt;思路和代码来自于郑昀以前的讨论稿，今为了促进&lt;/span&gt;&lt;span lang="EN-US"&gt;J2ME&lt;/span&gt;&lt;span&gt;多媒体应用发展，&lt;span&gt;决定遵照&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;GPL&lt;/span&gt;&lt;span&gt;协议的大意开放源代码，您可以自由传播和修改，在遵照下面的约束条件的前提下：&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt; &lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;table border="1" cellpadding="0" cellspacing="0" class="MsoNormalTable" width="94%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td valign="top" width="624"&gt;&lt;p class="MsoNormal"&gt;&lt;strong&gt;条件&lt;/strong&gt;&lt;strong&gt;1&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top" width="624"&gt;&lt;p class="MsoNormal"&gt;&lt;span&gt;只要你在&lt;/span&gt;&lt;span&gt;&lt;span style="font-family: 'Times New Roman';"&gt; &lt;/span&gt;&lt;/span&gt;&lt;strong&gt;手机流媒体简单演示&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;span&gt;的&lt;/span&gt;&lt;span&gt;每一副本上明显和恰当地出版版权声明，保持此许可证的声明和没有担保的声明完整无损，并和程序一起给每个其他的程序接受者一份许可证的副本，你就可以用任何媒体复制和发布你收到的原始的程序的源代码。你可以为转让副本的实际行动收取一定费用，但必须事先得到郑昀的同意。&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt; &lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;table border="1" cellpadding="0" cellspacing="0" class="MsoNormalTable" width="94%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td valign="top" width="624"&gt;&lt;p class="MsoNormal"&gt;&lt;strong&gt;条件&lt;/strong&gt;&lt;strong&gt;2&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top" width="624"&gt;&lt;p class="MsoNormal"&gt;&lt;span&gt;你可以修改&lt;/span&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;手机流媒体简单演示&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;span&gt;程序的一个或几个副本或程序的任何部分，以此形成基于程序的作品。只要你同时满足下面的所有条件，你就可以按前面第一款的要求复制和发布这一经过修改的程序或作品。&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family: 'Times New Roman';"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;a&lt;/span&gt;&lt;/span&gt;&lt;span&gt;）&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;strong&gt;你必须在修改的文件中附有明确的说明：你修改了这一文件及具体的修改日期。&lt;/strong&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family: 'Times New Roman';"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;b&lt;/span&gt;&lt;/span&gt;&lt;span&gt;）&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;strong&gt;你必须使你发布或出版的作品（它包含程序的全部或一部分，或包含由程序的全部或部分衍生的作品）允许第三方作为整体按许可证条款免费使用。&lt;/strong&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family: 'Times New Roman';"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;c&lt;/span&gt;&lt;/span&gt;&lt;span&gt;）&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span&gt;如果修改的程序在运行时以交互方式读取命令，你必须使它在开始进入常规的交互使用方式时打印或显示声明：包括适当的版权声明和没有担保的声明（或者你提供担保的声明）；用户可以按此许可证条款重新发布程序的说明；并告诉用户如何看到这一许可证的副本。（例外的情况：如果原始程序以交互方式工作，它并不打印这样的声明，你的基于程序的作品也就不用打印声明）。&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt; &lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span&gt;这样，您就可以自由使用并传播本源代码，&lt;strong&gt;当然请您原封不动地保留创建者&lt;/strong&gt;&lt;/span&gt;&lt;strong&gt;zhengyun_ustc(&lt;/strong&gt;&lt;strong&gt;郑昀&lt;/strong&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;strong&gt;的作者信息&lt;/strong&gt;&lt;span&gt;。&lt;/span&gt;&lt;/p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/p&gt;&lt;/div&gt;&lt;!-- [DocumentBodyEnd:bfcf5df4-d624-4c74-96f4-c845fda59a7b] --&gt;</description>
      <pubDate>Fri, 20 Nov 2009 11:42:52 GMT</pubDate>
      <author>developerworldwatch@kpi-consulting.net</author>
      <guid>http://developer.sonyericsson.com/community/docs/DOC-3331</guid>
      <dc:date>2009-11-20T11:42:52Z</dc:date>
      <clearspace:dateToText>1 day, 20 hours ago</clearspace:dateToText>
    </item>
    <item>
      <title>Java Verified 手册</title>
      <link>http://developer.sonyericsson.com/community/docs/DOC-3329</link>
      <description>&lt;!-- [DocumentBodyStart:107ca524-0eed-4d70-9369-961393bec462] --&gt;&lt;div class='jive-rendered-content'&gt;&lt;p&gt;&lt;span style="font-size: 14pt;"&gt;    本手册将逐步指导您实现，如何通过 Java Verified 提交门户网站提交应用软件进行认证，并简要介绍提交门户网站能为已提交的软件提供哪些服务。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 14pt;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 14pt;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 14pt;"&gt;    它将带您通过认证流程涉及的所有步骤，包括从获取 Publisher ID 到最终在线提交应用软件进行测试与签名。&lt;/span&gt;&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;span style="font-size: 12pt;"&gt;目录&lt;/span&gt;&lt;/strong&gt;&lt;br/&gt;1. 本手册的用途&lt;br/&gt;2. 什么是 Java Verified 提交门户网站？&lt;br/&gt;3. 什么是 Publisher ID？我该如何使用它？&lt;br/&gt;4. 我该如何注册使用提交门户网站？&lt;br/&gt;5. 在提交应用软件之前我需要做些什么？&lt;br/&gt;6. 我该如何将应用软件提交到门户网站？&lt;br/&gt;7. 我该如何提交应用软件进行研发签名？&lt;br/&gt;8. 我该如何提交应用软件进行测试与签名？&lt;br/&gt;9. 我该如何在门户网站上找到提交的内容？&lt;br/&gt;附录 A: 签署多个 JAD / JAR 文件对的脚本示例&lt;br/&gt;附录 B: 常见问题解答&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;关于如何在索尼爱立信手机上进行 Java 签名和 Java 的权限设置，请阅读下面的文章&amp;gt;&amp;gt;&lt;/p&gt;&lt;p&gt;&lt;a class="jive-link-wiki-small" href="http://developer.sonyericsson.com/community/docs/DOC-3059"&gt;索尼爱立信手机 Java ME 签名指南&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a class="jive-link-wiki-small" href="http://developer.sonyericsson.com/community/docs/DOC-3018"&gt;索尼爱立信手机的 Java ME 的权限设置&lt;/a&gt;&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;更多信息&amp;gt;&amp;gt;&lt;/p&gt;&lt;p&gt;&lt;a class="jive-link-external-small" href="http://developer.sonyericsson.com/site/zhcn/techsupport/javaverified/p_javaverified.jsp"&gt;http://developer.sonyericsson.com/site/zhcn/techsupport/javaverified/p_javaverified.jsp&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a class="jive-link-external-small" href="http://www.javaverified.com"&gt;http://www.javaverified.com&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;!-- [DocumentBodyEnd:107ca524-0eed-4d70-9369-961393bec462] --&gt;</description>
      <pubDate>Tue, 17 Nov 2009 09:30:37 GMT</pubDate>
      <author>developerworldwatch@kpi-consulting.net</author>
      <guid>http://developer.sonyericsson.com/community/docs/DOC-3329</guid>
      <dc:date>2009-11-17T09:30:37Z</dc:date>
      <clearspace:dateToText>4 days, 22 hours ago</clearspace:dateToText>
    </item>
    <item>
      <title>Java线程的同步</title>
      <link>http://developer.sonyericsson.com/community/docs/DOC-3323</link>
      <description>&lt;!-- [DocumentBodyStart:fe440b7f-7a7a-4bb8-84d1-b6976e30c9bd] --&gt;&lt;div class='jive-rendered-content'&gt;&lt;p&gt;在J2ME开发中，线程是一个需要非常重视的问题，下面是一段关于线程的文章。我认为对打好线程基本很有帮助。&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span&gt;zz &lt;/span&gt;&lt;a class="jive-link-external-small" href="http://www.j2medev.com/Article/ShowArticle.asp?ArticleID=5478"&gt;http://www.j2medev.com/Article/ShowArticle.asp?ArticleID=5478&lt;/a&gt;&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;div align="left"&gt;&lt;strong&gt;一、同步问题提出&lt;/strong&gt;&lt;/div&gt;&lt;div align="left"&gt; &lt;/div&gt;&lt;div align="left"&gt;线程的同步是为了防止多个线程访问一个数据对象时，对数据造成的破坏。&lt;/div&gt;&lt;div align="left"&gt;例如：两个线程ThreadA、ThreadB都操作同一个对象Foo对象，并修改Foo对象上的数据。&lt;/div&gt;&lt;div align="left"&gt; &lt;/div&gt;&lt;div align="left"&gt;&lt;div style="border: 1px solid #cccccc; padding: 4px; font-size: 10pt; width: 98%; color: #000000; line-height: 16px; font-family: verdana,宋体; background-color: #eeeeee;"&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; Foo { &lt;br/&gt;    &lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; x = 100; &lt;br/&gt;&lt;br/&gt;    &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; getX() { &lt;br/&gt;        &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; x; &lt;br/&gt;    } &lt;br/&gt;&lt;br/&gt;    &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; fix(&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; y) { &lt;br/&gt;        x = x - y; &lt;br/&gt;        &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; x; &lt;br/&gt;    } &lt;br/&gt;}&lt;/div&gt;&lt;/div&gt;&lt;div align="left"&gt; &lt;/div&gt;&lt;div align="left"&gt;&lt;div style="border: 1px solid #cccccc; padding: 4px; font-size: 10pt; width: 98%; color: #000000; line-height: 16px; font-family: verdana,宋体; background-color: #eeeeee;"&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; MyRunnable &lt;span style="color: #0000ff;"&gt;implements&lt;/span&gt; Runnable { &lt;br/&gt;    &lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; Foo foo = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Foo(); &lt;br/&gt;&lt;br/&gt;    &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; main(String[] args) { &lt;br/&gt;        MyRunnable r = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; MyRunnable(); &lt;br/&gt;        Thread ta = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Thread(r, &lt;span style="color: #800000;"&gt;"Thread-A"&lt;/span&gt;); &lt;br/&gt;        Thread tb = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Thread(r, &lt;span style="color: #800000;"&gt;"Thread-B"&lt;/span&gt;); &lt;br/&gt;        ta.start(); &lt;br/&gt;        tb.start(); &lt;br/&gt;    } &lt;br/&gt;&lt;br/&gt;    &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; run() { &lt;br/&gt;        &lt;span style="color: #0000ff;"&gt;for&lt;/span&gt; (&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; i = 0; i &amp;lt; 3; i++) { &lt;br/&gt;            &lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;.fix(30); &lt;br/&gt;            &lt;span style="color: #0000ff;"&gt;try&lt;/span&gt; { &lt;br/&gt;                Thread.sleep(1); &lt;br/&gt;            } &lt;span style="color: #0000ff;"&gt;catch&lt;/span&gt; (InterruptedException e) { &lt;br/&gt;                e.printStackTrace(); &lt;br/&gt;            } &lt;br/&gt;            System.out.println(Thread.currentThread().getName() + &lt;span style="color: #800000;"&gt;" : 当前foo对象的x值= "&lt;/span&gt; + foo.getX()); &lt;br/&gt;        } &lt;br/&gt;    } &lt;br/&gt;&lt;br/&gt;    &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; fix(&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; y) { &lt;br/&gt;        &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; foo.fix(y); &lt;br/&gt;    } &lt;br/&gt;}&lt;/div&gt;&lt;/div&gt;&lt;div align="left"&gt; &lt;/div&gt;&lt;div align="left"&gt;运行结果：&lt;/div&gt;&lt;div align="left"&gt;&lt;div style="border: 1px solid #cccccc; padding: 4px; font-size: 10pt; width: 98%; color: #000000; line-height: 16px; font-family: verdana,宋体; background-color: #eeeeee;"&gt;Thread-A : 当前foo对象的x值= 40 &lt;br/&gt;Thread-B : 当前foo对象的x值= 40 &lt;br/&gt;Thread-B : 当前foo对象的x值= -20 &lt;br/&gt;Thread-A : 当前foo对象的x值= -50 &lt;br/&gt;Thread-A : 当前foo对象的x值= -80 &lt;br/&gt;Thread-B : 当前foo对象的x值= -80 &lt;br/&gt;&lt;br/&gt;Process finished with exit code 0&lt;/div&gt;&lt;/div&gt;&lt;div align="left"&gt; &lt;/div&gt;&lt;div align="left"&gt;从结果发现，这样的输出值明显是不合理的。原因是两个线程不加控制的访问Foo对象并修改其数据所致。&lt;/div&gt;&lt;div align="left"&gt; &lt;/div&gt;&lt;div align="left"&gt;如果要保持结果的合理性，只需要达到一个目的，就是将对Foo的访问加以限制，每次只能有一个线程在访问。这样就能保证Foo对象中数据的合理性了。&lt;/div&gt;&lt;div align="left"&gt; &lt;/div&gt;&lt;div align="left"&gt;在具体的Java代码中需要完成一下两个操作：&lt;/div&gt;&lt;div align="left"&gt;把竞争访问的资源类Foo变量x标识为private；&lt;/div&gt;&lt;div align="left"&gt;同步哪些修改变量的代码，使用synchronized关键字同步方法或代码。&lt;/div&gt;&lt;div align="left"&gt; &lt;/div&gt;&lt;div align="left"&gt;&lt;strong&gt;二、同步和锁定&lt;/strong&gt;&lt;/div&gt;&lt;div align="left"&gt; &lt;/div&gt;&lt;div align="left"&gt;1、锁的原理&lt;/div&gt;&lt;div align="left"&gt; &lt;/div&gt;&lt;div align="left"&gt;Java中每个对象都有一个内置锁&lt;/div&gt;&lt;div align="left"&gt; &lt;/div&gt;&lt;div align="left"&gt;当程序运行到非静态的synchronized同步方法上时，自动获得与正在执行代码类的当前实例（this实例）有关的锁。获得一个对象的锁也称为获取锁、锁定对象、在对象上锁定或在对象上同步。&lt;/div&gt;&lt;div align="left"&gt; &lt;/div&gt;&lt;div align="left"&gt;当程序运行到synchronized同步方法或代码块时才该对象锁才起作用。&lt;/div&gt;&lt;div align="left"&gt; &lt;/div&gt;&lt;div align="left"&gt;一个对象只有一个锁。所以，如果一个线程获得该锁，就没有其他线程可以获得锁，直到第一个线程释放（或返回）锁。这也意味着任何其他线程都不能进入该对象上的synchronized方法或代码块，直到该锁被释放。&lt;/div&gt;&lt;div align="left"&gt; &lt;/div&gt;&lt;div align="left"&gt;释放锁是指持锁线程退出了synchronized同步方法或代码块。&lt;/div&gt;&lt;div align="left"&gt; &lt;/div&gt;&lt;div align="left"&gt;关于锁和同步，有一下几个要点：&lt;/div&gt;&lt;div align="left"&gt;1）、只能同步方法，而不能同步变量和类；&lt;/div&gt;&lt;div align="left"&gt;2）、每个对象只有一个锁；当提到同步时，应该清楚在什么上同步？也就是说，在哪个对象上同步？&lt;/div&gt;&lt;div align="left"&gt;3）、不必同步类中所有的方法，类可以同时拥有同步和非同步方法。&lt;/div&gt;&lt;div align="left"&gt;4）、如果两个线程要执行一个类中的synchronized方法，并且两个线程使用相同的实例来调用方法，那么一 次只能有一个线程能够执行方法，另一个需要等待，直到锁被释放。也就是说：如果一个线程在对象上获得一个锁，就没有任何其他线程可以进入（该对象的）类中 的任何一个同步方法。&lt;/div&gt;&lt;div align="left"&gt;5）、如果线程拥有同步和非同步方法，则非同步方法可以被多个线程自由访问而不受锁的限制。&lt;/div&gt;&lt;p align="left"&gt;6）、线程睡眠时，它所持的任何锁都不会释放。&lt;/p&gt;&lt;div align="left"&gt;7）、线程可以获得多个锁。比如，在一个对象的同步方法里面调用另外一个对象的同步方法，则获取了两个对象的同步锁。&lt;/div&gt;&lt;div align="left"&gt;8）、同步损害并发性，应该尽可能缩小同步范围。同步不但可以同步整个方法，还可以同步方法中一部分代码块。&lt;/div&gt;&lt;div align="left"&gt;9）、在使用同步代码块时候，应该指定在哪个对象上同步，也就是说要获取哪个对象的锁。例如：&lt;/div&gt;&lt;div align="left"&gt;    public int fix(int y) {&lt;br/&gt;        synchronized (this) {&lt;br/&gt;            x = x - y;&lt;br/&gt;        }&lt;br/&gt;        return x;&lt;br/&gt;    }&lt;/div&gt;&lt;div align="left"&gt; &lt;/div&gt;&lt;div align="left"&gt;当然，同步方法也可以改写为非同步方法，但功能完全一样的，例如：&lt;/div&gt;&lt;div align="left"&gt;    public synchronized int getX() {&lt;br/&gt;        return x++;&lt;br/&gt;    }&lt;/div&gt;&lt;div align="left"&gt;与&lt;/div&gt;&lt;div align="left"&gt;    public int getX() {&lt;br/&gt;        synchronized (this) {&lt;br/&gt;            return x;&lt;br/&gt;        }&lt;br/&gt;    }&lt;/div&gt;&lt;div align="left"&gt;效果是完全一样的。&lt;/div&gt;&lt;div align="left"&gt; &lt;/div&gt;&lt;div align="left"&gt;&lt;strong&gt;三、静态方法同步&lt;/strong&gt;&lt;/div&gt;&lt;div align="left"&gt; &lt;/div&gt;&lt;div align="left"&gt;要同步静态方法，需要一个用于整个类对象的锁，这个对象是就是这个类（XXX.class)。&lt;/div&gt;&lt;div align="left"&gt;例如：&lt;/div&gt;&lt;div align="left"&gt;public static synchronized int setName(String name){&lt;/div&gt;&lt;div align="left"&gt;      Xxx.name = name;&lt;/div&gt;&lt;div align="left"&gt;}&lt;/div&gt;&lt;div align="left"&gt;等价于&lt;br/&gt;public static int setName(String name){&lt;br/&gt;      synchronized(Xxx.class){&lt;br/&gt;            Xxx.name = name;&lt;br/&gt;      }&lt;br/&gt;}&lt;/div&gt;&lt;div align="left"&gt;&lt;br/&gt; &lt;/div&gt;&lt;div align="left"&gt;&lt;strong&gt;四、如果线程不能不能获得锁会怎么样&lt;/strong&gt;&lt;/div&gt;&lt;div align="left"&gt; &lt;/div&gt;&lt;div align="left"&gt;如果线程试图进入同步方法，而其锁已经被占用，则线程在该对象上被阻塞。实质上，线程进入该对象的的一种池中，必须在哪里等待，直到其锁被释放，该线程再次变为可运行或运行为止。&lt;/div&gt;&lt;div align="left"&gt; &lt;/div&gt;&lt;div align="left"&gt;当考虑阻塞时，一定要注意哪个对象正被用于锁定：&lt;/div&gt;&lt;div align="left"&gt;1、调用同一个对象中非静态同步方法的线程将彼此阻塞。如果是不同对象，则每个线程有自己的对象的锁，线程间彼此互不干预。&lt;/div&gt;&lt;div align="left"&gt; &lt;/div&gt;&lt;div align="left"&gt;2、调用同一个类中的静态同步方法的线程将彼此阻塞，它们都是锁定在相同的Class对象上。&lt;/div&gt;&lt;div align="left"&gt; &lt;/div&gt;&lt;div align="left"&gt;3、静态同步方法和非静态同步方法将永远不会彼此阻塞，因为静态方法锁定在Class对象上，非静态方法锁定在该类的对象上。&lt;/div&gt;&lt;div align="left"&gt; &lt;/div&gt;&lt;div align="left"&gt;4、对于同步代码块，要看清楚什么对象已经用于锁定（synchronized后面括号的内容）。在同一个对象上进行同步的线程将彼此阻塞，在不同对象上锁定的线程将永远不会彼此阻塞。&lt;/div&gt;&lt;div align="left"&gt; &lt;/div&gt;&lt;div align="left"&gt;&lt;strong&gt;五、何时需要同步&lt;/strong&gt;&lt;/div&gt;&lt;div align="left"&gt; &lt;/div&gt;&lt;div align="left"&gt;在多个线程同时访问互斥（可交换）数据时，应该同步以保护数据，确保两个线程不会同时修改更改它。&lt;/div&gt;&lt;div align="left"&gt; &lt;/div&gt;&lt;div align="left"&gt;对于非静态字段中可更改的数据，通常使用非静态方法访问。&lt;/div&gt;&lt;div align="left"&gt;对于静态字段中可更改的数据，通常使用静态方法访问。&lt;/div&gt;&lt;div align="left"&gt; &lt;/div&gt;&lt;div align="left"&gt;如果需要在非静态方法中使用静态字段，或者在静态字段中调用非静态方法，问题将变得非常复杂。已经超出SJCP考试范围了。&lt;/div&gt;&lt;div align="left"&gt; &lt;/div&gt;&lt;div align="left"&gt;&lt;strong&gt;六、线程安全类&lt;/strong&gt;&lt;/div&gt;&lt;div align="left"&gt; &lt;/div&gt;&lt;div align="left"&gt;当一个类已经很好的同步以保护它的数据时，这个类就称为“线程安全的”。&lt;/div&gt;&lt;div align="left"&gt; &lt;/div&gt;&lt;div align="left"&gt;即使是线程安全类，也应该特别小心，因为操作的线程是间仍然不一定安全。&lt;/div&gt;&lt;div align="left"&gt; &lt;/div&gt;&lt;div align="left"&gt;举个形象的例子，比如一个集合是线程安全的，有两个线程在操作同一个集合对象，当第一个线程查询集合非空后，删除集 合中所有元素的时候。第二个线程也来执行与第一个线程相同的操作，也许在第一个线程查询后，第二个线程也查询出集合非空，但是当第一个执行清除后，第二个 再执行删除显然是不对的，因为此时集合已经为空了。&lt;/div&gt;&lt;div align="left"&gt;看个代码：&lt;/div&gt;&lt;div align="left"&gt; &lt;/div&gt;&lt;div align="left"&gt;&lt;div style="border: 1px solid #cccccc; padding: 4px; font-size: 10pt; width: 98%; color: #000000; line-height: 16px; font-family: verdana,宋体; background-color: #eeeeee;"&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; NameList { &lt;br/&gt;    &lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; List nameList = Collections.synchronizedList(&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; LinkedList()); &lt;br/&gt;&lt;br/&gt;    &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; add(String name) { &lt;br/&gt;        nameList.add(name); &lt;br/&gt;    } &lt;br/&gt;&lt;br/&gt;    &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; String removeFirst() { &lt;br/&gt;        &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (nameList.size() &amp;gt; 0) { &lt;br/&gt;            &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; (String) nameList.remove(0); &lt;br/&gt;        } &lt;span style="color: #0000ff;"&gt;else&lt;/span&gt; { &lt;br/&gt;            &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;; &lt;br/&gt;        } &lt;br/&gt;    } &lt;br/&gt;}&lt;/div&gt;&lt;/div&gt;&lt;div align="left"&gt; &lt;/div&gt;&lt;div align="left"&gt;&lt;div style="border: 1px solid #cccccc; padding: 4px; font-size: 10pt; width: 98%; color: #000000; line-height: 16px; font-family: verdana,宋体; background-color: #eeeeee;"&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; Test { &lt;br/&gt;    &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; main(String[] args) { &lt;br/&gt;        &lt;span style="color: #0000ff;"&gt;final&lt;/span&gt; NameList nl = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; NameList(); &lt;br/&gt;        nl.add(&lt;span style="color: #800000;"&gt;"aaa"&lt;/span&gt;); &lt;br/&gt;        &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; NameDropper &lt;span style="color: #0000ff;"&gt;extends&lt;/span&gt; Thread{ &lt;br/&gt;            &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; run(){ &lt;br/&gt;                String name = nl.removeFirst(); &lt;br/&gt;                System.out.println(name); &lt;br/&gt;            } &lt;br/&gt;        } &lt;br/&gt;&lt;br/&gt;        Thread t1 = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; NameDropper(); &lt;br/&gt;        Thread t2 = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; NameDropper(); &lt;br/&gt;        t1.start(); &lt;br/&gt;        t2.start(); &lt;br/&gt;    } &lt;br/&gt;}&lt;/div&gt;&lt;/div&gt;&lt;div align="left"&gt; &lt;/div&gt;&lt;div align="left"&gt;虽然集合对象&lt;/div&gt;&lt;div align="left"&gt;    private List nameList = Collections.synchronizedList(new LinkedList());&lt;br/&gt;是同步的，但是程序还不是线程安全的。&lt;/div&gt;&lt;div align="left"&gt;出现这种事件的原因是，上例中一个线程操作列表过程中无法阻止另外一个线程对列表的其他操作。&lt;/div&gt;&lt;div align="left"&gt; &lt;/div&gt;&lt;div align="left"&gt;解决上面问题的办法是，在操作集合对象的NameList上面做一个同步。改写后的代码如下：&lt;/div&gt;&lt;div align="left"&gt;&lt;div style="border: 1px solid #cccccc; padding: 4px; font-size: 10pt; width: 98%; color: #000000; line-height: 16px; font-family: verdana,宋体; background-color: #eeeeee;"&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; NameList { &lt;br/&gt;    &lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; List nameList = Collections.synchronizedList(&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; LinkedList()); &lt;br/&gt;&lt;br/&gt;    &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;synchronized&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; add(String name) { &lt;br/&gt;        nameList.add(name); &lt;br/&gt;    } &lt;br/&gt;&lt;br/&gt;    &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;synchronized&lt;/span&gt; String removeFirst() { &lt;br/&gt;        &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (nameList.size() &amp;gt; 0) { &lt;br/&gt;            &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; (String) nameList.remove(0); &lt;br/&gt;        } &lt;span style="color: #0000ff;"&gt;else&lt;/span&gt; { &lt;br/&gt;            &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;; &lt;br/&gt;        } &lt;br/&gt;    } &lt;br/&gt;}&lt;/div&gt;&lt;/div&gt;&lt;div align="left"&gt; &lt;/div&gt;&lt;div align="left"&gt;这样，当一个线程访问其中一个同步方法时，其他线程只有等待。&lt;/div&gt;&lt;div align="left"&gt; &lt;/div&gt;&lt;div align="left"&gt;&lt;strong&gt;七、线程死锁&lt;/strong&gt;&lt;/div&gt;&lt;div align="left"&gt; &lt;/div&gt;&lt;div align="left"&gt;死锁对Java程序来说，是很复杂的，也很难发现问题。当两个线程被阻塞，每个线程在等待另一个线程时就发生死锁。&lt;/div&gt;&lt;div align="left"&gt; &lt;/div&gt;&lt;div align="left"&gt;还是看一个比较直观的死锁例子：&lt;/div&gt;&lt;div align="left"&gt; &lt;/div&gt;&lt;div align="left"&gt;&lt;div style="border: 1px solid #cccccc; padding: 4px; font-size: 10pt; width: 98%; color: #000000; line-height: 16px; font-family: verdana,宋体; background-color: #eeeeee;"&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; DeadlockRisk { &lt;br/&gt;    &lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; Resource { &lt;br/&gt;        &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; value; &lt;br/&gt;    } &lt;br/&gt;&lt;br/&gt;    &lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; Resource resourceA = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Resource(); &lt;br/&gt;    &lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; Resource resourceB = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Resource(); &lt;br/&gt;&lt;br/&gt;    &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; read() { &lt;br/&gt;        &lt;span style="color: #0000ff;"&gt;synchronized&lt;/span&gt; (resourceA) { &lt;br/&gt;            &lt;span style="color: #0000ff;"&gt;synchronized&lt;/span&gt; (resourceB) { &lt;br/&gt;                &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; resourceB.value + resourceA.value; &lt;br/&gt;            } &lt;br/&gt;        } &lt;br/&gt;    } &lt;br/&gt;&lt;br/&gt;    &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; write(&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; a, &lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; b) { &lt;br/&gt;        &lt;span style="color: #0000ff;"&gt;synchronized&lt;/span&gt; (resourceB) { &lt;br/&gt;            &lt;span style="color: #0000ff;"&gt;synchronized&lt;/span&gt; (resourceA) { &lt;br/&gt;                resourceA.value = a; &lt;br/&gt;                resourceB.value = b; &lt;br/&gt;            } &lt;br/&gt;        } &lt;br/&gt;    } &lt;br/&gt;}&lt;/div&gt;&lt;/div&gt;&lt;div align="left"&gt; &lt;/div&gt;&lt;div align="left"&gt;假设read()方法由一个线程启动，write()方法由另外一个线程启动。读线程将拥有resourceA锁，写线程将拥有resourceB锁，两者都坚持等待的话就出现死锁。&lt;/div&gt;&lt;div align="left"&gt; &lt;/div&gt;&lt;div align="left"&gt;实际上，上面这个例子发生死锁的概率很小。因为在代码内的某个点，CPU必须从读线程切换到写线程，所以，死锁基本上不能发生。&lt;/div&gt;&lt;div align="left"&gt; &lt;/div&gt;&lt;div align="left"&gt;但是，无论代码中发生死锁的概率有多小，一旦发生死锁，程序就死掉。有一些设计方法能帮助避免死锁，包括始终按照预定义的顺序获取锁这一策略。已经超出SCJP的考试范围。&lt;/div&gt;&lt;div align="left"&gt; &lt;/div&gt;&lt;div align="left"&gt;&lt;strong&gt;八、线程同步小结&lt;/strong&gt;&lt;/div&gt;&lt;div align="left"&gt; &lt;/div&gt;&lt;div align="left"&gt;1、线程同步的目的是为了保护多个线程反问一个资源时对资源的破坏。&lt;/div&gt;&lt;div align="left"&gt;2、线程同步方法是通过锁来实现，每个对象都有切仅有一个锁，这个锁与一个特定的对象关联，线程一旦获取了对象锁，其他访问该对象的线程就无法再访问该对象的其他非同步方法。&lt;/div&gt;&lt;div align="left"&gt;3、对于静态同步方法，锁是针对这个类的，锁对象是该类的Class对象。静态和非静态方法的锁互不干预。一个线程获得锁，当在一个同步方法中访问另外对象上的同步方法时，会获取这两个对象锁。&lt;/div&gt;&lt;div align="left"&gt;4、对于同步，要时刻清醒在哪个对象上同步，这是关键。&lt;/div&gt;&lt;div align="left"&gt;5、编写线程安全的类，需要时刻注意对多个线程竞争访问资源的逻辑和安全做出正确的判断，对“原子”操作做出分析，并保证原子操作期间别的线程无法访问竞争资源。&lt;/div&gt;&lt;div align="left"&gt;6、当多个线程等待一个对象锁时，没有获取到锁的线程将发生阻塞。&lt;/div&gt;&lt;div align="left"&gt;7、死锁是线程间相互等待锁锁造成的，在实际中发生的概率非常的小。真让你写个死锁程序，不一定好使，呵呵。但是，一旦程序发生死锁，程序将死掉。&lt;/div&gt;&lt;/div&gt;&lt;!-- [DocumentBodyEnd:fe440b7f-7a7a-4bb8-84d1-b6976e30c9bd] --&gt;</description>
      <pubDate>Wed, 11 Nov 2009 01:38:50 GMT</pubDate>
      <author>developerworldwatch@kpi-consulting.net</author>
      <guid>http://developer.sonyericsson.com/community/docs/DOC-3323</guid>
      <dc:date>2009-11-11T01:38:50Z</dc:date>
      <clearspace:dateToText>1 week, 4 days ago</clearspace:dateToText>
    </item>
    <item>
      <title>JAVA/J2ME中文编码问题完全解决方案zz</title>
      <link>http://developer.sonyericsson.com/community/docs/DOC-3299</link>
      <description>&lt;!-- [DocumentBodyStart:6ff34846-6270-4560-bb30-9f83d423e705] --&gt;&lt;div class='jive-rendered-content'&gt;&lt;p&gt;&lt;span&gt;zz &lt;/span&gt;&lt;a class="jive-link-external-small" href="http://mtiger2k.blog.51cto.com/90475/82801"&gt;http://mtiger2k.blog.51cto.com/90475/82801&lt;/a&gt;&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;div&gt;最近开发了一个在手机上打谱的围棋软件，因为要读中文棋谱，所以需要支持中文编码。在诺基亚，索爱，多普达等机器上运行良好，可以打开中文棋谱，并显示正常的中文棋评。但在三星，MOTO，联想等机型上无法打开文件。无论用什么中文编码，包括GB2312，GB18030，GBK，都不行。我的做法是：&lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt;try {&lt;br/&gt;     reader = new InputStreamReader(fis, "GB2312");&lt;br/&gt;} catch (UnsupportedEncodingException ex) {&lt;br/&gt;     showMsg("Unsupported Encoding Exception.");&lt;br/&gt;     return;&lt;br/&gt;}&lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt;后来决定自已处理GB2312字节。但是直接调用HGB2312.gb2utf8，诺基亚上没问题，在三星手机上还是行不通，显示乱码。&lt;/div&gt;&lt;div&gt;str = hgb2312.gb2utf8(str.getBytes());&lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt;研究了诺基亚SDK里的InputStreamReader实现后，发现Reader类无非就是按指定的编码，把字节一个一个提出来分析，按照 编码格式拼装成一个个char，这个处理方式跟HGB2312里的字节处理原理是一样的。于是决定自己实现一个InputStreamReader。实际 上只要继承java.io.Reader类，实现两个方法就行了：&lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt;import java.io.IOException;&lt;br/&gt;import java.io.InputStream;&lt;br/&gt;import java.io.Reader;&lt;/div&gt;&lt;div&gt;public class InputStreamReader extends Reader {&lt;br/&gt; private byte[] map = new byte[15228];&lt;br/&gt; InputStream In;&lt;br/&gt; &lt;br/&gt; public InputStreamReader(InputStream inputstream) throws Exception {&lt;br/&gt;  In = inputstream;&lt;br/&gt;  InputStream is = getClass().getResourceAsStream("/gb2u.dat");&lt;br/&gt;  is.read(map);&lt;br/&gt;  is.close();&lt;br/&gt; }&lt;br/&gt; &lt;br/&gt; public void close() throws IOException {&lt;br/&gt;  In.close();&lt;br/&gt; }&lt;/div&gt;&lt;div&gt; public int read(char[] ac, int i, int j) throws IOException {&lt;br/&gt;  byte bt;&lt;br/&gt;  byte[] bytes;&lt;br/&gt;  int ret;&lt;br/&gt;  int k = 0;&lt;br/&gt;  while (k &amp;lt; j) {&lt;br/&gt;   int c, h, l, ind;&lt;br/&gt;   bytes = new byte[1];&lt;br/&gt;   ret = In.read(bytes);&lt;br/&gt;   if (ret==-1) break;&lt;br/&gt;   &lt;br/&gt;   bt = bytes[0];&lt;br/&gt;   if (bt &amp;gt;= 0) {&lt;br/&gt;             ac[i+k] = ((char) bt);&lt;br/&gt;         } else {&lt;br/&gt;          bytes = new byte[1];&lt;br/&gt;          ret = In.read(bytes);&lt;br/&gt;          if (ret==-1) break;&lt;br/&gt;          &lt;br/&gt;          h = 256 + bt;&lt;br/&gt;             l = 256 + bytes[0];&lt;br/&gt;             h = h - 0xA0 - 1;&lt;br/&gt;             l = l - 0xA0 - 1;&lt;br/&gt;             if (h &amp;lt; 9) {&lt;br/&gt;                 ind = (h * 94 + l) &amp;lt;&amp;lt; 1;&lt;br/&gt;                 c = (byte2Int(map[ind]) &amp;lt;&amp;lt; 8 | byte2Int(map[ind + 1]));&lt;br/&gt;                 ac[i+k] = ((char) c);&lt;br/&gt;             } else if (h &amp;gt;= 9 &amp;amp;&amp;amp; h &amp;lt;= 14) {&lt;br/&gt;              ac[i+k] = ((char) 0);&lt;br/&gt;             } else if (h &amp;gt; 14) {&lt;br/&gt;                 h -= 6;&lt;br/&gt;                 ind = (h * 94 + l) &amp;lt;&amp;lt; 1;&lt;br/&gt;                 c = (byte2Int(map[ind]) &amp;lt;&amp;lt; 8 | byte2Int(map[ind + 1]));&lt;br/&gt;                 ac[i+k] = ((char) c);&lt;br/&gt; &lt;br/&gt;             } else {&lt;br/&gt;              ac[i+k] = ((char) 0);&lt;br/&gt;             }&lt;br/&gt;         }&lt;br/&gt;   k++;&lt;br/&gt;  }&lt;br/&gt;  return k != 0 ? k : -1;&lt;br/&gt; }&lt;/div&gt;&lt;div&gt; private int byte2Int(byte b) {&lt;br/&gt;  if (b &amp;lt; 0) {&lt;br/&gt;   return 256 + b;&lt;br/&gt;  } else {&lt;br/&gt;   return b;&lt;br/&gt;  }&lt;br/&gt; }&lt;/div&gt;&lt;div&gt;}&lt;br/&gt;&lt;/div&gt;&lt;div&gt;其中主要是&lt;span style="text-decoration: underline;"&gt;public int read(char[] ac, int i, int j)&lt;/span&gt; 这个方法。&lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt;这样直接用这个InputStreamReader包装InputStream类，其他代码根本不用改变。&lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt;测试结果：三星手机上可以打开中文棋谱了。其他手机型号如MOTO，联想，有待进一步确认。但我相信应该同样没问题。&lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt; 数据文件&lt;strong&gt;gb2u.data&lt;/strong&gt;请在&lt;a class="jive-link-external-small" href="http://download.csdn.net/source/263609"&gt;http://download.csdn.net/source/263609&lt;/a&gt;获取&lt;/div&gt;&lt;/div&gt;&lt;!-- [DocumentBodyEnd:6ff34846-6270-4560-bb30-9f83d423e705] --&gt;</description>
      <category domain="http://developer.sonyericsson.com/community/tags?containerType=?14&amp;container=2023">j2me</category>
      <category domain="http://developer.sonyericsson.com/community/tags?containerType=?14&amp;container=2023">编码</category>
      <pubDate>Thu, 29 Oct 2009 02:57:12 GMT</pubDate>
      <author>developerworldwatch@kpi-consulting.net</author>
      <guid>http://developer.sonyericsson.com/community/docs/DOC-3299</guid>
      <dc:date>2009-10-29T02:57:12Z</dc:date>
      <clearspace:dateToText>3 weeks, 3 days ago</clearspace:dateToText>
    </item>
    <item>
      <title>给游戏添加音乐zz</title>
      <link>http://developer.sonyericsson.com/community/docs/DOC-3298</link>
      <description>&lt;!-- [DocumentBodyStart:1f7ec6b2-bdee-42e1-8194-e0b430d45b3a] --&gt;&lt;div class='jive-rendered-content'&gt;&lt;p&gt;zz 转自www.j2mefans.com&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;J2me通过Mobile Media API 支持手机音频，这是在特定类型的设备上支持不同程度的多媒体的类和接口的一个集合。更具体地说，Mobile Media API划分为两个不同的API集合：&lt;br/&gt;     一个是Mobile Media API,主要针对高级声音和多媒体能力；另一个是MIDP2.0 Media API，主要针对支持唯一音频的受限制的设备。很明显，我们主要是讨论后一部分。&lt;br/&gt;     MIDP2.0 Media API 围绕着2个主要的部分进行设计：管理器，播放器，和控制器。MIDP2.0 Media API都位于javax.microedition.media 和javax.microedition.media.control包中。其中管理器Manager位于media包中，它通过为各种媒体类型创建播放 器，从而使我们能够查询一个手机的媒体能力。播放器Player接口位于同一个包中，提供了一组通用的方法来控制音频的回放。控制器Control接口位 于media.control包中，用来进行特定类型的媒体控制，例如，VolumeControl用来控制音量，ToneControl用来控制乐音。&lt;br/&gt; &lt;br/&gt;如果要想知道我们的手机对语音支持的能力，我们可以使用下面的代码（只提供Canvas类）：&lt;br/&gt; import javax.microedition.lcdui.*;&lt;br/&gt; import javax.microedition.media.*;&lt;br/&gt; import javax.microedition.media.control.*;&lt;br/&gt; &lt;br/&gt;public class SCCanvas extends Canvas {&lt;br/&gt;   private Display  display;&lt;br/&gt;   &lt;br/&gt;   public SCCanvas(Display d) {&lt;br/&gt;     super();&lt;br/&gt;     display = d;&lt;br/&gt;   }&lt;br/&gt; &lt;br/&gt;  void start() {&lt;br/&gt;     display.setCurrent(this);&lt;br/&gt;     repaint();&lt;br/&gt;   }&lt;br/&gt; &lt;br/&gt;  public void paint(Graphics g) {&lt;br/&gt;     &lt;span style="color: green;"&gt;// 清除画布&lt;/span&gt;&lt;br/&gt;     g.setColor(0, 0, 0);        &lt;br/&gt;     g.fillRect(0, 0, getWidth(), getHeight());&lt;br/&gt;     g.setColor(255, 255, 255);  &lt;br/&gt; &lt;br/&gt;    &lt;span style="color: green;"&gt;// 得到手机支持的声音的类型&lt;/span&gt;&lt;br/&gt;     String[] contentTypes = Manager.getSupportedContentTypes(null);&lt;br/&gt; &lt;br/&gt;    &lt;span style="color: green;"&gt;// 显示所支持的声音的类型&lt;/span&gt;&lt;br/&gt;     int y = 0;&lt;br/&gt;     for (int i = 0; i &amp;lt; contentTypes.length; i++) {&lt;br/&gt;       &lt;span style="color: green;"&gt;// 显示类型&lt;/span&gt;&lt;br/&gt;       g.drawString(contentTypes[i], 0, y, Graphics.TOP | Graphics.LEFT);&lt;br/&gt;       y += Font.getDefaultFont().getHeight();&lt;br/&gt; &lt;br/&gt;      &lt;span style="color: green;"&gt;// 如果支持乐音生成器，播放乐音&lt;/span&gt;&lt;br/&gt;       if (contentTypes[i] == "audio/x-tone-seq") {&lt;br/&gt;         try {&lt;br/&gt;           &lt;br/&gt;           Manager.playTone(ToneControl.C4, 2000, 100);&lt;br/&gt;         }&lt;br/&gt;         catch(MediaException me) {&lt;br/&gt;         }&lt;br/&gt;       }&lt;br/&gt;     }&lt;br/&gt;   }&lt;br/&gt; }&lt;br/&gt; &lt;br/&gt;下面是MIDP2.0手机所支持的常见的音频MIME类型：&lt;br/&gt; audio/x-tone-seq  表示乐音和乐音序列；audio/x-wav表示声波声音；audio/midi表示midi音乐；audio/mpeg表示MP3音频。&lt;br/&gt; &lt;br/&gt;使用MIDP2.0 Media API的步骤：&lt;br/&gt; （1）    使用Manager类获得一个针对特定媒体类型的播放器。&lt;br/&gt; （2）    使用Player接口在特定的播放器上播放媒体。&lt;br/&gt; （3）    如果需要的话，使用Control接口来改变媒体的回放。&lt;br/&gt; &lt;br/&gt;下面是一个播放乐音的例子：&lt;br/&gt; byte tempo=50; &lt;span style="color: green;"&gt;// 设定声音播放速度&lt;/span&gt;&lt;br/&gt;       byte d=8; &lt;span style="color: green;"&gt;// 音调值&lt;/span&gt;&lt;br/&gt; &lt;br/&gt;      byte C4=ToneControl.C4; &lt;span style="color: green;"&gt;//基准音调&lt;/span&gt;&lt;br/&gt;       byte D4=(byte)(C4+2);&lt;span style="color: green;"&gt; //音调值&lt;/span&gt;&lt;br/&gt;       byte E4=(byte)(C4+4);&lt;br/&gt;       byte G4=(byte)(C4+7); &lt;br/&gt;       byte rest=ToneControl.SILENCE; &lt;span style="color: green;"&gt;//无声&lt;/span&gt;&lt;br/&gt; &lt;br/&gt;      byte[] mySequence=&lt;br/&gt;       {&lt;br/&gt;         ToneControl.VERSION,1,             &lt;span style="color: green;"&gt;//设置版本号，当前必须设为1&lt;/span&gt;&lt;br/&gt;         ToneControl.TEMPO,tempo,            &lt;span style="color: green;"&gt;//设置声音播放速度，值越大，播放越快&lt;/span&gt;&lt;br/&gt;         ToneControl.SET_VOLUME,100,        &lt;span style="color: green;"&gt;//设置音量，值越大，音量越大&lt;/span&gt;&lt;br/&gt;         ToneControl.BLOCK_START,0,        &lt;span style="color: green;"&gt;//预定义播放块，当前块号为0&lt;/span&gt;&lt;br/&gt;         E4,d,D4,d,C4,d,E4,d,&lt;br/&gt;         E4,d,E4,d,E4,d,rest,d,                &lt;span style="color: green;"&gt;//块的内容&lt;/span&gt;&lt;br/&gt;         ToneControl.BLOCK_END,0,         &lt;span style="color: green;"&gt;//块定义结束符&lt;/span&gt;&lt;br/&gt;         ToneControl.PLAY_BLOCK,0,         &lt;span style="color: green;"&gt;//播放当前块号为0的块，块号必须提前定义&lt;/span&gt;&lt;br/&gt;         D4,d,D4,d,D4,d,rest,d,                &lt;span style="color: green;"&gt;//不使用块号方式播放的内容，必须位于块定义后面&lt;/span&gt;&lt;br/&gt;       };&lt;br/&gt; &lt;br/&gt;      &lt;span style="color: green;"&gt;//创建播放器&lt;/span&gt;&lt;br/&gt;       Player p=Manager.createPlayer(Manager.TONE_DEVICE_LOCATOR);&lt;br/&gt;       &lt;span style="color: green;"&gt;//准备播放信息&lt;/span&gt;&lt;br/&gt;       p.realize();&lt;br/&gt;       &lt;span style="color: green;"&gt;//获取音调控制&lt;/span&gt;&lt;br/&gt;       ToneControl c=(ToneControl)p.getControl("ToneControl");&lt;br/&gt;       &lt;span style="color: green;"&gt;//设置音调序列&lt;/span&gt;&lt;br/&gt; c.setSequence(mySequence);&lt;br/&gt; &lt;span style="color: green;"&gt;//设置播放资源，获取设备&lt;/span&gt;&lt;br/&gt;       p.prefetch();&lt;br/&gt;       &lt;span style="color: green;"&gt;//开始播放&lt;/span&gt;&lt;br/&gt;       p.start();&lt;br/&gt;     }&lt;br/&gt;     catch(Exception e)&lt;br/&gt;     {&lt;br/&gt;     }&lt;br/&gt; &lt;br/&gt;&lt;br/&gt; 下面是一个播放音乐文件的例子：&lt;br/&gt; try&lt;br/&gt; {&lt;br/&gt;       &lt;span style="color: green;"&gt;//从资源中获取声音&lt;/span&gt;&lt;br/&gt;       InputStream is=getClass().getResourceAsStream("/"+"Testsound.mid");&lt;br/&gt;       &lt;span style="color: green;"&gt;//创建播放MIDI声音的播放器&lt;/span&gt;&lt;br/&gt;       Player player=Manager.createPlayer(is,"audio/midi");&lt;br/&gt;       &lt;span style="color: green;"&gt;//获取播放信息&lt;/span&gt;&lt;br/&gt;       player.realize();&lt;br/&gt;       &lt;span style="color: green;"&gt;//获取设备&lt;/span&gt;&lt;br/&gt;       player.prefetch();&lt;br/&gt;       &lt;span style="color: green;"&gt;//开始播放声音&lt;/span&gt;&lt;br/&gt;       player.start();&lt;br/&gt; &lt;br/&gt;      VolumeControl control=(VolumeControl)player.getControl("VolumeControl"); &lt;span style="color: green;"&gt;//获得控制接口，此接口的获得必须在获取播放信息或者获取播放设备后面，如果在它们前面，将会出现无法播放声音的情况&lt;/span&gt;&lt;br/&gt;       if(control!=null) &lt;span style="color: green;"&gt;//必须检查是否为null，因为有些声音格式可能不支持音量控制&lt;/span&gt;&lt;br/&gt;       {&lt;br/&gt;         control.setLevel(5); &lt;span style="color: green;"&gt;//设置音量级别为50&lt;/span&gt;&lt;br/&gt; &lt;span style="color: green;"&gt;//control.setMute(true);&lt;/span&gt;                            &lt;span style="color: green;"&gt;//设置静音&lt;/span&gt;&lt;br/&gt;       }&lt;br/&gt; &lt;br/&gt;只是一个简单的例子，更详细的请参考专业的书籍。&lt;/p&gt;&lt;/div&gt;&lt;!-- [DocumentBodyEnd:1f7ec6b2-bdee-42e1-8194-e0b430d45b3a] --&gt;</description>
      <category domain="http://developer.sonyericsson.com/community/tags?containerType=?14&amp;container=2023">j2me</category>
      <category domain="http://developer.sonyericsson.com/community/tags?containerType=?14&amp;container=2023">音频</category>
      <pubDate>Thu, 29 Oct 2009 02:54:46 GMT</pubDate>
      <author>developerworldwatch@kpi-consulting.net</author>
      <guid>http://developer.sonyericsson.com/community/docs/DOC-3298</guid>
      <dc:date>2009-10-29T02:54:46Z</dc:date>
      <clearspace:dateToText>3 weeks, 3 days ago</clearspace:dateToText>
    </item>
    <item>
      <title>用于MIDP的URLEncoder类（转）</title>
      <link>http://developer.sonyericsson.com/community/docs/DOC-3297</link>
      <description>&lt;!-- [DocumentBodyStart:24884f00-717e-44e0-885f-e74d071ab9c4] --&gt;&lt;div class='jive-rendered-content'&gt;&lt;p&gt;转自&lt;a class="jive-link-external-small" href="http://blog.csdn.net/asklxf/archive/2005/10/20/509789.aspx"&gt;http://blog.csdn.net/asklxf/archive/2005/10/20/509789.aspx&lt;/a&gt;&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;p&gt;由于MIDP没有J2SE对应的java.net.URLEncoder类，因此，要向服务器发送HTTP请求，必须自己进行URL编码，参考JDK1.4.2的src代码，将其改为一个能用在MIDP环境中的URLEncoder类：&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Courier New'; color: #008080;"&gt;// URLEncoder.java&lt;br/&gt;package com.mboker.blog.midp.http;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Courier New'; color: #008080;"&gt;import java.io.*;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Courier New'; color: #008080;"&gt;/**&lt;br/&gt; * Encode url, just like java.net.URLEncoder.encode() in J2SE.&amp;lt;br&amp;gt;&lt;br/&gt; * NOTE: This class is modified from java.net.URLEncoder class in J2SE 1.4.&lt;br/&gt; * &lt;br/&gt; * @author Xuefeng&lt;br/&gt; */&lt;br/&gt;class URLEncoder {&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Courier New'; color: #008080;"&gt;    private static final int MAX_BYTES_PER_CHAR = 10; // rather arbitrary limit, but safe for now&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Courier New'; color: #008080;"&gt;    private static boolean[] dontNeedEncoding;&lt;br/&gt;    private static final int caseDiff = ('a' - 'A');&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Courier New'; color: #008080;"&gt;    static {&lt;br/&gt;        dontNeedEncoding = new boolean[256];&lt;br/&gt;        for (int i='a'; i&amp;lt;='z'; i++) {&lt;br/&gt;            dontNeedEncoding[i] = true;&lt;br/&gt;        }&lt;br/&gt;        for (int i='A'; i&amp;lt;='Z'; i++) {&lt;br/&gt;            dontNeedEncoding[i] = true;&lt;br/&gt;        }&lt;br/&gt;        for (int i='0'; i&amp;lt;='9'; i++) {&lt;br/&gt;            dontNeedEncoding[i] = true;&lt;br/&gt;        }&lt;br/&gt;        dontNeedEncoding[' '] = true;&lt;br/&gt;        dontNeedEncoding['-'] = true;&lt;br/&gt;        dontNeedEncoding['_'] = true;&lt;br/&gt;        dontNeedEncoding['.'] = true;&lt;br/&gt;        dontNeedEncoding['*'] = true;&lt;br/&gt;    }&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Courier New'; color: #008080;"&gt;    private URLEncoder() {}&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Courier New'; color: #008080;"&gt;    &lt;span style="color: #ff0000;"&gt;public static String encode(String s)&lt;/span&gt; {&lt;br/&gt;     boolean wroteUnencodedChar = false;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Courier New'; color: #008080;"&gt;        StringBuffer out = new StringBuffer(s.length());&lt;br/&gt;        ByteArrayOutputStream buf = new ByteArrayOutputStream(MAX_BYTES_PER_CHAR);&lt;br/&gt;        OutputStreamWriter writer = new OutputStreamWriter(buf);&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Courier New'; color: #008080;"&gt;        for (int i = 0; i &amp;lt; s.length(); i++) {&lt;br/&gt;            int c = (int) s.charAt(i);&lt;br/&gt;            if (c&amp;lt;256 &amp;amp;&amp;amp; dontNeedEncoding[c]) {&lt;br/&gt;                out.append((char) (c==' ' ? '+' : c));&lt;br/&gt;                wroteUnencodedChar = true;&lt;br/&gt;            } else {&lt;br/&gt;                // convert to external encoding before hex conversion&lt;br/&gt;                try {&lt;br/&gt;                    if (wroteUnencodedChar) { // Fix for 4407610&lt;br/&gt;                        writer = new OutputStreamWriter(buf);&lt;br/&gt;                        wroteUnencodedChar = false;&lt;br/&gt;                    }&lt;br/&gt;                    writer.write(c);&lt;br/&gt;                    /*&lt;br/&gt;                     * If this character represents the start of a Unicode&lt;br/&gt;                     * surrogate pair, then pass in two characters. It's not&lt;br/&gt;                     * clear what should be done if a bytes reserved in the&lt;br/&gt;                     * surrogate pairs range occurs outside of a legal surrogate&lt;br/&gt;                     * pair. For now, just treat it as if it were any other&lt;br/&gt;                     * character.&lt;br/&gt;                     */&lt;br/&gt;                    if (c &amp;gt;= 0xD800 &amp;amp;&amp;amp; c &amp;lt;= 0xDBFF) {&lt;br/&gt;                        if ((i + 1) &amp;lt; s.length()) {&lt;br/&gt;                            int d = (int) s.charAt(i + 1);&lt;br/&gt;                            if (d &amp;gt;= 0xDC00 &amp;amp;&amp;amp; d &amp;lt;= 0xDFFF) {&lt;br/&gt;                                writer.write(d);&lt;br/&gt;                                i++;&lt;br/&gt;                            }&lt;br/&gt;                        }&lt;br/&gt;                    }&lt;br/&gt;                    writer.flush();&lt;br/&gt;                } catch (IOException e) {&lt;br/&gt;                    buf.reset();&lt;br/&gt;                    continue;&lt;br/&gt;                }&lt;br/&gt;                byte[] ba = buf.toByteArray();&lt;br/&gt;                for (int j = 0; j &amp;lt; ba.length; j++) {&lt;br/&gt;                    out.append('%');&lt;br/&gt;                    char ch = toHex((ba[j] &amp;gt;&amp;gt; 4) &amp;amp; 0xF);&lt;br/&gt;                    // converting to use uppercase letter as part of&lt;br/&gt;                    // the hex value if ch is a letter.&lt;br/&gt;                    if (isLetter(ch)) {&lt;br/&gt;                        ch -= caseDiff;&lt;br/&gt;                    }&lt;br/&gt;                    out.append(ch);&lt;br/&gt;                    ch = toHex(ba[j] &amp;amp; 0xF);&lt;br/&gt;                    if (isLetter(ch)) {&lt;br/&gt;                        ch -= caseDiff;&lt;br/&gt;                    }&lt;br/&gt;                    out.append(ch);&lt;br/&gt;                }&lt;br/&gt;                buf.reset();&lt;br/&gt;            }&lt;br/&gt;        }&lt;br/&gt;        return out.toString();&lt;br/&gt;    }&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Courier New'; color: #008080;"&gt;    private static char toHex(int digit) {&lt;br/&gt;        if ((digit &amp;gt;= 16) || (digit &amp;lt; 0)) {&lt;br/&gt;            return '\0';&lt;br/&gt;        }&lt;br/&gt;        if (digit &amp;lt; 10) {&lt;br/&gt;            return (char)('0' + digit);&lt;br/&gt;        }&lt;br/&gt;        return (char)('a' - 10 + digit);&lt;br/&gt;    }&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Courier New'; color: #008080;"&gt;    private static boolean isLetter(char c) {&lt;br/&gt;        return (c&amp;gt;='a' &amp;amp;&amp;amp; c&amp;lt;='z');&lt;br/&gt;    }&lt;br/&gt;}&lt;/span&gt;&lt;/p&gt;&lt;p&gt;J2SE的URLEncoder依赖于java.lang.Character的许多特性，将其全部剔除并改造为基本运算，即可在MIDP环境中使用，中文测试也一切正常。&lt;/p&gt;&lt;/p&gt;&lt;/div&gt;&lt;!-- [DocumentBodyEnd:24884f00-717e-44e0-885f-e74d071ab9c4] --&gt;</description>
      <pubDate>Thu, 29 Oct 2009 01:37:59 GMT</pubDate>
      <author>developerworldwatch@kpi-consulting.net</author>
      <guid>http://developer.sonyericsson.com/community/docs/DOC-3297</guid>
      <dc:date>2009-10-29T01:37:59Z</dc:date>
      <clearspace:dateToText>3 weeks, 3 days ago</clearspace:dateToText>
    </item>
    <item>
      <title>J2ME 3D技术简介（转）</title>
      <link>http://developer.sonyericsson.com/community/docs/DOC-3296</link>
      <description>&lt;!-- [DocumentBodyStart:504dec3a-8d77-447a-ace5-53978a3baeec] --&gt;&lt;div class='jive-rendered-content'&gt;&lt;p&gt;转自&lt;a class="jive-link-external-small" href="http://blog.csdn.net/asklxf/archive/2005/03/07/313208.aspx"&gt;http://blog.csdn.net/asklxf/archive/2005/03/07/313208.aspx&lt;/a&gt;&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;3D技术对我们来说已经非常熟悉了，最常用的3D API有OpenGL和Microsoft的Direct 3D，在桌面游戏中早已广泛应用。对于J2ME程序而言，Mobile 3D Graphics API(&lt;a class="jive-link-external-small" href="http://jcp.org/en/jsr/detail?id=184"&gt;JSR184&lt;/a&gt;)的出现，使得为手机应用程序添加3D功能成为可能。&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;    JSR184标准（M3G：Mobile 3D Graphics）为Java移动应用程序定义了一个简洁的3D API接口，J2ME程序可以非常方便地使用M3G来实现3D应用比如游戏等等。M3G被设计为非常轻量级的，整个API的完整实现不超过150kb。&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;    M3G是J2ME的一个可选包，以OpenGL为基础的精简版，一共有30个类，运行在CLDC1.1/CLDC2.0上（必须支持浮点运算），可以在MIDP1.0和MIDP2.0中使用。目前，支持M3G的手机有Nokia 6230/3650/7650/6600、Siemens S65/CX65/S55/M55、Sony-Ericsson K700i/P800/P900、Moto 220/T720等。M3G只是一个Java接口，具体的底层3D引擎一般由C代码实现，比如许多手机厂商的3D引擎采用的便是SuperScape公司的Swerve引擎，这是一个专门为移动设备设计的高性能3D引擎。&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;    类似于Microsoft的D3D，M3G支持两种3D模式：立即模式（immediate mode）和保留模式（retained mode）。在立即模式下，开发者必须手动渲染每一帧，从而获得较快的速度，但代码较繁琐；在保留模式下，开发者只需设置好关键帧，剩下的动画由M3G完成，代码较简单，但速度较慢。M3G也允许混合使用这两种模式。&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;    3D模型可以在程序中创建，但是非常繁琐。因此，M3G提供一个Loader类，允许直接从一个单一的.m3g文件中读入全部3D场景。m3g文件可以通过3D Studio Max之类的软件创建。&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;    如果熟悉OpenGL，那么M3G是非常容易理解的。在M3G中，Graphics3D是3D渲染的屏幕接口，World代表整个3D场景，包括Camera（用于设置观察者视角）、Light（灯光）、Background（背景）和树型结构的任意数量的3D物体。3D对象在计算机中用点（Point, Pixel）、线（Line, Polyline, Spline）、面（Mesh）来描述，具体存储和运算（如旋转、投影）都是矩阵运算和变换。&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;    SUN的&lt;a class="jive-link-external-small" href="http://java.sun.com/products/j2mewtoolkit/download-2_2.html"&gt;WTK2.2&lt;/a&gt;已经内置了M3G的实现包，如果安装了WTK2.2，就可以在模拟器上运行3D MIDP程序。可以参考WTK2.2的示例demo3d。&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;    下面是一个最简单的M3G程序，来自Sony-Ericsson的示例代码，它创建一个旋转的金字塔，可以从&lt;a href="http://www.crackj2ee.com/blog/images/download.gif"&gt;&lt;img src="http://www.crackj2ee.com/blog/images/download.gif"/&gt;&lt;/a&gt; &lt;a class="jive-link-external-small" href="http://www.crackj2ee.com/blog/attachments/month_0503/kh0n_jsr_184_midlet.zip"&gt;此处&lt;/a&gt;下载完整代码并在WTK2.2中运行。&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;    首先，我们要获得唯一的Graphics3D实例，用于渲染3D场景。Graphics3D是一个Singleton实现，可以在任何地方获得：&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #008080;"&gt;g3d = Graphics3D.getInstance();&lt;/span&gt;&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;然后，在Canvas中渲染：&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #008080;"&gt;public class MyCanvas extends Canvas&lt;br/&gt;{&lt;br/&gt;   public void paint(Graphics g) {&lt;br/&gt;   try {&lt;br/&gt;      g3d.bindTarget(g);&lt;br/&gt;      ... update the scene ...&lt;br/&gt;      ... render the scene ...&lt;br/&gt;   } finally {&lt;br/&gt;      g3d.releaseTarget();&lt;br/&gt;   }&lt;br/&gt;}&lt;br/&gt;&lt;/span&gt;&lt;br/&gt;接下来创建一个World并设置Camera：&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #008080;"&gt;world = new World();&lt;br/&gt;camera = new Camera();&lt;br/&gt;world.addChild(camera);&lt;br/&gt;// The width and height of the canvas.&lt;br/&gt;float w = getWidth();&lt;br/&gt;float h = getHeight();&lt;br/&gt;// Constructs a perspective projection matrix and sets that as the current projection matrix.&lt;br/&gt;camera.setPerspective(60.0f, w / h, 0.1f, 50f);&lt;br/&gt;world.setActiveCamera(camera);&lt;/span&gt;&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;接着，在createPyramid()方法中创建一个Mesh，代表金字塔，并添加到World中：&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #008080;"&gt;private Mesh pyramidMesh; // the pyramid in the scene&lt;br/&gt;&lt;br/&gt;pyramidMesh = createPyramid(); // create our pyramid.&lt;br/&gt;pyramidMesh.setTranslation(0.0f, 0.0f, -3.0f); // move the pyramid 3 units into the screen.&lt;br/&gt;world.addChild(pyramidMesh); // add the pyramid to the world&lt;/span&gt;&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;最后，在一个线程中让金字塔绕Y轴旋转起来：&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #008080;"&gt;public void run() {&lt;br/&gt;    Graphics g = getGraphics();&lt;br/&gt;    while(true) {&lt;br/&gt;        // rotate the pyramid 1 degree around the Y-axis.&lt;br/&gt;        pyramidMesh.postRotate(3.0f, 0.0f, 1.0f, 0.0f);&lt;br/&gt;        draw3D(g);&lt;br/&gt;        flushGraphics();&lt;br/&gt;    }&lt;br/&gt;}&lt;/span&gt;&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;以上对M3G作了一个简单的介绍，如果需要更多资料，可以参考：&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;a class="jive-link-external-small" href="http://jcp.org/en/jsr/detail?id=184"&gt;http://jcp.org/en/jsr/detail?id=184&lt;/a&gt;&lt;br/&gt;&lt;a class="jive-link-external-small" href="http://www.opengl.org/"&gt;http://www.opengl.org&lt;/a&gt;&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;a class="jive-link-external-small" href="http://www.crackj2ee.com/blog/attachments/month_0503/kh0n_jsr_184_midlet.zip"&gt;点击下载源代码&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;!-- [DocumentBodyEnd:504dec3a-8d77-447a-ace5-53978a3baeec] --&gt;</description>
      <pubDate>Thu, 29 Oct 2009 01:33:16 GMT</pubDate>
      <author>developerworldwatch@kpi-consulting.net</author>
      <guid>http://developer.sonyericsson.com/community/docs/DOC-3296</guid>
      <dc:date>2009-10-29T01:33:16Z</dc:date>
      <clearspace:dateToText>3 weeks, 3 days ago</clearspace:dateToText>
    </item>
    <item>
      <title>Capuchin-JavaME程序员开发延伸之路.</title>
      <link>http://developer.sonyericsson.com/community/docs/DOC-3006</link>
      <description>&lt;!-- [DocumentBodyStart:02c3f6ad-7018-4229-85bf-c796294fa083] --&gt;&lt;div class='jive-rendered-content'&gt;&lt;/div&gt;&lt;!-- [DocumentBodyEnd:02c3f6ad-7018-4229-85bf-c796294fa083] --&gt;</description>
      <category domain="http://developer.sonyericsson.com/community/tags?containerType=?14&amp;container=2023">capuchin</category>
      <category domain="http://developer.sonyericsson.com/community/tags?containerType=?14&amp;container=2023">j2me</category>
      <category domain="http://developer.sonyericsson.com/community/tags?containerType=?14&amp;container=2023">javame</category>
      <pubDate>Fri, 08 May 2009 16:08:54 GMT</pubDate>
      <author>developerworldwatch@kpi-consulting.net</author>
      <guid>http://developer.sonyericsson.com/community/docs/DOC-3006</guid>
      <dc:date>2009-05-08T16:08:54Z</dc:date>
      <clearspace:dateToText>1 month, 29 minutes ago</clearspace:dateToText>
      <clearspace:replyCount>2</clearspace:replyCount>
    </item>
    <item>
      <title>低级UI上实现九宫图</title>
      <link>http://developer.sonyericsson.com/community/docs/DOC-3264</link>
      <description>&lt;!-- [DocumentBodyStart:56f5fce5-c6c7-433b-909a-9dffa95a2302] --&gt;&lt;div class='jive-rendered-content'&gt;&lt;p&gt;由于J2ME并没有提供Button控件，更不用说ImageButton了。所以J2ME中要实现九宫图只能通过Canvas和KeyPressed。&lt;/p&gt;&lt;p&gt;自己有个原创的，可以自适应屏幕大小。但很抱歉不能发布出来（软件所有权不属于我，555~~）。虽然这个实现很简单，但是却很繁琐，而且最近太懒了，不想单独再提炼一份。所以转一个过来。&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span&gt;转自：&lt;/span&gt;&lt;a class="jive-link-external-small" href="http://www.javaeye.com/topic/491888，如有转载，请注明出处。"&gt;http://www.javaeye.com/topic/491888，如有转载，请注明出处。&lt;/a&gt;&lt;/p&gt;&lt;p&gt;核心代码如下： &lt;br/&gt;public static final String[] filenames = { "/01.png", "/02.png", "/03.png", &lt;br/&gt;   "/04.png", "/05.png", "/06.png" }; &lt;br/&gt; public static final String[] labels = { "公文推送", "通知公告", "日程安排", "通讯录查询", &lt;br/&gt;   "会议室查询", "手机邮箱" }; &lt;br/&gt; public Image[] icons = new Image[9]; &lt;br/&gt; public void paint(Graphics g) { &lt;br/&gt;  int cw = this.getWidth(); &lt;br/&gt;  int ch = this.getHeight(); &lt;br/&gt;  try { &lt;br/&gt;   // paintHead(g); &lt;br/&gt;   this.setFullScreenMode(true); &lt;br/&gt;   Image img = Image.createImage("/sliderbgn.JPG"); &lt;br/&gt;   // g.drawImage(img,0, 0, Graphics.TOP|Graphics.LEFT); &lt;br/&gt;   g.drawImage(img, 0, 0, Graphics.TOP &lt;br/&gt;     | Graphics.LEFT); &lt;br/&gt; &lt;br/&gt;   for (int i = 0; i &amp;lt; filenames.length; i++) { &lt;br/&gt;    try { &lt;br/&gt;     icons[i] = Image.createImage(filenames[i]); &lt;br/&gt;    } catch (IOException ex) { &lt;br/&gt; &lt;br/&gt;    } &lt;br/&gt;   } &lt;br/&gt;   int old_color = g.getColor(); &lt;br/&gt;   g.setColor(0xffffff); &lt;br/&gt;      int startY=ch/4; &lt;br/&gt; &lt;br/&gt;   for (int i = 0; i &amp;lt; 2; i++) { &lt;br/&gt;    for (int j = 0; j &amp;lt; 3; j++) { &lt;br/&gt; &lt;br/&gt;     g.drawImage(icons[i * 3 + j], j * cw / 3 + 10, startY+i * ch*3 / 10, &lt;br/&gt;       Graphics.TOP | Graphics.LEFT); &lt;br/&gt;     g.drawString(labels[i * 3 + j], j * cw / 3 + 30, startY+i * ch*3 / 10 &lt;br/&gt;        + icons[i].getHeight(), &lt;br/&gt;       Graphics.HCENTER | Graphics.TOP); &lt;br/&gt;      &lt;br/&gt; &lt;br/&gt;    } &lt;br/&gt;   } &lt;br/&gt;   g.setColor(old_color); &lt;br/&gt;   paintBottom(g); &lt;br/&gt;  } catch (Exception ex) { &lt;br/&gt;   System.out.println(ex.toString()); &lt;br/&gt;  } &lt;br/&gt; }&lt;/p&gt;&lt;/div&gt;&lt;!-- [DocumentBodyEnd:56f5fce5-c6c7-433b-909a-9dffa95a2302] --&gt;</description>
      <category domain="http://developer.sonyericsson.com/community/tags?containerType=?14&amp;container=2023">九宫图</category>
      <category domain="http://developer.sonyericsson.com/community/tags?containerType=?14&amp;container=2023">j2me</category>
      <pubDate>Wed, 21 Oct 2009 02:41:30 GMT</pubDate>
      <author>developerworldwatch@kpi-consulting.net</author>
      <guid>http://developer.sonyericsson.com/community/docs/DOC-3264</guid>
      <dc:date>2009-10-21T02:41:30Z</dc:date>
      <clearspace:dateToText>1 month, 2 days ago</clearspace:dateToText>
    </item>
    <item>
      <title>在J2ME中查找内存泄漏的方法</title>
      <link>http://developer.sonyericsson.com/community/docs/DOC-3263</link>
      <description>&lt;!-- [DocumentBodyStart:62d05053-35cc-4632-8e7e-d2fd1ead630f] --&gt;&lt;div class='jive-rendered-content'&gt;&lt;p&gt;转自&lt;a class="jive-link-external-small" href="http://www.loongzh.com/?p=69"&gt;http://www.loongzh.com/?p=69&lt;/a&gt;&lt;/p&gt;&lt;p style="min-height: 8pt; height: 8pt; padding: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;在J2ME中查找内存泄漏是一件很困难的事，它不像J2SE似的有很强大的工具支持，但是它还是有一定的方法来做的。&lt;/p&gt;&lt;p&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt;首先在查找内存泄漏时，不要使用&lt;span&gt;Runtime.free/totalMemory()这两个函数，它们在大多数情况下得到的数值都是不准确的，也不要相信WTK中的memory monitor显示的数值,它也是不准确的。如果说有什么模拟器的可以相信的话，Nokia的S40手机的模拟器可能算上一个。可遗憾的是它比较不好用。&lt;/span&gt;&lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt;&lt;span style="font-family: arial, sans-serif;"&gt;既然通过得到内存大小的方式是不保险的，那么在碰到内存泄漏的情况下要怎么来判断了？答案是使用WTK 的memory monitor，WTK的memory monitor显示的内存不正确，但是它还有一个功能是显示每一个class的instance个数，通过比较memory monitor的instance与实际中需要的instance个数，我们就能得出是否发生内存泄漏，泄漏在那几个对象上。&lt;/span&gt;&lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt;当确定内存泄漏的地方后，可以通过排除法来锁定内存泄漏的代码：把功能一点点的去掉，看内存泄漏现像是否存在，如果不存在，那么就找到对应的代码了。当然这还存在一个问题，那就是当功能去掉时，可能会导致泄漏的内存大小也变小，如果以为这就是找到对应的代码的话，那么就大错特错了，因为内存的减少可能是资源图片的减少了（资源图片占用的内存都比较大，少加张图片和不少加图片是相差很大的）。为了避免这种情况，还是要用到memory monitor，使用它来比较instancer的个数，通过instance的个数是否减少来判断是否在是真正找到对应的问题所在。&lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt;使用这种方法是痛苦的，除了这种方法，还有一种就是看代码，这里说的看代码是有几个侧重点的，不是什么代码都要仔仔细细的看一遍过去的！首先可以看一下Vector这种变量，看是否出现像&lt;a class="jive-link-external-small" href="http://www.douban.com/subject/3360807/"&gt;《Effective Java》&lt;/a&gt;中第六条的情况，出现过期引用的情况。这种情况是相当常见的（都上了《Effect Java》，肯定常见了），然后可以看一下Listener（监听器）与回调的实现。在Listener中，很有可能的情况就是对象A指向对B，A做为listener注册到一个hashtable中去了。这时把B的值设置为null，而不清除对应的listener的话，那么B这个对象也是不会被回收的。&lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt;总得说来，在查找内存泄漏的时候，我们不要相信J2ME的函数，善用工具，有侧重的查看代码。做到这些，问题肯定会被解决的。&lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;/p&gt;&lt;/div&gt;&lt;!-- [DocumentBodyEnd:62d05053-35cc-4632-8e7e-d2fd1ead630f] --&gt;</description>
      <category domain="http://developer.sonyericsson.com/community/tags?containerType=?14&amp;container=2023">内存泄漏</category>
      <category domain="http://developer.sonyericsson.com/community/tags?containerType=?14&amp;container=2023">j2me</category>
      <pubDate>Tue, 20 Oct 2009 15:07:01 GMT</pubDate>
      <author>developerworldwatch@kpi-consulting.net</author>
      <guid>http://developer.sonyericsson.com/community/docs/DOC-3263</guid>
      <dc:date>2009-10-20T15:07:01Z</dc:date>
      <clearspace:dateToText>1 month, 2 days ago</clearspace:dateToText>
    </item>
  </channel>
</rss>

