【Android開發筆記】3.編寫第一個Android程序


前言

上一節我們通過一個Demo熟悉了Eclipse的基本使用、如何在模擬器和手機中運行以及如何打包成APK,但沒具體編寫代碼,相信很多同學已經按耐不住了吧,這一節我們會動手編寫代碼來熟悉Android SDK的情況和JAVA的一些特性。

聲明

本系列文章不是教程,僅為筆記,如有不當之處請指正。

歡迎轉載,轉載請保留原出處:http://www.cnblogs.com/rayee

正文

我們先了解一下編寫程序都要涉及到哪些東西,熟悉一下SDK的基本組件,然后編寫一個很簡單的小程序。

一、分析Demo

在上一節建立的工程Demo下,打開src/com.android.demo下的DemoActivity.java,如下所示:

image

Demo程序的代碼就只有13行,我們依次來分析一下:

package com.android.demo;	/** 申明這個文件的代碼屬於包“com.android.demo” */

import android.app.Activity;/** 從Android SDK中引用Activity組件 */
import android.os.Bundle;	/** 從Android SDK中引用Bundle組件 */

public class DemoActivity extends Activity {	/** 新建類DemoActivity,繼承Activity,它就擁有Activity的特性了  */
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {	/** 重寫基類的同名函數,程序運行候創建Activity時被調用 */
        super.onCreate(savedInstanceState);		/** 調用基類的同名函數 */
        setContentView(R.layout.main);			/** 設置試圖,用於顯示界面 */
    }
}

第1行,聲明代碼屬於哪個包,這里的包名得與文件所在的包對應上,否則會報錯。

第3、4行,引用組件。這里的“引用”並不像其他語言的include那樣將文件包含進來,只是告訴編譯器,后面會使用到這里面的成員。

關於Package 與 Import的詳細說明,>>請到這里查看

第6行,新建一個類DemoActivity,繼承Activity。JAVA是一門完全面向對象的語言,所有東西都要封裝在類里面,之前不熟悉面向對象的朋友估計會很不習慣(話說我之前用PHP做WEB開發,哪里都能寫實現…)。DemoActivity類繼承了Activity的特性,就屬於一個“Activity”了(前面提過,Activity是Android中的基本組件之前,非常之基礎,任何有界面的程序都有它)。

想深入了解“面向對象”的同學,>>請到這里查看

第9行,重載onCreate函數。有編程經驗的同學看到on前綴就知道這個函數是個回調函數,屬於小受受,只能“被”,它在Activity這個界面開始創建時被調用。

第10行,調用基類的同名函數。基類還有些事情要處理呢,得通知他。

第11行,指定用哪個視圖來顯示界面。從字面上可以看到setContentView(R.layout.main),采用R.layout.main作為試圖,那么R.layout.main代表什么?我們要修改的話從哪里下手呢呢?

我們在上一節介紹工程文件的時候介紹過一個由IDE自動維護的文件夾gen,里面有個R.java文件,有同學可能明白了,這里就是引用里面的內容,如下所示:

image

R.layout.main就是R.layout類里面的一個屬性,值為0x7f030000,一個資源ID,那么它指向哪里呢?

image

上圖可以看到,真正的視圖布局文件在這里。上一節講過,res文件夾下的資源會自動在R.java里面生成記錄,現在看到確實是如此。至於那個資源ID是根據什么規則生成的,那就沒研究了,反正他自動維護,我們樂得清閑。

一會兒我們要修改程序界面就可以從這里入手。

Demo程序的代碼部分就這么多,是不是覺得其實並沒那么難?呵呵。

█ 學過JAVA的同學可能會有疑問了:怎么沒有入口函數呢?

我們編寫Android程序是在Android SDK下進行的,SDK在背后完成了很多工作,包括程序從哪里運行、怎么渲染視圖等等,我們只需要寫程序的邏輯部分、視圖部分,對於這個程序里的代碼來說,DemoActivity類就相當於一個入口了(姑且稱之為入口Activity吧),這和原生的JAVA編程是有一點不一樣哈。

█ 喜歡動腦經的同學會想:一個程序可能有多個界面,就有多個Activity,那么怎么知道該選擇哪個Activity為入口呢?

上一節還提到過一個全局配置文件AndroidMainifest.xml,我們打開看看:

image

我們可以看到,在這個文件里面配置了所有Activity的信息,DemoActivity里面有兩個intent-filter,<action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" />,發現了LAUNCHER字樣,可以猜測這個就是入口標記,我們一會兒驗證一下。

二、新建一個Activity

我們新建一個Activity,脫離自動生成的DemoActivity試試

image

在src下的com.android.demo上點擊右鍵 –> New –> Class

image

Name處填寫類的名稱,在這里我們填寫launcherActivity,Superclass處我們填寫android.app.Activity,就是Activity的基類,其余的不用修改,點擊”Finish“,結果如下圖所示:

image

可以看到,launcherActivity新建好了,還自動生成了部分代碼,真方便。

糟了,DemoActivity類是大寫字母開頭的,我們的是小寫的l開頭,還是統一一下吧:

在launcherActivity.java中直接修改類的名稱,將l修改為L,發現IDE報錯了(因為JAVA是區分大小寫的,類名必須和文件名一樣),把鼠標移動到錯誤的地方,彈出修改建議,我們選擇”Rename compilation unit to…“,如下圖所示:

image

報錯消失了,文件名也變為大寫開頭了,真方便…

