Android開發的基礎常識二之程序解讀

前言:雖然寫android開發時間也有半年之久,但是對於用java開發出自己的代碼還是比較薄弱,因為自己都是看例程已有的代碼或者看視頻中按部就班來運行,更註重的是結果。所以想就一篇例程來詳細註釋每一行代碼的意思,瞭解android編程的特點,同時對於Java面向對象的特點展示出來,就有瞭此片文章,所以面對的讀者都是基礎學者,希望一起學習,一起進步,歡迎評論。

本文建立在獲取手勢的例程上:

1、src目錄下的.java文件是完成事務,也就是自己編寫的主要代碼,其內容如下:

package com.example.gesturetest; //建立工程時,新建立的包文件,分別有com、example、gesturetest三個子文件夾,指出這個檔桉所在的名稱空間

import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.Button;
//程序中預設導入瞭 “android.app.Activity”跟”android.os.Bundle”兩個
Package,在所有的 Android 應用程序中都會用到這兩個 Package。”import”(導入)是用作導入Package
的關鍵字。在 Java 語言中,使用到任何 API 前都要事先導入相對應的 Package。我們馬上將學到這兩個 Package 的用途。Android
支援的 Package 與標準的 Java(j2se) 不盡相同。在寫 Android 應用程序時,你偶而可能需要參考可用的 API 列表,以確認使用到的 Package 是否有內建支援。後續章節中也將講解如何透過新增”jar”檔來呼叫額外的
Package。完整的 API 可查閱官方的 package 列表:https://code.google.com/android/reference/packages.html

public class Gesture extends Activity

//第 6 行開始瞭程序的主體。其組成是這樣的:代碼:public
class Gesture”Gesture”是這個類別的名稱。”class”則是用作宣告類別關鍵字。”private”關鍵字是用來修飾”Gesture”這個類別。表示”Gesture”是個”私有”的類別,不可以從
package 外部取用。”public class Gesture”後面再加上”extends Activity”敘述,則表示 “Gesture”這個類別的功能、型別等全繼承自”Activity”類別。”extends”是繼承(Inherit)類別的關鍵字。”Activity”是
來自於我們在第 3 行剛導入的 Package。因此整句話的含意即:”宣告一個私有的 Gesture 類別。這個 Gesture 類別繼承瞭程序開頭導入的 Activity 類別”。”{}”大括號規范瞭一個程序區塊。大括號中的程序表達的這個程序區塊的主要內容。

