編輯:Android開發實例
先上一段代碼大家來看一下:
- package com.himi;
- import android.app.Activity;
- import android.os.Bundle;
- import android.util.Log;
- import android.view.MotionEvent;
- import android.view.Window;
- import android.view.WindowManager;
- /**
- * @author Himi
- */
- public class MainActivity extends Activity {
- private Object object;
- private final int TIME = 50;//備注1
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
- this.requestWindowFeature(Window.FEATURE_NO_TITLE);
- setContentView(R.layout.main);
- object = new Object();
- }
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- if (event.getAction() == MotionEvent.ACTION_DOWN) {
- Log.v("Himi", "ACTION_DOWN");
- } else if (event.getAction() == MotionEvent.ACTION_UP) {
- Log.v("Himi", "ACTION_UP");
- } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
- Log.v("Himi", "ACTION_MOVE");
- }
- synchronized (object) {//備注2
- try {
- object.wait(TIME);
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- return true;//這裡一定要返回true!原因請看【Android2D游戲開發之九】
- }
- }
代碼很清晰呵呵,主要就是備注2的地方:
一: 前言:
各位童鞋肯定都知道在模擬器中,我們的鼠標當點擊一次模擬器屏幕然後釋放,先觸發 ACTION_DOWN 然後 ACTION_UP ;如果是在屏幕上移動那麼才會觸發 ACTION_MOVE 的動作;OK,很對。但是你要知道,這只是模擬器!!!!!
二:真機與模擬器的區別:
當我們的小用戶(說到用戶我就想起“我叫MT”中的暗夜男那句經典台詞:親愛的客戶,我是嫩爹!)咳咳,回到話題;當我們的用戶在玩我們的游戲的時候,尤其是RPG這種類型的,用戶肯定需要會長時間的去觸屏按我們的虛擬按鍵,比如我們會在屏幕上畫上一個虛擬方向盤類似這樣子~那麼其實 ACTION_MOVE 這個事件會被Android一直在響應!!
三: 為什麼會一直響應 ACTION_MOVE 這個動作呢? 如果用戶沒有移動手指而是靜止不動也會一直響應?
原因有兩點:第一點是因為,Android 對於觸屏事件很敏感!第二點:雖然我們的手指感覺是靜止沒有移動,其實事實不是如此!當我們的手指觸摸到手機屏幕上之後,感覺靜止沒動,其實手指在不停的微顫抖震動。不信你試試靜止下手指,是不是微微動?嘿嘿~
so~ 我們就要分析了,如果ACTION_MOVE此時間一直被Android os 一直不停的響應並處理,無疑對我們游戲的性能增加了不少的負擔!
比如我們游戲線程繪圖時間每次用了100ms,那麼當手指觸摸屏幕,這短暫的0.1秒內大概會產生10個左右的MotionEvent ,並且系統會盡可能快的把這些event發給監聽線程, 這樣的話在這一段時間內cpu就會忙於處理onTouchEvent從而杯具點的話會造成畫面一卡一卡的。
那麼我們其實根本用不著按鍵響應這麼多次,而是需要在我們每次繪圖後,或者繪圖前接受一次用戶按鍵就OK了,這樣能讓幀率不至於下降的太厲害不是麼?!so~我們要控制這個時間,讓他慢下來,隨著我們的繪圖時間一起來合作~這樣就能減不少系統線程的負擔。
備注2:
可能有的童鞋會問為什麼不用sleep()的方法,其實如果我們只是想讓線程休眠指定時間的話可以用sleep()函數,但是這個沒有資源鎖的限制。而Object的wait,notify方法通常用在時間不定的條件限制等待,並且必須寫在同步代碼塊中。so~
還有童鞋會問,為什麼不用當前類的object來使用:this.wait(),而是new 一個object來:
synchronized 中的Object 表示Object 調用wait必須擁有該對象的監視鎖,當前我們有了object的鎖,就要用object調用wait~
備注1:
這裡的變量大家都知道其實是我們設置的休眠的時間,那麼這裡我想拿出來跟大家說下關於這個時間的定值,在上文我也有說過我們的游戲中只要按鍵跟我們的繪圖線程的時間一樣即可,當然這裡是個我們的理想時間!如果我們游戲中有人物的幀,那麼我們可以來根據人物幀數來當成設定這個睡眠時間也是相當合適的,畢竟人物一幀說明邏輯執行了一遍了呵呵~這個還是根據大家游戲的情況而定吧~
注意:Object.wait(long timeout)這個方法也需要慎用!
原因是因為測試發現:這個睡眠的時間其實比你規定的時間要略微的長一些,不過我們合理控制好時間還是沒問題的。
補充:
1.看到有童鞋問//備注2這裡能不能用this,也就是當前的object,答案是可以的,但是要注意最好不要這樣用,原因是如果當其他地方也需要與當前的Object進行同步的話有可能出現死鎖情況!用一個新的object的原因也就是可以讓代碼中該干什麼就干什麼,互不影響,
2.//備注2這裡其實我們可以對其優化,畢竟一個Object比較浪費,我們其實只需要一個字節就足夠了,so~我們可以這樣定義一個:byte[] lock = new byte[0]; 這樣可以算是最優了~
本文實例講述了Android實現ListView異步加載圖片的方法。分享給大家供大家參考。具體如下: ListView異步加載圖片是非常實用的方法,凡是是要通過網
JSON代表JavaScript對象符號。它是一個獨立的數據交換格式,是XML的最佳替代品。本章介紹了如何解析JSON文件,並從中提取所需的信息。Android提供了四個
JSON代表JavaScript對象符號。它是一個獨立的數據交換格式,是XML的最佳替代品。本章介紹了如何解析JSON文件,並從中提取所需的信息。Android提供了四個
可以輕松地控制鈴聲音量和鈴聲配置文件,即:(無聲,震動,響亮等)在Android中。 Android提供了訪問這些控件AudioManager類。