依瓢畫葫蘆,把Bundle組件引入進來,import android.os.Bundle;

然后重載onCreate方法。這個必須重載,我們得在里面設置視圖呀,操作如下:

image

LauncherActivity文件上點擊右鍵,Source –> Override/ Implement Methods...,勾選onCreate,點擊”OK“,代碼就自動生成好了:

image

三、新建布局

這個Activity還沒有視圖,我們新建一個:

image

在res/layout上點擊右鍵,New –> Other

image

選擇Android XML Layout File,點擊”Next“,在下一個頁面輸入布局名稱”launcher“,點擊”Finish“,布局文件就創建好了:

image

現在的SDK自帶了可視化布局,直接往上拖就行了,不過想要做出好看的界面,還需要深入了解Android界面布局,以后遇到再詳細講解。

image

可點擊標注處切換可視化界面或XML編輯界面,很多XML頁面打開都有這個切換按鈕,可以進行切換。

這里我們要做一個啟動界面,中間加個加載圖標,一行文字即可。詳細過程不多敘述(因為我都還沒完全學會如何布局,不敢誤人子弟),最終界面如下所示:

image

XML文件內容如下,可復制粘貼到文件里:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >


    <FrameLayout
        android:id="@+id/frameLayout1"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >


        <ProgressBar
            android:id="@+id/progressBar1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center" />



        <TextView
            android:id="@+id/textView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:layout_marginTop="120dip"
            android:text="Welcome ..."
            android:textAppearance="?android:attr/textAppearanceLarge" />

    </FrameLayout>

</LinearLayout>

在LauncherActivity類的onCreate方法中加上設置視圖的代碼:

setContentView(R.layout.launcher);

這樣JAVA代碼就編寫好了,但還沒完,我們還需要在AndroidMainifest.xml文件中添加這個Activity的配置信息,同時將DemoActivity配置中的intent-filter移動到LauncherActivity配置中,驗證一下是否真的是入口標志,最終的配置信息如下:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.android.demo"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="8" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:name=".DemoActivity"
            android:label="@string/app_name" >
        </activity>
        <activity
            android:name=".LauncherActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

一個新的Activity就編寫完成了,按照上一節的方法運行看看是否正確:

image

可以看到,我們親自編寫的Activity運行起來了。正如我們所料,intent-filter段中的那個配置信息確實是起到了標記入口Activity的作用。

程序運行了半天還是一直加載,怎么回事呢?因為程序中沒后續動作了。接下來我們修改程序讓它跳轉到DemoActivity中。

四、Activity之間的跳轉

這需要在LauncherActivity類中修改代碼,思路是在onCreate被調用、設置好視圖后,等待一段時間,再跳轉到DemoActivity。開始編碼:

		Timer timer = new Timer();
		timer.schedule(new TimerTask() {
			@Override
			public void run() {
				// TODO Auto-generated method stub
				Intent goIntent = new Intent();
				goIntent.setClass(LauncherActivity.this, DemoActivity.class);
				startActivity(goIntent);
			}
		}, 3*1000);

這里我們新建了個計時器timer,添加了個任務,在3秒鍾后執行。跳轉的代碼位於第6、7、8行:

建立一個Intent,設置好起始地點(LauncherActivity),目的地點(DemoActivity),開始跳轉(startActivity)。

這段代碼位於setContentView(R.layout.launcher);之后,最終代碼如下所示:

package com.android.demo;

import java.util.Timer;
import java.util.TimerTask;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;

public class LauncherActivity extends Activity{

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.launcher);
		
		Timer timer = new Timer();
		timer.schedule(new TimerTask() {
			@Override
			public void run() {
				// TODO Auto-generated method stub
				Intent goIntent = new Intent();
				goIntent.setClass(LauncherActivity.this, DemoActivity.class);
				startActivity(goIntent);
			}
		}, 3*1000);
	}

}

保存,再次運行,看歡迎頁面是否在3秒鍾后跳轉到了主頁面。

五、遺留的問題

在這一節,又接觸了一些新東西,之前沒說明,可能有些同學早就產生疑問了,這里集中講一下:

第二個import語句引入的Bundle是什么,后面一直沒用過?

Bundle的字面意思為:捆、束,一組東西,在Android中用來傳遞數據,表現為Key-Value鍵值對,可以從一個Activity傳遞數據到另一個Activity。在這個例子中我們還沒用到它,但onCreate函數的參數必須要它,所以,必須import…

最后又用到了個Intent,是什么?

Intent,意圖,和Bundle類似,也是包含一組東西,但不僅僅是數據,還包含操作類型、操作對象等信息。在上面的例子中startActivity函數只需要一個goIntent就能實現跳轉功能,就是因為goIntent包含了操作所需的東西,如果需要傳遞其它信息,還需要更復雜的設置。

結尾

這一節我們編寫了一個完整的小程序,雖然它實際上沒什么用…

仔細想想接觸到的東西還是挺多,面向對象、繼承、資源引用、全局配置、Activity的創建、布局文件的創建、Activity之間跳轉。

今天還是沒能寫出牛叉的程序,可能同學們覺得太慢了,但只要每天堅持學習幾個知識點,學習新的東西,不間斷的堅持下去,一定會成為大牛的!

下一節我們寫個牛叉的:基站定位,會學習到SDK中其它API的調用,HTTP通信,JSON解析等相關知識。

如果你喜歡看到這些文字,請點擊右下角的”推薦“支持我一下,謝謝!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM