﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>语源科技BlogJava-&lt;font color="#FFFF00"&gt;Cyh的博客&lt;/font&gt;</title><link>http://www.blogjava.net/kissyan4916/</link><description>Email:kissyan4916@163.com&lt;br&gt;
</description><language>zh-cn</language><lastBuildDate>Sat, 04 Apr 2026 09:01:05 GMT</lastBuildDate><pubDate>Sat, 04 Apr 2026 09:01:05 GMT</pubDate><ttl>60</ttl><item><title>集成FCKeditor 3.5.3</title><link>http://www.blogjava.net/kissyan4916/archive/2011/05/18/350524.html</link><dc:creator>啥都写点</dc:creator><author>啥都写点</author><pubDate>Wed, 18 May 2011 13:24:00 GMT</pubDate><guid>http://www.blogjava.net/kissyan4916/archive/2011/05/18/350524.html</guid><description><![CDATA[<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 好像现在改名字了 叫CKeditor了。。。 最近带学生做高校门户网站，得用Struts+hibernate来做。 于是将项目搭建好后，集成了freemarker 以及最新版本的FCKeditor3.5.3, 可能很多初学者也在寻找这方面的资源，所以将该DEMO上传，欢迎大家前去下载， 项目保证能够运行，如若出现问题，请联系我 chenyanhu@vip.163.com<br /><br />下载地址 <div>http://download.csdn.net/source/3291055</div></div><img src ="http://www.blogjava.net/kissyan4916/aggbug/350524.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kissyan4916/" target="_blank">啥都写点</a> 2011-05-18 21:24 <a href="http://www.blogjava.net/kissyan4916/archive/2011/05/18/350524.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>android自适应屏幕方向和大小</title><link>http://www.blogjava.net/kissyan4916/articles/339702.html</link><dc:creator>啥都写点</dc:creator><author>啥都写点</author><pubDate>Fri, 03 Dec 2010 02:35:00 GMT</pubDate><guid>http://www.blogjava.net/kissyan4916/articles/339702.html</guid><description><![CDATA[<p>一：不同的layout</p>
<p>Android手机 屏幕 大小不一，有480x320, 640x360, 800x480.怎样才能让App自动 适应不同的屏幕 呢？ <br />
&nbsp;&nbsp; 其实很简单，只需要在res目录下创建不同的layout文件 夹，比如layout-640x360,layout-800x480,所有的layout文件在编译 之后都会写入R.java里，而系统 会根据屏幕 的大小自己选择合适的layout进行使用。</p>
<p>二：hdpi、mdpi、ldpi</p>
<p>在之前的版本中，只有一个drawable，而2.1版本中有drawable-mdpi、drawable-ldpi、drawable-hdpi三个，这三个主要是为了支持多分辨率。</p>
<p>　　drawable- hdpi、drawable- mdpi、drawable-ldpi的区别：</p>
<p>　　(1)drawable-hdpi里面存放高分辨率的图片,如WVGA (480x800),FWVGA (480x854)</p>
<p>　　(2)drawable-mdpi里面存放中等分辨率的图片,如HVGA (320x480)</p>
<p>　　(3)drawable-ldpi里面存放低分辨率的图片,如QVGA (240x320)</p>
<p>　　系统会根据机器的分辨率来分别到这几个文件夹里面去找对应的图片。</p>
<p>　　在开发 程序 时为了兼容不同平台 不同屏幕 ，建议各自文件夹根据需求均存放不同版本图片。</p>
<p>屏幕 方向：</p>
<p>横屏竖屏自动切换：</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; 可以在res目录下建立layout-port和layout-land两个目录，里面分别放置竖屏和横屏两种布局文件，这样在手机屏幕 方向变化的时候系统会自动调用相应的布局文件，避免一种布局文件无法满足两种屏幕 显示的问题。</p>
<p>不切换：</p>
<p><br />
以下步骤是网上流传的，不过我自己之前是通过图形化界面 实现这个配置，算是殊途同归，有空我会把图片贴上来。</p>
<p>还要说明一点：每个activity 都有这个属性screenOrientation，每个activity都需要设置 ，可以设置为竖屏（portrait），也可以设置为无重力感应（nosensor）。</p>
<p>要让程序界面保持一个方向，不随手机方向转动而变化的处理办法： <br />
&nbsp; <br />
在AndroidManifest.xml里面配置一下就可以了。加入这一行android :screenOrientation="landscape"。<br />
例如（landscape是横向，portrait是纵向）：</p>
<p>代码 :</p>
<p>view plaincopy to clipboardprint?<br />
&lt;?xml version="1.0" encoding="utf-8"?&gt;&nbsp; <br />
&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; package="com.ray.linkit"&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; android:versionCode="1"&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; android:versionName="1.0"&gt;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &lt;application android:icon="@drawable/icon" android:label="@string/app_name"&gt;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;activity android:name=".Main"&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; android:label="@string/app_name"&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; android:screenOrientation="portrait"&gt;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;intent-filter&gt;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;action android:name="android.intent.action.MAIN" /&gt;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;category android:name="android.intent.category.LAUNCHER" /&gt;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/intent-filter&gt;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/activity&gt;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;activity android:name=".GamePlay"&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; android:screenOrientation="portrait"&gt;&lt;/activity&gt;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;activity android:name=".OptionView"&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; android:screenOrientation="portrait"&gt;&lt;/activity&gt;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &lt;/application&gt;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &lt;uses-sdk android:minSdkVersion="3" /&gt;&nbsp; <br />
&lt;/manifest&gt;&nbsp; <br />
&lt;?xml version="1.0" encoding="utf-8"?&gt;<br />
&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; package="com.ray.linkit"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; android:versionCode="1"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; android:versionName="1.0"&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;application android:icon="@drawable/icon" android:label="@string/app_name"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;activity android:name=".Main"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; android:label="@string/app_name"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; android:screenOrientation="portrait"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;intent-filter&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;action android:name="android.intent.action.MAIN" /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;category android:name="android.intent.category.LAUNCHER" /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/intent-filter&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/activity&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;activity android:name=".GamePlay"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; android:screenOrientation="portrait"&gt;&lt;/activity&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;activity android:name=".OptionView"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; android:screenOrientation="portrait"&gt;&lt;/activity&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/application&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;uses-sdk android:minSdkVersion="3" /&gt;<br />
&lt;/manifest&gt; </p>
<p>另外，android中每次屏幕 的切换动会重启Activity，所以应该在Activity销毁前保存当前活动的状态，在Activity再次Create的时候载入配置，那样，进行中的游戏 就不会自动重启了！</p>
<p>有的程序适合从竖屏切换到横屏，或者反过来，这个时候怎么办呢？可以在配置Activity的地方进行如下的配置android:screenOrientation="portrait"。这样就可以保证是竖屏总是竖屏了，或者landscape横向。</p>
<p>而有的程序是适合横竖屏切换的。如何处理呢？首先要在配置Activity的时候进行如下的配置：android:configChanges="keyboardHidden|orientation"，另外需要重写Activity的 onConfigurationChanged方法。实现方式如下，不需要做太多的内容：</p>
<p>view plaincopy to clipboardprint?<br />
@Override&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void onConfigurationChanged(Configuration newConfig) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super.onConfigurationChanged(newConfig);&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // land do nothing is ok&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // port do nothing is ok&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp; </p>
<p>&nbsp;</p>
<p>本文来自CSDN博客，转载请标明出处：http://blog.csdn.net/JavaTiger427/archive/2010/11/29/6043097.aspx</p><img src ="http://www.blogjava.net/kissyan4916/aggbug/339702.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kissyan4916/" target="_blank">啥都写点</a> 2010-12-03 10:35 <a href="http://www.blogjava.net/kissyan4916/articles/339702.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Android游戏开发之旅（二十） 双按事件捕获</title><link>http://www.blogjava.net/kissyan4916/articles/339701.html</link><dc:creator>啥都写点</dc:creator><author>啥都写点</author><pubDate>Fri, 03 Dec 2010 02:34:00 GMT</pubDate><guid>http://www.blogjava.net/kissyan4916/articles/339701.html</guid><description><![CDATA[<p>对于游戏开发中我们可能经常要用到双按屏幕，在Android 1.6以前并没有提供完善的手势识别类，在Android 1.5 SDK中我们可以找到android.view.GestureDetector.OnDoubleTapListener，但是经过测试仍然无法正常工作，不知道什么原因，如果您知道可以联系android123@163.com 共享下。最终我们使用的解决方法如下 </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; 最终我们测试的如下:</p>
<p>view plaincopy to clipboardprint?<br />
public class TouchLayout extends RelativeLayout {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; public Handler doubleTapHandler = null;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; protected long lastDown = -1;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; public final static long DOUBLE_TIME = 500;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;public TouchLayout(Context context) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super(context);&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; public TouchLayout(Context context, AttributeSet attrs) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super(context, attrs);&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; public TouchLayout(Context context, AttributeSet attrs, int defStyle) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super(context, attrs, defStyle);&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; public boolean onTouchEvent(MotionEvent event) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.handleEvent(event);&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (event.getAction() == MotionEvent.ACTION_DOWN) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; long nowDown = System.currentTimeMillis();&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (nowDown - lastDown &lt; DOUBLE_TIME)&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (doubleTapHandler != null)&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; doubleTapHandler.sendEmptyMessage(-1);&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lastDown = nowDown;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return true;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; protected void handleEvent(MotionEvent event) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; switch (event.getAction()) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case MotionEvent.ACTION_DOWN:&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //Do sth 这里处理即可&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case MotionEvent.ACTION_UP:&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //Do sth&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
}&nbsp; <br />
public class TouchLayout extends RelativeLayout {<br />
&nbsp;&nbsp;&nbsp; public Handler doubleTapHandler = null;<br />
&nbsp;&nbsp;&nbsp; protected long lastDown = -1;<br />
&nbsp;&nbsp;&nbsp; public final static long DOUBLE_TIME = 500;<br />
&nbsp;<br />
&nbsp;public TouchLayout(Context context) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super(context);<br />
&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; public TouchLayout(Context context, AttributeSet attrs) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super(context, attrs);<br />
&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; public TouchLayout(Context context, AttributeSet attrs, int defStyle) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super(context, attrs, defStyle);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; public boolean onTouchEvent(MotionEvent event) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.handleEvent(event);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (event.getAction() == MotionEvent.ACTION_DOWN) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; long nowDown = System.currentTimeMillis();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (nowDown - lastDown &lt; DOUBLE_TIME)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (doubleTapHandler != null)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; doubleTapHandler.sendEmptyMessage(-1);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lastDown = nowDown;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return true;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp; <br />
&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; protected void handleEvent(MotionEvent event) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; switch (event.getAction()) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case MotionEvent.ACTION_DOWN:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //Do sth 这里处理即可<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case MotionEvent.ACTION_UP:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //Do sth<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp; }<br />
} </p>
<p>&nbsp;</p>
<p>本文来自CSDN博客，转载请标明出处：http://blog.csdn.net/JavaTiger427/archive/2010/11/25/6034698.aspx</p><img src ="http://www.blogjava.net/kissyan4916/aggbug/339701.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kissyan4916/" target="_blank">啥都写点</a> 2010-12-03 10:34 <a href="http://www.blogjava.net/kissyan4916/articles/339701.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Android游戏开发之旅（十八） SoundPool类 </title><link>http://www.blogjava.net/kissyan4916/articles/339699.html</link><dc:creator>啥都写点</dc:creator><author>啥都写点</author><pubDate>Fri, 03 Dec 2010 02:33:00 GMT</pubDate><guid>http://www.blogjava.net/kissyan4916/articles/339699.html</guid><description><![CDATA[<p>对于Android的游戏音效播放，上次Android123已经告诉大家使用SoundPool类来实现，由于本次我们的游戏需要多种音效同时播放所以就选择了SoundPool类，它和Android提供常规的MediaPlayer类有哪些不同呢? </p>
<p>&nbsp; 1. SoundPool载入音乐文件使用了独立的线程，不会阻塞UI主线程的操作。但是这里Android开发网提醒大家如果音效文件过大没有载入完成，我们调用play方法时可能产生严重的后果，这里Android SDK提供了一个SoundPool.OnLoadCompleteListener类来帮助我们了解媒体文件是否载入完成，我们重载 onLoadComplete(SoundPool soundPool, int sampleId, int status) 方法即可获得。 </p>
<p>&nbsp; 2. 从上面的onLoadComplete方法可以看出该类有很多参数，比如类似id，是的SoundPool在load时可以处理多个媒体一次初始化并放入内存中，这里效率比MediaPlayer高了很多。 </p>
<p>&nbsp; 3. SoundPool类支持同时播放多个音效，这对于游戏来说是十分必要的，而MediaPlayer类是同步执行的只能一个文件一个文件的播放。 </p>
<p>&nbsp; SoundPool类使用示例代码: </p>
<p>view plaincopy to clipboardprint?<br />
SoundPool sp=new SoundPool(8, /*maxStreams*/, AudioManager.STREAM_MUSIC /*streamType*/, 100 /*srcQuality*/) ;&nbsp; <br />
SoundPool sp=new SoundPool(8, /*maxStreams*/, AudioManager.STREAM_MUSIC /*streamType*/, 100 /*srcQuality*/) ; </p>
<p>&nbsp;有关载入音效的方法，有以下几种方法 </p>
<p>view plaincopy to clipboardprint?<br />
int&nbsp; load(Context context, int resId, int priority)&nbsp; //从APK资源载入&nbsp;&nbsp; <br />
&nbsp;&nbsp; int&nbsp; load(FileDescriptor fd, long offset, long length, int priority)&nbsp; //从FileDescriptor对象载入&nbsp;&nbsp; <br />
&nbsp;&nbsp; int&nbsp; load(AssetFileDescriptor afd, int priority)&nbsp; //从Asset对象载入&nbsp;&nbsp; <br />
&nbsp;&nbsp; int&nbsp; load(String path, int priority)&nbsp; //从完整文件路径名载入&nbsp; <br />
int&nbsp; load(Context context, int resId, int priority)&nbsp; //从APK资源载入<br />
&nbsp;&nbsp; int&nbsp; load(FileDescriptor fd, long offset, long length, int priority)&nbsp; //从FileDescriptor对象载入<br />
&nbsp;&nbsp; int&nbsp; load(AssetFileDescriptor afd, int priority)&nbsp; //从Asset对象载入<br />
&nbsp;&nbsp; int&nbsp; load(String path, int priority)&nbsp; //从完整文件路径名载入 </p>
<p>我们看到了每个load的重载版本的最后一个参数为优先级，这里用于播放多个文件时，系统会优先处理不过目前Android123提示大家SDK提到了目前并没有实现，所以没有实际的效果。 </p>
<p>&nbsp;&nbsp; 对于播放，可以使用 play(int soundID, float leftVolume, float rightVolume, int priority, int loop, float rate)&nbsp;&nbsp; 而停止则可以使用 pause(int streamID) 方法，这里的streamID和soundID均在构造SoundPool类的第一个参数中指明了总数量，而id从0开始。</p>
<p><br />
本文来自CSDN博客，转载请标明出处：http://blog.csdn.net/JavaTiger427/archive/2010/11/25/6034679.aspx</p><img src ="http://www.blogjava.net/kissyan4916/aggbug/339699.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kissyan4916/" target="_blank">啥都写点</a> 2010-12-03 10:33 <a href="http://www.blogjava.net/kissyan4916/articles/339699.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Android游戏开发之旅（十九） 分辨率大全</title><link>http://www.blogjava.net/kissyan4916/articles/339700.html</link><dc:creator>啥都写点</dc:creator><author>啥都写点</author><pubDate>Fri, 03 Dec 2010 02:33:00 GMT</pubDate><guid>http://www.blogjava.net/kissyan4916/articles/339700.html</guid><description><![CDATA[<p>对于Android游戏开发我们不得不像iPhone那样思考兼容Android平板电脑，对于苹果要考虑iPad、iPhone 3GS和iPhone 4等屏幕之间的兼容性，对于几乎所有的分辨率Android123总结了大约超过20中粉笔阿女郎的大小和对应关系，对于开发Android游戏而言可以考虑到未来的3.0以及很多平板电脑的需要。 </p>
<p>&nbsp; 常规的我们可能只考虑QVGA，HVGA，WVGA，FWVGA和DVGA，但是抛去了手机不谈，可能平板使用类似 WSVGA的1024x576以及WXGA的1280x768等等。</p>
<p>QVGA = 320 * 240;<br />
WQVGA = 320 * 480;<br />
WQVGA2 = 400 * 240;<br />
WQVGA3 = 432 * 240;<br />
HVGA = 480 * 320;<br />
VGA = 640 * 480;<br />
WVGA = 800 * 480;<br />
WVGA2 = 768 * 480;<br />
FWVGA = 854 * 480;<br />
DVGA = 960 * 640;<br />
PAL = 576 * 520;<br />
NTSC = 486 * 440;<br />
SVGA = 800 * 600;<br />
WSVGA = 1024 * 576;<br />
XGA = 1024 * 768;<br />
XGAPLUS = 1152 * 864;<br />
HD720 = 1280 * 720;<br />
WXGA = 1280 * 768;<br />
WXGA2 = 1280 * 800;<br />
WXGA3 = 1280 * 854;<br />
SXGA = 1280 * 1024;<br />
WXGA4 = 1366 * 768;<br />
SXGAMINUS = 1280 * 960;<br />
SXGAPLUS = 1400 * 1050;<br />
WXGAPLUS = 1440 * 900;<br />
HD900 = 1600 * 900;<br />
WSXGA = 1600 * 1024;<br />
WSXGAPLUS = 1680 * 1050;<br />
UXGA = 1600 * 1200;<br />
HD1080 = 1920 * 1080;<br />
QWXGA = 2048 * 1152;<br />
WUXGA = 1920 * 1200;<br />
TXGA = 1920 * 1400;<br />
QXGA = 2048 * 1536;<br />
WQHD = 2560 * 1440;<br />
WQXGA = 2560 * 1600;<br />
QSXGA = 2560 * 2048;<br />
QSXGAPLUS = 2800 * 2100;<br />
WQSXGA = 3200 * 2048;<br />
QUXGA = 3200 * 2400;<br />
QFHD = 3840 * 2160;<br />
WQUXGA = 3840 * 2400;<br />
HD4K = 4096 * 2304;<br />
HXGA = 4096 * 3072;<br />
WHXGA = 5120 * 3200;<br />
HSXGA = 5120 * 4096;<br />
WHSXGA = 6400 * 4096;<br />
HUXGA = 6400 * 4800;<br />
SHV = 7680 * 4320;<br />
WHUXGA = 7680 * 4800;</p>
<p>&nbsp;</p>
<p>本文来自CSDN博客，转载请标明出处：http://blog.csdn.net/JavaTiger427/archive/2010/11/25/6034693.aspx</p><img src ="http://www.blogjava.net/kissyan4916/aggbug/339700.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kissyan4916/" target="_blank">啥都写点</a> 2010-12-03 10:33 <a href="http://www.blogjava.net/kissyan4916/articles/339700.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Android游戏开发之旅（十七） 图像渐变特效</title><link>http://www.blogjava.net/kissyan4916/articles/339698.html</link><dc:creator>啥都写点</dc:creator><author>啥都写点</author><pubDate>Fri, 03 Dec 2010 02:32:00 GMT</pubDate><guid>http://www.blogjava.net/kissyan4916/articles/339698.html</guid><description><![CDATA[<p>在Android游戏开发中我们不免要涉及到一些图形特效处理，今天主要看下Android平台下实现渐变效果。在 android.graphics中我们可以找到有关Gradient字样的类，比如LinearGradient 线性渐变、RadialGradient径向渐变和 角度渐变SweepGradient 三种，他们的基类为android.graphics.Shader。为了显示出效果android123使用一个简单的例子来说明。 </p>
<p>&nbsp; 一、LinearGradient线性渐变</p>
<p>&nbsp; 在android平台中提供了两种重载方式来实例化该类分别为，他们的不同之处为参数中第一种方法可以用颜色数组，和位置来实现更细腻的过渡效果，比如颜色采样int[] colors数组中存放20种颜色，则渐变将会逐一处理。而第二种方法参数仅为起初颜色color0和最终颜色color1。</p>
<p>view plaincopy to clipboardprint?<br />
LinearGradient(float x0, float y0, float x1, float y1, int[] colors, float[] positions, Shader.TileMode tile)&nbsp;&nbsp;&nbsp; <br />
LinearGradient(float x0, float y0, float x1, float y1, int color0, int color1, Shader.TileMode tile)&nbsp;&nbsp; <br />
LinearGradient(float x0, float y0, float x1, float y1, int[] colors, float[] positions, Shader.TileMode tile) <br />
LinearGradient(float x0, float y0, float x1, float y1, int color0, int color1, Shader.TileMode tile)&nbsp; </p>
<p>使用实例如下</p>
<p>view plaincopy to clipboardprint?<br />
Paint p=new Paint();&nbsp;&nbsp; <br />
&nbsp; LinearGradient lg=new LinearGradient(0,0,100,100,Color.RED,Color.BLUE,Shader.TileMode.MIRROR);&nbsp; //参数一为渐变起初点坐标x位置，参数二为y轴位置，参数三和四分辨对应渐变终点，最后参数为平铺方式，这里设置为镜像&nbsp; <br />
Paint p=new Paint();<br />
&nbsp; LinearGradient lg=new LinearGradient(0,0,100,100,Color.RED,Color.BLUE,Shader.TileMode.MIRROR);&nbsp; //参数一为渐变起初点坐标x位置，参数二为y轴位置，参数三和四分辨对应渐变终点，最后参数为平铺方式，这里设置为镜像 </p>
<p>刚才Android开发网已经讲到Gradient是基于Shader类，所以我们通过Paint的setShader方法来设置这个渐变，代码如下:</p>
<p>view plaincopy to clipboardprint?<br />
p.setShader(lg);&nbsp;&nbsp; <br />
&nbsp; canvas.drawCicle(0,0,200,p); //参数3为画圆的半径，类型为float型。&nbsp; <br />
p.setShader(lg);<br />
&nbsp; canvas.drawCicle(0,0,200,p); //参数3为画圆的半径，类型为float型。 </p>
<p>二、 RadialGradient镜像渐变 </p>
<p>&nbsp; 有了上面的基础，我们一起来了解下径向渐变。和上面参数唯一不同的是，径向渐变第三个参数是半径，其他的和线性渐变相同。</p>
<p>view plaincopy to clipboardprint?<br />
RadialGradient(float x, float y, float radius, int[] colors, float[] positions, Shader.TileMode tile)&nbsp;&nbsp;&nbsp; <br />
&nbsp; RadialGradient(float x, float y, float radius, int color0, int color1, Shader.TileMode tile)&nbsp;&nbsp; <br />
RadialGradient(float x, float y, float radius, int[] colors, float[] positions, Shader.TileMode tile) <br />
&nbsp; RadialGradient(float x, float y, float radius, int color0, int color1, Shader.TileMode tile)&nbsp; </p>
<p>三、 SweepGradient角度渐变 </p>
<p>&nbsp; 对于一些3D立体效果的渐变可以尝试用角度渐变来完成一个圆锥形，相对来说比上面更简单，前两个参数为中心点，然后通过载入的颜色来平均的渐变渲染。</p>
<p>view plaincopy to clipboardprint?<br />
SweepGradient(float cx, float cy, int[] colors, float[] positions)&nbsp; //对于最后一个参数SDK上的描述为May be NULL. The relative position of each corresponding color in the colors array, beginning with 0 and ending with 1.0. If the values are not monotonic, the drawing may produce unexpected results. If positions is NULL, then the colors are automatically spaced evenly.，所以Android123建议使用下面的重载方法，本方法一般为NULL即可。&nbsp;&nbsp; <br />
SweepGradient(float cx, float cy, int color0, int color1)&nbsp; </p>
<p><br />
本文来自CSDN博客，转载请标明出处：http://blog.csdn.net/JavaTiger427/archive/2010/11/25/6034673.aspx</p><img src ="http://www.blogjava.net/kissyan4916/aggbug/339698.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kissyan4916/" target="_blank">啥都写点</a> 2010-12-03 10:32 <a href="http://www.blogjava.net/kissyan4916/articles/339698.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Android游戏开发之旅（十六） 异步音乐播放</title><link>http://www.blogjava.net/kissyan4916/articles/339697.html</link><dc:creator>啥都写点</dc:creator><author>啥都写点</author><pubDate>Fri, 03 Dec 2010 02:29:00 GMT</pubDate><guid>http://www.blogjava.net/kissyan4916/articles/339697.html</guid><description><![CDATA[<p>在Android游戏开发中我们必须考虑背景音乐播放问题，在Android平台中提供了MediaPlayer类可以播放声音，但是游戏除了播放音乐外还需要考虑画面的流畅性，以及多种音效同时播放，所以必须用到Android多线程机制和异步音效播放。Android SDK从1.0开始就提供了AsyncPlayer类，这里我们为了根据我们自己的需要可以派生或修改出更灵活的播放类。</p>
<p>view plaincopy to clipboardprint?<br />
import android.content.Context;&nbsp;&nbsp; <br />
import android.net.Uri;&nbsp;&nbsp; <br />
import android.os.PowerManager;&nbsp;&nbsp; <br />
import android.os.SystemClock;&nbsp;&nbsp; <br />
import android.util.Log;&nbsp;&nbsp; <br />
import java.io.IOException;&nbsp;&nbsp; <br />
import java.lang.IllegalStateException;&nbsp;&nbsp; <br />
import java.util.LinkedList;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; <br />
public class AsyncPlayer {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; private static final int PLAY = 1;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; private static final int STOP = 2;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; private static final boolean mDebug = false;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; private static final class Command {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int code;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Context context;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Uri uri;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; boolean looping;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int stream;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; long requestTime;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public String toString() {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return "{ code=" + code + " looping=" + looping + " stream=" + stream&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + " uri=" + uri + " }";&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; private LinkedList&lt;Command&gt; mCmdQueue = new LinkedList();&nbsp; //用一个链表保存播放参数队列&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; private void startSound(Command cmd) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MediaPlayer player = new MediaPlayer();&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; player.setAudioStreamType(cmd.stream);&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; player.setDataSource(cmd.context, cmd.uri);&nbsp; //设置媒体源，这里Android123提示大家本类的public void play (Context context, Uri uri, boolean looping, int stream) 类第二个参数Uri为媒体位置。&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; player.setLooping(cmd.looping);&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; player.prepare();&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; player.start();&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (mPlayer != null) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mPlayer.release();&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mPlayer = player;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch (IOException e) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Log.w(mTag, "error loading sound for " + cmd.uri, e);&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (IllegalStateException e) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Log.w(mTag, "IllegalStateException (content provider died?) " + cmd.uri, e);&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; private final class Thread extends java.lang.Thread {&nbsp;&nbsp; //通过多线程方式不阻塞调用者&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thread() {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super("AsyncPlayer-" + mTag);&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void run() {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (true) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Command cmd = null;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; synchronized (mCmdQueue) {&nbsp;&nbsp; //同步方式执行&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd = mCmdQueue.removeFirst();&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; switch (cmd.code) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case PLAY:&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; startSound(cmd);&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case STOP:&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (mPlayer != null) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mPlayer.stop();&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mPlayer.release();&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mPlayer = null;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Log.w(mTag, "STOP command without a player");&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; synchronized (mCmdQueue) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (mCmdQueue.size() == 0) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mThread = null;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; releaseWakeLock();&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; private String mTag;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; private Thread mThread;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; private MediaPlayer mPlayer;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; private PowerManager.WakeLock mWakeLock;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; private int mState = STOP;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; public AsyncPlayer(String tag) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (tag != null) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mTag = tag;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mTag = "AsyncPlayer";&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; public void play(Context context, Uri uri, boolean looping, int stream) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Command cmd = new Command();&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.requestTime = SystemClock.uptimeMillis(); //这里为了测试性能，传递了开始执行前的系统tickcount计时器值&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.code = PLAY;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.context = context;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.uri = uri;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.looping = looping;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.stream = stream;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; synchronized (mCmdQueue) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; enqueueLocked(cmd);&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mState = PLAY;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; public void stop() {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; synchronized (mCmdQueue) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (mState != STOP) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Command cmd = new Command();&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.requestTime = SystemClock.uptimeMillis();&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.code = STOP;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; enqueueLocked(cmd);&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mState = STOP;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; private void enqueueLocked(Command cmd) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mCmdQueue.add(cmd);&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (mThread == null) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; acquireWakeLock();&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mThread = new Thread();&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mThread.start();&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }&nbsp; <br />
import android.content.Context;<br />
import android.net.Uri;<br />
import android.os.PowerManager;<br />
import android.os.SystemClock;<br />
import android.util.Log;<br />
import java.io.IOException;<br />
import java.lang.IllegalStateException;<br />
import java.util.LinkedList;<br />
&nbsp;<br />
public class AsyncPlayer {<br />
&nbsp;&nbsp;&nbsp; private static final int PLAY = 1;<br />
&nbsp;&nbsp;&nbsp; private static final int STOP = 2;<br />
&nbsp;&nbsp;&nbsp; private static final boolean mDebug = false;<br />
&nbsp;&nbsp;&nbsp; private static final class Command {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int code;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Context context;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Uri uri;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; boolean looping;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int stream;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; long requestTime;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public String toString() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return "{ code=" + code + " looping=" + looping + " stream=" + stream<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + " uri=" + uri + " }";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; private LinkedList&lt;Command&gt; mCmdQueue = new LinkedList();&nbsp; //用一个链表保存播放参数队列<br />
&nbsp;&nbsp;&nbsp; private void startSound(Command cmd) {<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MediaPlayer player = new MediaPlayer();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; player.setAudioStreamType(cmd.stream);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; player.setDataSource(cmd.context, cmd.uri);&nbsp; //设置媒体源，这里Android123提示大家本类的public void play (Context context, Uri uri, boolean looping, int stream) 类第二个参数Uri为媒体位置。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; player.setLooping(cmd.looping);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; player.prepare();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; player.start();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (mPlayer != null) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mPlayer.release();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mPlayer = player;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch (IOException e) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Log.w(mTag, "error loading sound for " + cmd.uri, e);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (IllegalStateException e) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Log.w(mTag, "IllegalStateException (content provider died?) " + cmd.uri, e);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; private final class Thread extends java.lang.Thread {&nbsp;&nbsp; //通过多线程方式不阻塞调用者<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thread() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super("AsyncPlayer-" + mTag);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void run() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (true) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Command cmd = null;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; synchronized (mCmdQueue) {&nbsp;&nbsp; //同步方式执行<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd = mCmdQueue.removeFirst();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; switch (cmd.code) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case PLAY:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; startSound(cmd);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case STOP:<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (mPlayer != null) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mPlayer.stop();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mPlayer.release();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mPlayer = null;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Log.w(mTag, "STOP command without a player");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; synchronized (mCmdQueue) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (mCmdQueue.size() == 0) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mThread = null;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; releaseWakeLock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; private String mTag;<br />
&nbsp;&nbsp;&nbsp; private Thread mThread;<br />
&nbsp;&nbsp;&nbsp; private MediaPlayer mPlayer;<br />
&nbsp;&nbsp;&nbsp; private PowerManager.WakeLock mWakeLock;<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp; private int mState = STOP;<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp; public AsyncPlayer(String tag) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (tag != null) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mTag = tag;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mTag = "AsyncPlayer";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp; public void play(Context context, Uri uri, boolean looping, int stream) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Command cmd = new Command();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.requestTime = SystemClock.uptimeMillis(); //这里为了测试性能，传递了开始执行前的系统tickcount计时器值<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.code = PLAY;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.context = context;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.uri = uri;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.looping = looping;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.stream = stream;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; synchronized (mCmdQueue) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; enqueueLocked(cmd);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mState = PLAY;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp; <br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp; public void stop() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; synchronized (mCmdQueue) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (mState != STOP) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Command cmd = new Command();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.requestTime = SystemClock.uptimeMillis();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.code = STOP;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; enqueueLocked(cmd);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mState = STOP;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; private void enqueueLocked(Command cmd) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mCmdQueue.add(cmd);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (mThread == null) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; acquireWakeLock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mThread = new Thread();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mThread.start();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; } </p>
<p>一般对于Android游戏而言下面的代码不用考虑，一般用户都在交互操作，不会出现屏幕锁问题</p>
<p>view plaincopy to clipboardprint?<br />
public void setUsesWakeLock(Context context) {&nbsp; //电源管理wakelock处理&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (mWakeLock != null || mThread != null) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new RuntimeException("assertion failed mWakeLock=" + mWakeLock&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + " mThread=" + mThread);&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, mTag);&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; private void acquireWakeLock() {&nbsp;&nbsp; //加锁&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (mWakeLock != null) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mWakeLock.acquire();&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; private void releaseWakeLock() { //解锁&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (mWakeLock != null) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mWakeLock.release();&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
}&nbsp; </p>
<p>&nbsp;</p>
<p>本文来自CSDN博客，转载请标明出处：http://blog.csdn.net/JavaTiger427/archive/2010/11/25/6034662.aspx</p><img src ="http://www.blogjava.net/kissyan4916/aggbug/339697.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kissyan4916/" target="_blank">啥都写点</a> 2010-12-03 10:29 <a href="http://www.blogjava.net/kissyan4916/articles/339697.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> Android游戏开发之旅（十四） 游戏开发实战一</title><link>http://www.blogjava.net/kissyan4916/articles/339695.html</link><dc:creator>啥都写点</dc:creator><author>啥都写点</author><pubDate>Fri, 03 Dec 2010 02:28:00 GMT</pubDate><guid>http://www.blogjava.net/kissyan4916/articles/339695.html</guid><description><![CDATA[<p>从今天开始Android123将开始带领大家进入Android游戏开发实战篇，本次我们首个游戏为2D的基于SurfaceView的类似横版卷轴游戏。第一天我们说下需要做哪些准备: </p>
<p>&nbsp; 一、游戏地图编辑器，在J2ME时代我们可能都是用GIF分割多帧或BMP上放置多个图片通过减少文件头来压缩体积，但是在Android平台上开发游戏我们不需要那么节省，不过资源的释放仍然很重要，否则会出现OutOfMemoryError这样的悲剧发生。一般简单的2D平面游戏地图都是使用二维数组来标记的。我们可以想象矩阵中的每个元素对应每个图片资源。详细的存储方法我们将在下次具体讲到。</p>
<p>&nbsp; 二、控制方式，由于横版过关类游戏不适合重力感应操作，我们这里选择屏幕下方加设一个区域，放置上、下、左、右按键，同时右侧给出常用的攻击、跳跃按钮，而游戏的暂停可以通过触控实现继续或暂停。</p>
<p>&nbsp; 三、音效处理，常规的一般在攻击比如出拳、发射子弹的过程中有音效，或对手自己中弹（当然对于Android图形开发来说就是碰撞检测）时发出音效，跳跃、过关均会需要一些声音素材文件，一般的游戏还需要背景音乐配合烘托游戏气氛。</p>
<p>&nbsp; 四、游戏逻辑，这是主要的地方，我们将通过实例代码让大家了解游戏开发中是如何的卷轴、人物的跳跃、攻击有效判断即碰撞检测，电脑智能等算法问题。</p>
<p>&nbsp; 五、细节处理，比如计分，等级，游戏计时，关卡档案的存档，读取以及开场设计，关卡过渡的过场动画处理。</p>
<p>&nbsp; 这里Android开发网提示大家，目前很多J2ME的游戏可以轻松的移植到Android平台，主要的细节只要了解Google Android平台的图形相关问题即可，主要是Bitmap、Drawable和View线程处理问题。</p>
<p>&nbsp;</p>
<p>本文来自CSDN博客，转载请标明出处：http://blog.csdn.net/JavaTiger427/archive/2010/11/25/6034645.aspx</p><img src ="http://www.blogjava.net/kissyan4916/aggbug/339695.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kissyan4916/" target="_blank">啥都写点</a> 2010-12-03 10:28 <a href="http://www.blogjava.net/kissyan4916/articles/339695.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Android游戏开发之旅（十五） 按键中断处理</title><link>http://www.blogjava.net/kissyan4916/articles/339696.html</link><dc:creator>啥都写点</dc:creator><author>啥都写点</author><pubDate>Fri, 03 Dec 2010 02:28:00 GMT</pubDate><guid>http://www.blogjava.net/kissyan4916/articles/339696.html</guid><description><![CDATA[<p>有关Android平台上游戏开发中我们需要处理一些特别的按键事件，对于突发的事情我们需要特别的考虑，比如突然来电话了和游戏中按下一些特殊的键，比如拍照键</p>
<p>view plaincopy to clipboardprint?<br />
@Override&nbsp; <br />
&nbsp;&nbsp;&nbsp; public boolean dispatchKeyEvent(KeyEvent event)&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; switch (event.getKeyCode())&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case KeyEvent.KEYCODE_VOLUME_UP:&nbsp;&nbsp; //音量键+&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case KeyEvent.KEYCODE_VOLUME_DOWN:&nbsp;&nbsp; //音量键-&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case KeyEvent.KEYCODE_CAMERA:&nbsp; //拍照键&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case KeyEvent.KEYCODE_FOCUS:&nbsp;&nbsp; //拍照键半按的对焦状态&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp; event.getAction() == KeyEvent.ACTION_UP&nbsp;&nbsp; //Android123提示如果按键按下后弹起时触发&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return true; //这些标记为处理过，则不在往内部传递&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; default:&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return super.dispatchKeyEvent(event);&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }&nbsp; <br />
@Override<br />
&nbsp;&nbsp;&nbsp; public boolean dispatchKeyEvent(KeyEvent event)<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; switch (event.getKeyCode())<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case KeyEvent.KEYCODE_VOLUME_UP:&nbsp;&nbsp; //音量键+<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case KeyEvent.KEYCODE_VOLUME_DOWN:&nbsp;&nbsp; //音量键-<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case KeyEvent.KEYCODE_CAMERA:&nbsp; //拍照键<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case KeyEvent.KEYCODE_FOCUS:&nbsp;&nbsp; //拍照键半按的对焦状态<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp; event.getAction() == KeyEvent.ACTION_UP&nbsp;&nbsp; //Android123提示如果按键按下后弹起时触发<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return true; //这些标记为处理过，则不在往内部传递<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; default:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return super.dispatchKeyEvent(event);<br />
&nbsp;&nbsp;&nbsp; } </p>
<p>对于游戏突然来电话我们一般采取通过PhoneStateListener类提供的public void onCallStateChanged (int state, String incomingNumber) 回调方法可以获取电话的状态，比如常规空闲时CALL_STATE_IDLE、来电时<br />
CALL_STATE_RINGING和 CALL_STATE_OFFHOOK 摘机通话中，有关处理的细节网友可以查看Android Git项目中的Music，在Android开源项目中系统自带的音乐播放器可以很好的处理，比如在通话结束后恢复音乐播放，而我们游戏需要做的就是记住当前的游戏状态尽量数据持久化处理，不能因为长时间的通话，游戏的Activity被清理了，这里我们一般通过onSaveInstanceState来保存当前窗口的一些记录，通过Intent标记来让系统管理好我们游戏的生命周期。</p>
<p>&nbsp;</p>
<p>本文来自CSDN博客，转载请标明出处：http://blog.csdn.net/JavaTiger427/archive/2010/11/25/6034653.aspx</p><img src ="http://www.blogjava.net/kissyan4916/aggbug/339696.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kissyan4916/" target="_blank">啥都写点</a> 2010-12-03 10:28 <a href="http://www.blogjava.net/kissyan4916/articles/339696.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Android游戏开发之旅（十二）Sensor重力感应（2）</title><link>http://www.blogjava.net/kissyan4916/articles/339694.html</link><dc:creator>啥都写点</dc:creator><author>啥都写点</author><pubDate>Fri, 03 Dec 2010 02:27:00 GMT</pubDate><guid>http://www.blogjava.net/kissyan4916/articles/339694.html</guid><description><![CDATA[<p>有关Android游戏开发中的Sensor感应示例今天我们将一起来讨论，对于目前最新的Android 2.2平台 而言仍然没有具体的感应判断逻辑，下面我们一起定义 下常用的感应动作事件。首先Android123提醒大家由于是三轴的立体空间感应所以相对于轨迹球、导航键的上下左右外，还提供了前后的感应，所以我们定义最基本的六种空间方向。 </p>
<p>view plaincopy to clipboardprint?<br />
public static final int CWJ_UP = 0;&nbsp;&nbsp; <br />
public static final int CWJ_DOWN = 1;&nbsp;&nbsp; <br />
public static final int CWJ_LEFT = 2;&nbsp;&nbsp; <br />
public static final int CWJ_RIGHT = 4;&nbsp;&nbsp; <br />
public static final int CWJ_FORWARD = 8; //向前&nbsp;&nbsp; <br />
public static final int CWJ_BACKWARD = 16; //向后&nbsp; <br />
public static final int CWJ_UP = 0;<br />
public static final int CWJ_DOWN = 1;<br />
public static final int CWJ_LEFT = 2;<br />
public static final int CWJ_RIGHT = 4;<br />
public static final int CWJ_FORWARD = 8; //向前<br />
public static final int CWJ_BACKWARD = 16; //向后 </p>
<p>下面我们做精确的角度旋转修正值定义，我们用到yaw、pitch和roll，相信学过3D开发的网友不会对这些陌生的，我们就把他们对应为绕y、x、z 轴的角度好了，如果你们没有学过3D相关的知识这里Android开发网推荐大家可以通过Cube例子 自定义Render来观察这三个值对应立方体的旋转角度。<br />
Yaw在(0,0,0)中， 以xOz的坐标平面中围绕y轴旋转，如果是负角则我们定义为CWJ_YAW_LEFT 即往左边倾斜，同理我们定义如下: </p>
<p>view plaincopy to clipboardprint?<br />
public static final int CWJ_YAW_LEFT = 0;&nbsp;&nbsp; <br />
public static final int CWJ_YAW_RIGHT = 1;&nbsp;&nbsp; <br />
public static final int CWJ_PITCH_UP = 2;&nbsp;&nbsp; <br />
public static final int CWJ_PITCH_DOWN = 4;&nbsp;&nbsp; <br />
public static final int CWJ_ROLL_LEFT = 8;&nbsp;&nbsp; <br />
public static final int CWJ_ROLL_RIGHT = 16;&nbsp; <br />
public static final int CWJ_YAW_LEFT = 0;<br />
public static final int CWJ_YAW_RIGHT = 1;<br />
public static final int CWJ_PITCH_UP = 2;<br />
public static final int CWJ_PITCH_DOWN = 4;<br />
public static final int CWJ_ROLL_LEFT = 8;<br />
public static final int CWJ_ROLL_RIGHT = 16; </p>
<p>我们通过加速感应器可以获得SensorEvent的四个值，今天Android123给大家一个简单示例，不考虑其他因素，在public int accuracy 、public Sensor sensor 、public long timestamp&nbsp; 和&nbsp; public final float[] values 中，我们获取values的浮点数组来判断方向。</p>
<p>view plaincopy to clipboardprint?<br />
int nAndroid123=CWJ_UP //向上&nbsp;&nbsp; <br />
float ax = values[0];&nbsp;&nbsp; <br />
float ay = values[1];&nbsp;&nbsp; <br />
float az = values[2];&nbsp;&nbsp; <br />
&nbsp; <br />
float absx = Math.abs(ax);&nbsp;&nbsp; <br />
float absy = Math.abs(ay);&nbsp;&nbsp; <br />
float absz = Math.abs(az);&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp; <br />
if (absx &gt; absy &amp;&amp; absx &gt; absz) {&nbsp;&nbsp; <br />
if (ax &gt; 0) {&nbsp;&nbsp; <br />
&nbsp; nAndroid123 = CWJ_RIGHT;&nbsp;&nbsp; <br />
} else {&nbsp;&nbsp; <br />
&nbsp; nAndroid123 = CWJ_LEFT;&nbsp;&nbsp; <br />
}&nbsp;&nbsp; <br />
} else if (absy &gt; absx &amp;&amp; absy &gt; absz) {&nbsp;&nbsp; <br />
&nbsp; <br />
if (ay &gt; 0) {&nbsp;&nbsp; <br />
nAndroid123= CWJ_FORWARD;&nbsp;&nbsp; <br />
} else {&nbsp;&nbsp; <br />
nAndroid123= CWJ_BACKWARD;&nbsp;&nbsp; <br />
}&nbsp;&nbsp; <br />
} else if (absz &gt; absx &amp;&amp; absz &gt; absy) {&nbsp;&nbsp; <br />
if (az &gt; 0) {&nbsp;&nbsp; <br />
&nbsp; nAndroid123 = CWJ_UP;&nbsp;&nbsp; <br />
} else {&nbsp;&nbsp; <br />
&nbsp; nAndroid123 = CWJ_DOWN;&nbsp;&nbsp; <br />
}&nbsp;&nbsp; <br />
} else {&nbsp;&nbsp; <br />
nAndroid123 = CWJ_UNKNOWN;&nbsp;&nbsp; <br />
}&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int nAndroid123=CWJ_UP //向上<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; float ax = values[0];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; float ay = values[1];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; float az = values[2];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; float absx = Math.abs(ax);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; float absy = Math.abs(ay);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; float absz = Math.abs(az);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (absx &gt; absy &amp;&amp; absx &gt; absz) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (ax &gt; 0) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nAndroid123 = CWJ_RIGHT;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nAndroid123 = CWJ_LEFT;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if (absy &gt; absx &amp;&amp; absy &gt; absz) {<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (ay &gt; 0) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nAndroid123= CWJ_FORWARD;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nAndroid123= CWJ_BACKWARD;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if (absz &gt; absx &amp;&amp; absz &gt; absy) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (az &gt; 0) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nAndroid123 = CWJ_UP;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nAndroid123 = CWJ_DOWN;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nAndroid123 = CWJ_UNKNOWN;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </p>
<p>有关偏向角度问题，我们将在下一次详细讲述，对于一般的2D游戏，我们可以参考本文来实现重力控制，所以总体来说Android游戏开发比较简单易懂，Android平台使用的Java 语言还是很适合做游戏的。在逻辑表达上更清晰。</p>
<p>&nbsp;</p>
<p>本文来自CSDN博客，转载请标明出处：http://blog.csdn.net/JavaTiger427/archive/2010/11/25/6034640.aspx</p><img src ="http://www.blogjava.net/kissyan4916/aggbug/339694.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kissyan4916/" target="_blank">啥都写点</a> 2010-12-03 10:27 <a href="http://www.blogjava.net/kissyan4916/articles/339694.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>