{

private Button mButton; //private定義瞭私有的成員變量,Button是繼承類下來的關鍵字,所以重新定義瞭一個Button按鈕的變量

private GestureDetector mGestureDetector; //同上,定義瞭一個新的手勢檢測的新成員變量。

@Override

//表示重寫父類函數的方法
protected void onCreate(Bundle savedInstanceState)

// “onCreate”是這個方法的名稱。”void”則是宣告瞭這個方法的回傳值的型別(type)。”public”關鍵字是用來修飾”onCreate”這個方法。表示”onCreate”是個”公開”的方法,可以由
bmi 類別外部取用。方法的回傳值的型別,即是這個方法的型別。”onCreate”這個方法使用”void”型別,表示
“onCreate”這個方法不需回傳值。同時,這個方法傳入瞭一個名為”savedInstanceState”的”Bundle”型別參數,”Bundle”型別正是來自我們前面所導入的
Package 之一。我們並不需要知道太多”Bundle”型別或”savedInstanceState”實體的細節,隻要知道”Bundle”的內容與手機平臺的記
憶體管理有關(Bundle一般用於攜帶數據、數據傳送)。當 Android 應用程序啟動、換到背景等待、關閉時,都會用到 “savedInstanceState”這個實體來處理記憶體相關的事宜。當然,你也可以用其他名稱來代替它。還好”onCreate”這個方法永遠都
是傳入”Bundle savedInstanceState”這個參數,寫應用程序時隻要正確照規定傳入即可,你可以不用太去在意它。給對 Bundle 是什麼有興趣的讀者:”Bundle”可以保存程序上一次關閉(凍結)時的狀態。你可以透過覆寫
onFreeze 方法(與onCreate 方法的作用類似) 來保存凍結前的狀態。 當程序啟動(Activity 重新初始化)時,會再次呼叫 onCreate 方法,你就能從 savedInstanceState
中得到前一次凍結的狀態。我們也可以透過”Bundle”來將這個 Activity 的內容傳到下一個 Activity 中。 之後講Activity 時,也會講解 onCreate/onFreeze 等方法的關系。

{

super.onCreate(savedInstanceState);

//”super”是關鍵字。代表著這個 “Bmi”類別的上層類別(Activity)。”super.onCreate(savedInstanceState);”的意思就是:”執行 Activity 類別中 onCreate
方法的內容”。這麼做的目的是什麼呢?Google Android 將其應用程序的界面稱為視圖 (View),而負責控制各種動作行為的程序主體(Controller),則稱為活動(Activity)。因此一個
Android 應用程序,必定會對應到一個以上的 Activity。 “onCreate” 方法則是每個 Activity 類別初始化時都會去呼叫
的方法。我們想做的事,是保持原本”onCreate” 方法預設的動作,然後在其中加入我們想要的內容。而 Android
產生的程序預設卻覆載(@Override)瞭”Bmi” 類別的”onCreate” 方法。原本繼承自”Activity”類別的”onCreate”方法,其原本內容都被覆載掉瞭。因此想將原本的”onCreate”方法內容保留,並在
其中加入我們的內容的話,就要使用”super”語句。當程序運行到我們覆寫的”onCreate”方法時,透
過”super.onCreate(savedInstanceState);”語句,會先將
原本”Activity”類別中的”onCreate”方法 執行一次,然後再執行我們覆寫的”onCreate”方法裡面其他的程序內容。我們要執行原本的”onCreate”方法時,仍然需要提 供原本”onCreate”方法所需的傳入參數。因此”super.onCreate(savedInstanceState);”語句中,我們
將”savedInstanceState”這個參數傳入原本的”onCreate”函式中。”savedInstanceState”是我們 在”public void onCreate(BundlesavedInstanceState)”語句中所宣告的傳入參數。

setContentView(R.layout.activity_gesture);

//透過螢幕顯示的各種元素是按照界面層次結構來描述的。要將一個顯示元素的層次結構轉換顯示到一個螢幕上,Activity
會呼叫它用來設定 View 的 “setContentView” 方法,並傳入想引用的 XML 描述文件。當 Activity 被啟動並需要顯示到螢幕上時,系統會通知Activity,並根據引用的 XML
文件敘述來描繪出使用者界面。上一章中我們定義好的res/layout/main.xml 描述檔,就是透過這個機制繪出到螢幕上。setContentView 方法也可以在 Activity 類別中找到。你可能也註意到
“setContentView” 方法確實是透過 “R.layout.main”來引用 XML 文件描述檔的資源,而不是直接透過 res 目錄來引用。

mGestureDetector = new GestureDetector(this, new MyOnGestureListener());

//新建一個GestureDetector類型的mGestureDetector和MyOnGestureListener()

mButton = (Button) findViewById(R.id.btn_textgesture);

//通過findViewById方法來獲取來自.xml中的Button按鈕mButton
mButton.setOnTouchListener(new OnTouchListener() //為按鈕添加觸摸監聽器

{

@Override
public boolean onTouch(View v, MotionEvent event) {
Log.i(getClass().getName(), “onTouch—–” + getActionName(event.getAction()));

//使用包中的log函數來查看輸出
mGestureDetector.onTouchEvent(event);

//同時也綁定手勢檢測的監聽器
// 一定要返回true,不然獲取不到完整的事件
return true;
}
});

}
//自定義獲取名稱的成員函數
private String getActionName(int action)
{
String name = “”;
switch (action) {
case MotionEvent.ACTION_DOWN: {
name = “ACTION_DOWN”;
break;
}
case MotionEvent.ACTION_MOVE: {
name = “ACTION_MOVE”;
break;
}
case MotionEvent.ACTION_UP: {
name = “ACTION_UP”;
break;
}
default:
break;
}
return name;
}

class MyOnGestureListener extends SimpleOnGestureListener implements OnGestureListener {
@Override
public boolean onSingleTapUp(MotionEvent e) {
Log.i(getClass().getName(), “onSingleTapUp—–” + getActionName(e.getAction()));
return false;
}
//復寫類MyOnGestureListener中的函數,利用log輸出查看所檢測到的手勢
@Override
public void onLongPress(MotionEvent e) {
Log.i(getClass().getName(), “onLongPress—–” + getActionName(e.getAction()));
}

@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
Log.i(getClass().getName(),
“onScroll—–” + getActionName(e2.getAction()) + “,(” + e1.getX() + “,” + e1.getY() + “) ,(“
+ e2.getX() + “,” + e2.getY() + “)”);
return false;
}

@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
Log.i(getClass().getName(),
“onFling—–” + getActionName(e2.getAction()) + “,(” + e1.getX() + “,” + e1.getY() + “) ,(“
+ e2.getX() + “,” + e2.getY() + “)”);
return false;
}

@Override
public void onShowPress(MotionEvent e) {
Log.i(getClass().getName(), “onShowPress—–” + getActionName(e.getAction()));
}

@Override
public boolean onDown(MotionEvent e) {
Log.i(getClass().getName(), “onDown—–” + getActionName(e.getAction()));
return false;
}

@Override
public boolean onDoubleTap(MotionEvent e) {
Log.i(getClass().getName(), “onDoubleTap—–” + getActionName(e.getAction()));
return false;
}

@Override
public boolean onDoubleTapEvent(MotionEvent e) {
Log.i(getClass().getName(), “onDoubleTapEvent—–” + getActionName(e.getAction()));
return false;
}

@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
Log.i(getClass().getName(), “onSingleTapConfirmed—–” + getActionName(e.getAction()));
return false;
}

}

}

發佈留言