Google 手機程式設計

2007 年 10 月,Google Phone 即將出現的傳聞吵得沸沸煬煬,2007年11月12日,Google 終於公布答岸,原來、Google 並非要做手機,而是直接釋出了一個基於 Linux 的手機平台 - Android,Android 平台的核心採用了 GPL v2 的授權,應用部分則採用了 Apache Software License 授權,這意味著手機產業可能會有所改變,由於已經有 33 家廠商參與 Android 的 Open Handset Alliance聯盟,目前市場上以 Nokia 的 Symbian 平台與微軟 Windows Mobile 平台為主的局勢很可能會被打破,Google 所採用的開放原始碼架構對廠商與開發者都有相當大的吸引力,因此、Android 可望再手機平台上異軍突起,這是所有手機軟硬體開發者都應該仔細研究的一項新興技術。

Google 手機除了採用 Linux 平台為核心以外,也使用了 Java 作為開發的主要語言 (到作者截稿前、更是唯一的應用程式開發語言),而 Java 也從 2007 年初開始就已經成為開放原始碼的成員之一,從這點看來、Google 使用開放原始碼的意圖相當明顯,然而、為了避免強制開放原始碼的限制,使得手機製造商與軟體設計廠商被迫要開放原始碼,因此、在應用端的 Java 平台以上,Android 所使用的是 Apache Software License (ASL)[1][2],ASL 並不要求軟體開發者要開放原始碼,這使得軟體開發廠商可以透過開發 Google 手機程式營利。

Google 在手機開發平台上的這種佈局是相當精巧而有彈性的,一方面藉助開放原始碼社群的力量,另一方面又可以吸引手機製造公司與軟體設計公司紛紛加入戰局,而不需要受到開放原始碼與平台授權金的限制,這使得 Google Phone – Android 平台具有相當大的吸引力,相信在 2008 年中 Google Phone 開始量產販售後,我們應該可以看到手機產業的大轉變。

本書將由淺入深的講解 Google 手機平台上的程式設計原理與方法,並以範例導向的方式,引導程式設計者進入 Google Phone 的程式設計殿堂。

內容

Google 手機程式設計... 1

序... 1

第一章 Android 平台簡介... 6

1.1 Android 平台的結構... 6

1.2 Google Phone 的外觀與功能... 7

1.3 啟動Google Phone 的模擬器... 10

第二章 程式開發環境的安裝... 13

2.1 安裝 Java 的 JDK. 13

2.2 安裝 Android 的 SDK. 13

2.3 安裝 Eclipse 整合開發環境... 13

2.4 在 Eclipse 中安裝 Android 外元件... 13

第三章 開發您的第一個程式... 14

3.1 建立 Android 程式專案... 14

3.2 修改 XML介面... 16

3.3 執行專案程式... 18

3.4 程式執行的原理... 20

第四章 Android 核心物件與程式架構... 23

4.1 Android 的系統架構... 23

4.2 程式核心 - Activity 物件... 23

4.3 重要的元件簡介... 23

第五章 視覺化介面的基礎... 26

5.1 Android 介面設計簡介... 26

5.2 以 XML 設計視覺化介面... 27

5.3 基本的視覺元件... 27

5.4 各種排版元件 – Layout. 27

5.4.1 FrameLayout. 27

5.4.2 AbsoluteLayout. 30

5.4.3 LinearLayout. 32

5.4.4 RelativeLayout. 33

5.4.5 TableLayout. 35

第六章 視覺化介面進階... 39

6.1 基本視覺元件... 39

6.2 資料綁定元件... 39

6.3 XML 屬性的設定... 39

6.4 統一的風格元件... 40

第七章 事件處理... 41

7.1 事件處理的基本概念... 41

7.2 視覺化介面的事件處理... 41

7.3 時間相關事件的處理... 43

7.4 Notification通知事件的處理... 43

第八章 系統程式相關物件... 44

8.1 Android 的系統程式簡介... 44

8.2 程式核心 - Activity 物件... 44

8.3 連接者 – Intent 物件... 44

8.4 服務 – Service 物件... 44

8.5 資料提供者 – Provider 物件... 44

8.6 AlarmManager 44

第九章 字串處理與XML. 45

9.1 Android 中的字串相關函式庫... 45

9.2 字串物件的使用... 45

9.3 正規表示式... 45

9.4 處理XML 文件... 45

第十章 資料儲存... 47

10.1 共用資料 – SharedPreference.. 47

10.2 檔案系統 - Files. 48

10.3 資料庫- Sqlite.. 48

10.4 資料提供者 – ContentProvider 48

第十一章 網路函式庫... 49

11.1 網路相關函式庫... 49

11.2 Socket 程式設計... 49

11.3 Apache 的 HttpClient. 49

11.4 Android 的網路函式庫... 49

11.5 XMPP 網路服務協定... 49

11.6 WebKit 瀏覽器的控制... 49

第十二章 二維繪圖功能... 50

12.1. 50

12.2. 50

12.3. 50

第十三章 2D 動畫功能... 51

13.1. 51

13.2 變形與轉換... 51

13.3. 53

第十四章 3D 動畫 OpenGL. 55

14.1 3D 動畫的基本概念... 55

14.2 3D 模型的設計... 55

14.3 OpenGL 的範例... 55

第十五章 影像與聲音功能... 57

15.1 播放內部影音資源... 57

15.2 播放外部影音檔案... 57

15.3 播放網路上的影音檔案... 57

15.4 錄音與錄影... 57

15.5 照相功能... 58

第十六章 電話功能 Telephony. 59

16.1 電話相關函式庫... 59

16.2 撥打電話... 59

16.3 取得電話資訊... 60

16.4 簡訊功能... 60

16.5 E-mail 功能... 60

第十七章 衛星定位... 61

17.1 衛星 GPS 相關函式庫... 61

17.2 衛星定位的程式... 61

17.3 控制 Google Map 的顯示... 61

第十八章 藍芽功能... 62

18.1 開放原始碼的藍芽函式庫 - BlueZ. 62

18.2 搜尋藍芽裝置... 62

18.3 檔案與物件交換... 62

18.4 透過藍芽連上 Internet. 62

第十九章 部署與安裝程式... 63

19.1 建立安裝程式... 63

19.2 部署程式到 Google Phone 上... 63

第二十章 Google Phone 的未來... 64

20.1 Google.. 64

20.2 結論... 64

附錄一 Android 的開發工具... 65

附錄二 Eclipse 的使用方法... 66

附錄三 Android 的函式庫列表... 67

附錄四 Android 中的視覺畫元件展示館... 72

附錄六 Android 説明文件的閱讀指引... 76

android.widget.TableRow.LayoutParams. 76

Summary. 77

Details. 83

附錄七 Android 與 Java 之間的關係... 85

參考文獻... 86

第一章 Android 平台簡介

1.1 Android 平台的結構

Android 平台是 Google Phone 的手機作業平台,平台的底層採用了 Linux 作為作業系統 (圖一中的紅色部分),在Linux作業系統之下、內建了許多控制裝置的驅動程式,包含藍芽(Bluetooth)、無線網路(WiFi)、隨插即用的USB 介面等等,當然還有記憶體、銀幕、鍵盤、照像、音效等裝置的驅動程式,在 Linux 作業系統之上,內建了許多由 C/C++ 語言所開發出來的函式庫 (Libraries) (圖一中的綠色部份),包含 libc、OpenGL/ES、WebKit、Sqlite等,接著、Google 架構出 Java 環境 Android Runtime,這包含了一個虛擬機器 Dalvik Virtual Machine (DVM) 與基本的Java 函式庫 (Core Libraries),然後、Google 利用這些 C/C++ 函式庫與 Java 虛擬機器建構出一組應用架構 (Application Framework),以協助應用程式設計者開發出好的應用程式 (Application)。

clip_image002

目前、Android 當中內建的應用程式已有瀏覽器 (Web Browser)、Google Map、手機通話 (Phone) 等,在未來應該會有更多的應用被開發出來,在筆者寫作的同時,Google 也正在舉辦一個 Android 應用軟體大賽,總共提供了1000萬美元的獎金,為的應該就是要快速的充實Android手機平台上的軟體。

Android 平台的函式庫主要來自下列三個群體,第一個是 Android 本身開發的,第二個是 Java 原有的函式庫,第三個是 開放原始碼社群的函式庫 (Android 採用最多的是從 Apache Software Foundation來的)

1.2 Google Phone 的外觀與功能

要成為一個 Google Phone 的手機程式設計師之前,應該先熟悉 Google Phone 的手機使用環境,在 Android 平台所提供的預設環境當中,有三種形式的Google Phone,包含 QVGA-L、QVGA-P、HVGA 等,其中 HVGA 又分成垂直版 HVGA-L 與水平版HVGA-P 兩種, 下表顯示了這些手機的型號、大小與樣式。

skinID

Description

Skin

QVGA-L

320x240, landscape (default)

clip_image004

QVGA-P

240x320, portrait

clip_image006

HVGA-L

480x320, landscape

clip_image008

HVGA-P

320x480, portrait

clip_image010

clip_image012

這就是 Google Phone 的樣子了,其中的按鈕大多都很直覺,會使用手機的人應該都很容易上手,然而、中間的幾個按鈕式功能鈕,並非一般手機所具有的,下表說明了每個按鈕的功能:

按鈕圖示

按鈕名稱

功能說明

clip_image014

功能表鈕

按此鈕會顯示功能表 (若該畫面具有功能表的話)

clip_image016

退回鈕

按此鈕會退回到上一層

clip_image018

主畫面鈕

按此鈕會回到系統最上層的主畫面

clip_image020

取消鈕

按此鈕會取消某個動作

1.3 啟動Google Phone 的模擬器

clip_image022

當我要啟動模擬器時,最簡單的方式就是在 emulator.exe 上雙擊滑鼠右鍵,此時、預設的模擬器畫面 QVGA-L 將會被啟動,結果如下圖所示:

clip_image024

在啟動過程完成之後,將會呈現出主視窗畫面如下:

clip_image012[1]

第二章 程式開發環境的安裝

要開發 Google Phone – Android 平台的程式,您必須先安裝 Android 的開發環境,這個環境所採用的平台是建構在 Java 的虛擬機器 Java Virtual Machine (JVM)的一個手機特製版本 Delvik Virtual Machine (DVM) 上的,開發用的程式語言為 Java,並使用 Java 上最主要的整合開發工具 Eclipse 所為開發環境,設計者只要在 Eclipse 當中外掛 Android Development Tools plugin即可完成開發環境的安裝。

http://code.google.com/android/intro/installing.html

2

2.1 安裝 Java 的 JDK

clip_image026

clip_image028

clip_image030

clip_image032

clip_image034

clip_image036

clip_image038

clip_image040

clip_image042

clip_image044

clip_image046

clip_image048

clip_image050

clip_image052

clip_image054

2.2 安裝 Android 的 SDK

clip_image056

點選 windows 中的 android_sdk_windows_xxx.zip

clip_image058

clip_image060

clip_image062

clip_image064

clip_image066

clip_image068

2.3 安裝 Eclipse 整合開發環境

clip_image070

clip_image072

clip_image074

clip_image076

clip_image078

clip_image080

clip_image082

clip_image084

2.4 在 Eclipse 中安裝 Android 外掛元件
clip_image086

clip_image088

clip_image090

Start Eclipse, then select Help > Software Updates > Find and Install....

In the dialog that appears, select Search for new features to install and press Next.

Press New Remote Site.

In the resulting dialog box, enter a name for the remote site (e.g. Android Plugin) and enter this as its URL: https://dl-ssl.google.com/android/eclipse/. Press OK.

You should now see the new site added to the search list (and checked). Press Finish.

In the subsequent Search Results dialog box, select the checkbox for Android Plugin > Eclipse Integration > Android Development Tools and press Next.

Read the license agreement and then select Accept terms of the license agreement, if appropriate. Press Next.

Press Finish.

The ADT plugin is not signed; you can accept the installation anyway by pressing Install All.

Restart Eclipse.

After restart, update your Eclipse preferences to point to the SDK root directory ($SDK_ROOT):

Select Window > Preferences... to open the Preferences panel. (Mac OS X: Eclipse > Preferences)

Select Android from the left panel.

For the SDK Location in the main panel, press Browse... and find the SDK root directory.

Press Apply, then OK

clip_image092

Click Help/Software/Find and Install

clip_image094

Click Search for New Feature to Install

clip_image096

Press New Remote Site

clip_image098

In the resulting dialog box, enter a name for the remote site (e.g. Android Plugin) and enter this as its URL: https://dl-ssl.google.com/android/eclipse/. Press OK.

clip_image100

In the subsequent Search Results dialog box, select the checkbox for Android Plugin > Eclipse Integration > Android Development Tools and press Next.

clip_image102

clip_image104

clip_image106

clip_image108

clip_image110

Read the license agreement and then select Accept terms of the license agreement, if appropriate. Press Next.

Press Finish.

The ADT plugin is not signed; you can accept the installation anyway by pressing Install All.

Restart Eclipse.

After restart, update your Eclipse preferences to point to the SDK root directory ($SDK_ROOT):

Select Window > Preferences... to open the Preferences panel. (Mac OS X: Eclipse > Preferences)

Select Android from the left panel.

For the SDK Location in the main panel, press Browse... and find the SDK root directory.

Press Apply, then OK

更改執行環境

clip_image112

clip_image114

clip_image116

clip_image118

第三章 開發您的第一個程式

依照程式設計者的慣例,在撰寫第一個程式時,我們都會以最簡單的輸出 Hello World ! 訊息在銀幕上作為第一個程式,以下我們就遵循這樣一個慣例,在 Android 平台上開發出第一個屬於 Google Phone 的 Hello World ! 程式。

3

3.1 建立 Android 程式專案

當你安裝好 Eclipse 之後,就可以開始撰寫程式了,首先要先建立一個專案,請點選 Eclipse 功能表中的 File/New/Android Project 的選項,如下圖所示:

clip_image120

當您點選後,會出現一個 New Android Project 的視窗,請在 Project Name 一欄中鍵入 HelloWorld 作為專案名稱,選擇 Create new project in workspace,並在 Package Name 中鍵入 test.hello 作為套件名稱,接著在 Activity Name 與 Application Name 欄位中都鍵入 HelloWorld 作為程式名稱,然後按下 Finish 鍵。

clip_image122

如此、Eclipse 就會建立一個名稱為 HelloWorld 的專案,並且自動產生很多檔案,其中、我們的主程式位在 src/test/hello/HelloWorld.java 中,另外、還有一個重要的檔案,是 res/layout/main.xml 檔。

clip_image124

3.2 修改 XML介面

請點選 res/layout/main.xml 檔案,您會看到如下圖的一個 XML 文件,請仔細觀察一下這個文件,猜猜看他的用途 ?

clip_image126

您可能已經猜到、Android 是使用 XML 來做視窗介面的描述 (微軟也正在做同樣的事,Microsoft.NET 3.5 與Visual Studio 2008 正在建立一個稱為 Windows Presentation Foundation (WPF) 的顯示架構,同樣是使用 XML 來描述視窗介面)。

main.xml 中的最外層標記 LinearLayout 表示本畫面將使用線性排列的方式,其中的TextView 代表在本畫面中會有一個文字區域,屬性 android:text 代表該文字區域中所顯示的文字,在此、請將其內容改為 Hello World !

clip_image128

如此、您便完成了第一個程式 HelloWorld。

3.3 執行專案程式

接著、您就可以在 Navigate 視窗中的 HelloWorld 專案上按下滑鼠右鍵,選擇 Run As/Android Application 功能,開始執行您的 HelloWorld 程式,如下圖所示:

clip_image130

稍後片刻之後,模擬器會被啟動,經過一小段開機程序,您會看到HelloWorld 程式的執行結果畫面如下。

clip_image132

讀到這裡,可能很多人對 Android 的程式設計原理會有相當大的疑問,為了解開這些疑問,我們將更深入 HelloWorld 程式的其他檔案一窺究竟。

3.4 程式執行的原理

在src/test/hello資料夾中的HelloWorld.java程式如下所示

package test.hello;

import android.app.Activity;

import android.os.Bundle;

public class HelloWorld extends Activity {

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle icicle) {

super.onCreate(icicle);

setContentView(R.layout.main);

}

}

在上例中、import 指令引入了 android.app.Activity與 android.os.Bundle 兩個類別,我們可以看到 HelloWorld 繼承了Activity 這個類別,Activity 在 Android 平台當中的地位相當於一個作業系統的行程 (Process),也就是相當於 Java 程式中的主程式 main,然而、在 Android 當中使用 Activity 物件來取代主程式的概念是有原因的,因為 Android 將主程式的概念也徹底的物件導向化了,於是屬於靜態函數的 main 搖身一變就成了物件版的 Activity 了。

為何 Android 要將主程式物件化呢,這牽涉到 Android 的設計理念,在 Google Phone 當中,程式一開始執行後就會一直存在,通常不會結束,這樣的做法在手機當中很自然,例如、我們正在玩遊戲的當中可能會有電話打進來,此時、我們會先去接個電話,等到電話講完了,我們又會回來繼續玩遊戲,因此、Google Phone 的程式必須要適應這種半途中斷的狀況,於是 Android 平台將主程式物件化,使得主程式永遠存在 Google Phone 中,然而、當越來越多的 Activity 被放入記憶體執行之後,卻可能使得手機的記憶體不堪負荷,而導致記憶空間不足的窘境,為了解決這樣的困擾,Android的作業系統在必要時會將不重要的 Activity 先置換出去,等到該 Activity 又要被執行的時候才置換回來,於是、Activity 必須要在被置換出去前先儲存重要資訊,以便在被置換回來後得以取回這些資訊,以回復到先前的程式執行狀態,這樣也可節省行程切換所產生的負擔,於是 Android 採用了物件化的 Activity 作為主程式的概念,使得 Android 中的程式變得很不一樣。

主程式被物件化為 Activity之後,視覺化介面的作業也跟著要搭配 Activity 而設計,因而、Android 採用了 View 這一個概念,每個 Activity 都可以搭配一些 View 而被顯示出來,只要使用Activity 中的 setContentView 函數即可,這也就是上述範例中 setContentView(R.layout.main) 指令的意義所在,當 HelloWorld 這個 Activity 被啟動後,立即將其顯示介面設為 R.layout.main,於是、R.layout.main 所對應到的介面將會被顯示出來。

然而、R.layout.main 到底對應到甚麼介面呢,這個答案很不明顯,但其實就是我們在 res/layout/main.xml 中所寫的那個介面。

當我們修改 main.xml 之後按下存檔按鈕時,Eclipse 會利用 Android 在 tools 資料夾下提供的 Android Asset Packaging Tool (aapt) 程式,立即產生R.layout.main 以及對映的類別到 bin/test/ 資料夾下的 HelloWorld.apk 壓縮檔中,這裏會包含 R.layout.main 所對應的物件,於是當我們使用setContentView(R.layout.main) 指令的時候,Activity 就會指定該物件為其顯示物件。

第四章 Android 核心物件與程式架構

4

4.1 Android 的系統架構

clip_image133

圖 4.1 Android 手機平台的架構

4.2 程式核心 - Activity 物件
4.3 重要的元件簡介

UI Elements and Concepts Glossary

Here is a list of common UI elements and concepts that you will see here and elsewhere in the SDK.

Activity

The standard screen in an Android application. Activity is a class that Android can start when a matching Intent is thrown by this or another application. Most commonly, it is visibly represented by a full screen window that can receive and handle UI events and perform complex tasks, because of the Window it uses to render its window. Though an Activity is typically full screen, it can also be floating or transparent.

View

A rectangular area on the screen that can be drawn to, handles click, keystroke, and other interaction events. A View is a base class for most components of an Activity or Dialog screen (text boxes, windows, and so on). It receives calls from its container object to draw itself, and informs its parent object about where and how big it would like to be (which may or may not be respected by the parent). It is represented by the base class View.

View Group

A container that holds multiple child View objects, deciding where they will be and how large they can be, and calling on them to draw themselves when appropriate. Some are invisible and for layout only, while others have a UI themselves (for instance, scrolling list boxes). View groups are all in the widget package, but extend ViewGroup.

Widget

A form element, such as a text box or popup menu. They have the ability to draw themselves and handle UI events. Widgets are all in the widget package.

Drawable

A visual element that is loaded into another UI element, typically as a background image. It does not receive events, but does assign various other properties such as "state" and scheduling to enable subclasses such as animation objects or image libraries. Many drawable objects are loaded from resource files — xml or bitmap files that describe the image. The base class is Drawable. See Resources.

Panel

A panel is a concept not backed by a specific class. It is a View of some sort that is tied in closely to a parent window, but can handle clicks and perform simple functions related to its parent. A panel floats in front of its parent, and is positioned relative to it. A common example of a panel (implemented by Android) is the options menu available to every screen. At present, there are no specific classes or methods for creating a panel — it's more of a general idea.

Dialog

A dialog is a floating window that can have buttons, and acts as a lightweight form that is intended to, at most, perform a simple action (such as click a button) and perhaps return a value. It is not intended to persist in the history stack, contain complex layout, or perform complex actions. Android provides a default simple dialog for you with optional buttons, though you can define a dialog layout yourself. The base class is Dialog, and the helper methods to open a dialog box are the various Activity.showAlert() methods.

Window

An abstract class that specifies the elements of a generic window, such as the look and feel (title bar text, location and content of menus, and so on). Dialog and Activity use an implementation of this class to render a window. You should not need to implement this class.

Surface

A block of memory that gets composited to the screen. A Surface holds a Canvas object for drawing, and provides various helper methods to draw layers and resize the surface. You should not use this class directly; use SurfaceView instead.

SurfaceView

A View object that wraps a Surface for drawing, and exposes methods to specify its size and format dynamically. The camera app uses SurfaceView for its preview screen. A SurfaceView provides a way to draw independently of the UI thread for resource-intense operations (such as games or camera previews), but it uses extra memory as a result. SurfaceView supports both Canvas and OpenGL ES graphics.

Canvas

A drawing surface where the actual bits are composited. It has methods for standard computer drawing of bitmaps, lines, circles, rectangles, text, and so on. It is bound to a Bitmap or Surface. Canvas is the simplest, easiest way to draw 2D objects on the screen. However, it does not support hardware acceleration, as OpenGL ES does.

OpenGL ES

Android provides OpenGL ES libraries that you can use for fast, complex 3D images. It is much harder to use than a Canvas object, but better for 3D objects. The graphics.glutils package exposes OpenGL ES functionality.

第五章 視覺化介面的基礎

5

5.1 Android 介面設計簡介

在上一章我們曾經談到, Android 平台的視覺化介面是使用 XML 的方式設計的,然而上一章我們只做了一個簡單的 HelloWorld 的表單,在本章、我們將介紹如何利用常用的元件設計出較實用的表單,並展示每個常用視覺元件的用途。

Android 當中的視覺化界面元件,可分為『容器』與『非容器』兩類,容器類繼承 ViewGroup 物件,非容器類則從 View 衍生出來,如下圖所示。

clip_image135

這些 Layout 可以套疊式的組成一棵元件樹,其中、父節點的 Layout 與子節點的 LayoutParams 之間有控制關系,舉例而言、若父節點是 RelativeLayout,則子節點的元件中可以指定 RelativeLayout.LayoutParams 中的屬性,以控制子節點在父節點中的排列狀況,如下圖所示:

clip_image137

5.2 以 XML 設計視覺化介面
5.3 基本的視覺元件
5.4 各種排版元件 – Layout

容器類物件中專們用來排版者,稱為 Layout,以下是 Android 中 Layout 物件的列表:

元件名稱

説明

FrameLayout

單一物件的容器

AbsoluteLayout

以絕對座標排版的容器。

LinearLayout

線性 (水平或垂直) 排版的容器。

RelativeLayout

以相對座標 (相對於父元件或兄弟元件) 排版的容器。

TableLayout

以表格方式排版的容器。

5.4.1 FrameLayout

Android 中的 FrameLayout 與 Java Swing 中的 FrameLayout 完全不同,Android 中的 FrameLayout 代表只能放入單一視覺元件的容器,與 Swing 中區分『上、下、左、右、中』的 FrameLayout 完全是兩回事。

clip_image139

 

clip_image141

android:orientation="vertical"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

>

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="Hello World, FrameLayoutTest"

/>

5.4.2 AbsoluteLayout

clip_image143

android:layout_width="fill_parent"

android:layout_height="fill_parent"

>

android:layout_x = "10px"

android:layout_y = "10px"

android:layout_width="200px"

android:layout_height="wrap_content"/>

GitHub 加速计划 / li / linux-dash
10.39 K
1.2 K
下载
A beautiful web dashboard for Linux
最近提交(Master分支:2 个月前 )
186a802e added ecosystem file for PM2 4 年前
5def40a3 Add host customization support for the NodeJS version 4 年前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