在英特爾® 淩動™ 處理器上將 OpenGL* 遊戲移植到 Android* (第一部分)

來源:互聯網
上載者:User

將遊戲和其他使用大量 3D 圖形的應用從 OpenGL 標準移植到 Google Android 裝置(包括構建在英特爾 淩動 微架構上的裝置)存在巨大的機遇,因為基於 OpenGL 的遊戲、遊戲引擎和其他傳統軟體易於獲得;OpenGL 便於移植;而且 Android 可提供對 OpenGL ES 和 C/C++ 的支援。 甚至,許多基於 OpenGL 的遊戲和引擎的可用性與開源軟體一樣,如 Id Software 的 Quake 系列。 本文包括兩部分的內容,通過詳述在英特爾淩動處理器上將早期版本的 OpenGL 所構建的應用的渲染組件移植到 Android 中存在的障礙來介紹如何開始這樣的項目。 這些應用可以是遊戲、遊戲引擎或使用 OpenGL 構建 3D 情境或圖形化使用者介面(GUI)的任何一種軟體。 此外,還包括從台式機作業系統(如 Windows* 和 Linux* )以及使用嵌入式版本的 OpenGL ES(無論包括或不包括 windowing 系統)的應用移植 OpenGL 代碼。

本文的第一部分介紹了如何通過軟體開發套件(SDK)或 Android 原生開發工具套件(NDK)在 Android 平台上使用 OpenGL ES,以及如何確定選擇何種方法。 本部分還介紹了各種 SDK 和 NDK 中的 OpenGL ES 樣本應用,以及 Java* 原生介面(JNI),這支援您結合使用 Java 和 C/C++ 組件。 此外,還討論了如何確定使用 OpenGL ES 版本 1.1 還是 2.0。

第二部分將討論您在開始這樣的項目之前,應該瞭解的移植 OpenGL 遊戲存在的障礙,包括 OpenGL 擴充、浮點支援、紋理壓縮格式和 GLU 庫的區別。 此外,還介紹了藉助 OpenGL ES 如何為英特爾淩動處理器設定 Android 的開發系統,以及如何獲得 Android 虛擬裝置類比工具的最佳效能。

Android 上的圖形

您可以通過四種不同的方式在 Android 平台上渲染圖形,每種方式都有其長處和不足之處(見表 1)。 本文並未對四種方式都進行介紹。 只有兩種方式適用於從其他平台移植 OpenGL 代碼: 面向 OpenGL ES 的 SDK 封裝程式類,以及可用於在 C/C++ 中開發 OpenGL ES 的 NDK。 關於其他兩種方法,SDK Canvas 應用編程介面(API)是一款強大的 2D API,可支援您結合 OpenGL ES 使用,但是僅限於 2D 且需要使用新的代碼。

Android 的 Renderscript API 最初並不支援 OpenGL ES,已在 API 等級 16 (Jelly Bean) 中被棄用,因而不能在新的項目中使用。 現在,最適合 Renderscript 的是可以提升計算密集型演算法的效能且不需要分配大量記憶體或傳輸大量資料的應用,如模擬遊戲物理引擎的計算。

表 1.在 Android 上渲染圖形的四種方式

方法 規定
SDK Canvas API 僅支援 Java 和 2D 圖形
面向 OpenGL ES 的 SDK 封裝程式類 可從 Java 調用 OpenGL ES 1.1 和 2.0(但是有 JNI 開銷)
NDK OpenGL ES OpenGL ES 1.1 和 2.0(包括從 Java 中調用原生 C/C++)
面向 OpenGL ES 的 Renderscript OpenGL ES 支援已在 API 等級 16 中棄用

將 OpenGL 應用移植到早期版本的 Android 較為困難,因為大多數傳統的 OpenGL 代碼是使用 C 或 C++ 進行編寫的,而且 Android 僅支援 NDK 在 Android 1.5 中發布之前的 NDK(Cupcake)。 OpenGL ES 1.0 和 1.1 從開始便可提供支援,但是效能不一致,因為加速為可選操作。 但是,近年來 Android 取得了重大的進步。 向 Android 2.2 (Froyo) 中的 SDK 和修訂版 3 中的 NDK 添加了 OpenGL ES 2.0 支援,在 NDK 修訂版 7 中的 OpenGL ES 擴充添加了擴充支援。 現在,在所有新的 Android 裝置上,加速的 OpenGL ES 1.1 和 2.0 是必備配置 — 尤其隨著螢幕尺寸不斷增大。 今天,Android 可為 Java 或 C/C++ 中 OpenGL ES 1.1 或 2.0 上構建的 3D 密集型應用提供一致、可靠的效能,且開發人員可選擇多種方式讓植入流程更輕鬆。

使用採用 OpenGL ES 封裝程式類的 Android 架構 SDK

Android SDK 架構可為 Android 支援的三個版本的 OpenGL ES (1.0、1.1 和 2.0) 提供一套封裝程式類。 這些分類支援 Java 代碼在 Android 系統中輕鬆調用 OpenGL ES 驅動程式 — 即使驅動程式在本地執行。 如果您正在從新開始建立一個新的 OpenGL ES Android 遊戲,或願意將傳統的 C/C++ 代碼轉換為 Java,則這可能是最簡單的方法。 雖然 Java 的設計具備便攜性,但是移植 Java 應用卻較為困難,因為 Android 不能支援全套的現有 Java 平台、標準版(Java SE)或 Java 平台、微型版 (Java ME)分類、庫或 API。 雖然 Android 的 Canvas API 支援 2D API,但是它僅可在 Android 上使用且無法與傳統代碼相容。

Android SDK 提供的多種其他分類讓使用 OpenGL ES 更加輕鬆,如 GLSurfaceView 和 TextureView。 GLSurfaceView 與配合 Canvas API 使用的 SurfaceView 類相類似,但是它還具備其他一些特性 — 尤其對 OpenGL ES。 它可處理所需的嵌入式系統圖形庫(EGL)的初始化,並可分配渲染介面以便 Android 在螢幕的固定位置顯示並進行渲染。 此外,它還具備一些追蹤和調試 OpenGL ES 調用的有用特性。 通過執行面向GLSurfaceView.Renderer() 介面的三種方法,您可以快速建立一個新的 OpenGL ES 應用,如表 2 所示。

表 2. 適用於 GLSurfaceView.Renderer 的基本方法

方法 描述
onSurfaceCreated() 在應用開始初始化時調用一次
onSurfaceChanged() 當 GLSurfaceView 的尺寸或方向發生變化時進行調用
onDrawFrame() 重複調用以渲染每幀圖形情境

如果從 Android 4.0 開始,您可以使用 TextureView 類,不要使用 GLSurfaceView,以便為具備額外功能的 OpenGL ES 提供渲染介面,但是這需要使用更多代碼。 TextureView 介面的運行方式與普通 Views 相同,並可用於渲染至螢幕外介面。 當將 TextureViews 合成至螢幕時,藉助該功能,您可以使其遷移、轉化、實現動畫效果或混合。 此外,您也可以使用 TextureView 以結合使用 OpenGL ES 渲染和 Canvas API。

The 藉助位元影像和 GLUtils 類,使用 Android Canvas API 為 OpenGL ES 建立紋理,或從 PNG、JPG 或 GIF 檔案載入紋理將更輕鬆。 位元影像可用於為 Android 的 Canvas API 分配渲染介面。 GLUtils 類可將影響從位元影像轉換為 OpenGL ES 紋理。 該整合支援您使用 Canvas API 渲染 2D 映像,然後將其用作配合 OpenGL ES 使用的紋理。 這對於建立 OpenGL ES 未提供的圖形元素尤其有用 如 GUI widget 和文本字型。 但是當然,需要使用新的 Java 代碼來利用這些特性。

位元影像類主要是配合 Canvas API 使用,當將它用於為 OpenGL ES 載入紋理時,有一些嚴重的限制。 Canvas API 遵循適用於 alpha 值混合處理的 Porter-Duff 規格,位元影像通過以 premultiplied 格式(A、R*A、G*A、B*A)進行儲存來最佳化每個像素 alpha 值的映像。 這適合 Porter-Duff 但不適合 OpenGL,後者需要使用非 premultiplied(ARGB)格式。 這意味著位元影像類僅可配合完全不透明(或沒有每個像素的 alpha 值)的紋理使用。 一般而言,三維遊戲需要使用帶有每個像素 alpha 值的紋理,在這種情況下,您必須避免使用位元影像,而從位元組陣列或通過 NDK 來載入紋理。

另一個問題是位元影像僅支援從 PNG、JPG 或 GIF 格式載入映像,但是一般情況下,OpenGL 遊戲使用由 GPU 解碼的壓縮紋理格式,且通常僅專用於 GPU 架構,如 ETC1 和 PVRTC。 位元影像和 GLUtils 不支援任何專用的壓縮紋理格式或 mipmapping。 因為這些紋理被大部分的 3D 遊戲頻繁使用,這為使用 SDK 將傳統的 OpenGL 遊戲移植到 Android 帶來嚴重的障礙。 直到 Google 解決了這些問題,最好的解決方案是避免使用位元影像GLUtils 類來載入紋理。 本文中將進一步討論紋理格式,"紋理壓縮格式。”

Android ApiDemos 包含一個名為 StaticTriangleRenderer 的樣本應用,可證明如何使用面向 OpenGL ES 1.0 的 GLES10 封裝、GLSurfaceView位元影像和 GLUtils 類從 PNG 資源載入不透明紋理。 名為 GLES20TriangleRenderer 的類似版本使用面向 OpenGL ES 2.0 的 GLES20 封裝類。 如果您正在使用封裝類處理 Android 架構 SDK,這些樣本應用可為開發 OpenGL ES 遊戲奠定良好的基礎。 請勿使用名為 TriangleRenderer 的原始版本,因為它為名為 javax.microedition.khronos.opengles 的 Java 使用了面向較舊版本的 OpenGL ES 綁定的封裝。 Google 建立了新的綁定,從而能夠為專門面向 Android 的 OpenGL ES 提供靜態介面。 這些靜態繫結可提供更出色的效能,實現更多的 OpenGL ES 特性,並可提供更接近於 OpenGL ES 配合 C/C++ 使用的編程模型 — 這有益於代碼的重新使用。

Android 架構 SDK 可通過 Google 和 Khronos 提供的面向 Java 的多種綁定為 OpenGL ES 提供支援,如表 3 所示。

表 3. 面向 OpenGL ES 的封裝類總結和樣本應用

面向 OpenGL ES 的 Java 綁定 描述 樣本應用
javax.microedition.khronos.egl Khronos standard definition
javax.microedition.khronos.opengles Khronos standard definition TriangleRenderer, Kube, CubeMap
android.opengl Android 專用靜態介面

Android 專用靜態繫結可提供更出色的效能,如果可行,應使用它而非 Khronos 綁定。 靜態繫結可為 Android 上應用開發可用的所有版本的 OpenGL ES 提供相應的封裝類。 表 4 對這些類進行了總結。

表 4. 面向 OpenGL ES 的 Android 封裝類總結和樣本應用

API 版本 Java 類 樣本應用
OpenGL ES 1.0 android.opengl.GLES10 StaticTriangleRenderer, CompressedTexture
OpenGL ES 1.0 android.opengl.GLES10Ext
OpenGL ES 1.1 android.opengl.GLES11
OpenGL ES 1.1 android.opengl.GLES11Ext
OpenGL ES 2.0 android.opengl.GLES20 GLES20TriangleRenderer, BasicGLSurfaceView, HelloEffects

這些封裝類支援傳統的 C/C++ 代碼中的大部分 OpenGL ES 調用僅通過使用適當 API 版本的封裝類為 OpenGL ES 函數和符號名加首碼來轉換為 Java。 參閱表 5 中的樣本。

表 5.將 OpenGL ES 調用從 C 編輯為 Java 的樣本

C 語言 Java 語言
glDrawArrays(GL_TRIANGLES, 0, count) GLES11.glDrawArrays(GLES11.GL_TRIANGLES, 0, count)
glDrawArrays(GL_TRIANGLES, 0, count) GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, count)

使用上述封裝類將 OpenGL 遊戲移植至 Android 有三大局限: 需要使用大量 JAVA 虛擬機器和 JNI 的開銷以及操作將傳統的 C/C++ 代碼轉換為 Java。 Java 是解釋語言,Android 上所有 Java 代碼都在 Dalvik 虛擬機器上運行,因此比編譯的 C/C++ 代碼運行地更慢。 因為 OpenGL ES 驅動程式總是在本地運行,所以每次通過這些封裝調用 OpenGL ES 函數都會造成 JNI 開銷,這限制了遊戲圖形渲染的效能。 您的應用發出的 OpenGL ES 調用越多,對 JNI 開銷造成的而影響越大。 所幸,OpenGL ES 的設計可協助最大限度地減少一般在效能關鍵型渲染迴圈中需要的調用數量。 如果效能很重要,您可以隨時選擇使用 NDK 將效能關鍵型代碼遷移至 C/C++。 但是當然,如果您的代碼開始就是 C/C++,最好先使用 NDK。

是否需要將 C/C++ 代碼轉換為 Java 取決於您項目的具體情況。 如果 C/C++ 代碼的量相對較小且易於理解,而且您不希望提高效能功耗,那麼可以將其轉換至 Java。 如果 C/C++ 代碼的量較大且不易理解,而且您不希望增加功耗,則可以考慮使用 NDK。

使用 Android NDK

Google 於 2009 年 6 月添加了 NDK 以允許應用使用本地啟動並執行 C/C++ 代碼,這可比 Java 提供更高的效能。 因為大部分傳統的 OpenGL 代碼使用 C 或 C++ 編寫,NDK 可提供更簡單的路徑來移植應用,尤其當 C/C++代碼的量太大以至於將其全部轉換為 Java 不實際的時候。 這是 Google 決定公開釋放 NDK 的主要原因,這可讓將 OpenGL 遊戲移植到 Android 更輕鬆。 由於這些優勢,NDK 成為在 Android 上實現需要較快圖形速度的應用的主要方法。

藉助 NDK,您可以將 C/C++ 代碼編寫至 Linux 共用物件程式庫,這些庫靜態串連至您的 Android 應用。 庫使用 GNU 工具構建。這些工具包含在 Google 提供的 NDK 發行軟體包中,您可以使用 Eclipse* 整合式開發環境或命令列介面在 Windows、Mac OS* X 或 Linux 開發系統上運行該工具。 該工具鏈支援三種處理器架構: ARM、英特爾淩動 (x86) 和 MIPS。 雖然 C/C++ 的全部效能可用,但是大部分的 Linux API 不可用。 事實上,直接支援的 API 僅包括 OpenGL ES、OpenMAX* AL、OpenSL ES*、zlib 和 Linux 檔案 I/O,Google 稱其為穩定 API。 但是,根據需求將會提供有關如何將其他的 Linux 庫移植到您的 NDK 項目中的文檔。

NDK 允許您根據應用的情況靈活地在 Java 和 C/C++ 之間對代碼分區。 NDK 支援從名為 Java Native Interface 的 Java 調用 C/C++ 代碼。 但是,JNI 調用將出現大量的開銷,因此,使用原生代碼對應用分區以便最大程度地減少通過 JNI 的調用量非常重要。 一般而言,大部分的 OpenGL ES 應保持以 C/C++ 編寫以便獲得最佳效能和易於移植,但是如要使用 GLSurfaceView 和其他 SDK 類來管理應用生命週期事件和支援其他遊戲函數,可以編寫新的 Java 代碼。 Android 開始支援面向英特爾淩動處理器的 JNI,以 NDK 修訂版 6b 開始。

NDK 支援 OpenGL ES 1.1 和 2.0 並可為兩個版本提供樣本應用,這些樣本應用還可示範如何使用 JNI 將 C 函數與 Java 結合。 這些應用區別在於其代碼在 Java 和 C 之間的分區以及線程化的方式。 它們均使用 NDK 和本地 C 代碼,但是,native-media 樣本應用的所有 OpenGL ES 代碼都是在 Java 中完成,而 san-angeles 和 native-activity 的所有 OpenGL ES 代碼都是在 C 中完成,hello-gl2 在 Java 和 C 之間分割了其 EGL 和 OpenGL ES 代碼。我們應避免使用 hello-gl2 樣本,不僅因為上述的分割,而且因為它無法為 OpenGL ES 2.0 介面優先配置GLSurfaceView,它負責調用 setEGLContextClientVersion(2)。 請參見表 6。

表 6. NDK 中的 OpenGL ES 樣本應用總結

使用的 API 樣本應用 SDK/NDK 分區
OpenGL ES 1.1 san-angeles 所有 EGL 和 OpenGL ES 代碼均為 C。
OpenGL ES 1.1 native-activity 所有代碼均為 C 並使用 NativeActivity 類。
OpenGL ES 2.0 hello-gl2 EGL 設定位於 Java,OpenGL ES 代碼為 C。
OpenGL ES 2.0 native-media 所有的 EGL 和 OpenGL ES 代碼均為 Java。

雖然未使用 OpenGL ES,但是 bitmap-plasma 樣本也非常有趣,因為它示範了如何使用 jnigraphics 庫來執行本地函數,直接存取 Android 位元影像的像素。

註: 您可以從 http://developer.android.com/tools/sdk/ndk/index.html 下載 Android NDK。

活動生命週期事件和線程化

Android 要求所有對 OpenGL ES 的調用均從單線程執行,因為 EGL 環境僅可與單線程關聯,非常不建議在主 UI 線程上渲染圖形。 所以,最好的方法是專門為所有的 OpenGL ES 代碼建立單獨的線程並一直通過該線程執行。 如果您的應用使用了 GLSurfaceView,它可自動建立此專用 OpenGL ES 渲染線程。 在其他情況下,您的應用必須自己建立渲染線程。

san-angeles 和 native-activity 樣本應用的所有 OpenGL ES 代碼均在 C 中,但是 san-angeles 使用了一些 Java 和 GLSurfaceView 來建立渲染線程和管理活動生命週期,而 native-activity 樣本未使用任何 Java 代碼。 不要使用 GLSurfaceView,因為它在 C 中管理活動生命週期;使用 NativeActivity 類提供的渲染線程。 NativeActivity 是 NDK 提供的一種使用便捷的類,支援您使用本地代碼執行活動生命週期處理常式,如 onCreate()onPause() 和 onResume()。 一些 Android 服務和內容供應商無法直接從本地代碼訪問,但可以通過 JNI 獲得。

native-activity 樣本適合匯入 OpenGL ES 遊戲,因為它示範了如何使用 NativeActivity 類和 android_native_app_glue 靜態庫用本地代碼處理生命週期活動。 該類提供了一個單獨的面向 OpenGL ES 代碼的渲染線程、一個渲染介面和一個介面上的視窗,因此,您無需使用GLSurfaceView 或 TextureView 類。 該本地應用的主要進入點是 android_main(),它可在自己的線程中運行並擁有自己檢索輸入事件的事件迴圈。 遺憾的是,NDK 無法提供面向 OpenGL ES 2.0 的樣本版本,但是您可以使用 2.0 代碼在該樣本中更換所有 1.1 代碼。

使用 NativeActivity 的應用必須在 Android 2.3 或更高版本上使用,並在其資訊清單檔中發出專門的聲明,詳見本文的第二部分。

Java 原生介面

如果您選擇在 C/C++ 中實現大部分的應用,將很難避免為更大型且更專業的項目使用 Java 類。 例如,Android AssetManager 和 Resources API 僅可在 SDK 中使用,這是處理國際化和不同介面尺寸等的首選方式。 但是,JNI 可提供解決方案,因為它不僅允許 Java 代碼調用 C/C++ 函數,還允許 C/C++ 代碼調用 Java 類。 因此,雖然 JNI 會產生一些開銷,但是請不要完全避免使用它。 它是訪問僅可在 SDK 中使用的重要系統功能的最好方法 — 尤其當這些功能不是效能關鍵型功能時。 本文不對使用 JNI 進行完整介紹,但是下面列出了使用 JNI 從 Java 調用至 C/C++ 所需的三個基本步驟:

  1. 為 Java 類檔案中的 C/C++ 函數添加一個聲明作為本地類型。
  2. 為包含本地函數的共用物件程式庫添加一個靜態初始化器。
  3. 按照具體的命名方案向本地源檔案中添加相應名稱的功能。

註: 關於藉助 NDK 使用 JNI 的更多資訊,請參閱 http://developer.android.com/training/articles/perf-jni.html。

選擇 OpenGL ES 1.1 還是 2.0?

您應在 Android 上使用哪個版本的 OpenGL ES? 1.0 版的 OpenGL ES 已被 1.1 版取代,因此,真正需要選擇的是 1.1 版和 2.0 版。 Khronos 和 Google 可能無限定地支援兩種版本,但是在大部分情況下,OpenGL ES 2.0 優於 1.1。 憑藉其 OpenGL 著色語言(GLSL)ES 著色器編程特性,它功能更全面並可提供更高的效能。 甚至,它可能會需要更少的代碼和記憶體來處理紋理。 但是,Khronos 和 Google 仍然繼續支援 1.1 版的原因是,它更像台式機和控制台遊戲世界數十年來一直使用的初始 OpenGL 1.x。 因此,將舊版的遊戲移植到 OpenGL ES 1.1 比 2.0 更輕鬆;而且遊戲版本越舊,這種情況越適用。

如果移植的遊戲沒有著色器代碼,則您可以選擇 OpenGL ES 1.1 也可以選擇 2.0,但是使用 1.1 版可能更輕鬆。 如果您的遊戲已經有了著色器代碼,那麼肯定應該選擇 OpenGL ES 2.0,尤其是考慮到近來的 Android 版本都大量地使用了 2.0 版。 根據 Google,截至 2012 年 10 月,訪問 Google Play 網站的 Android 裝置中有超過 90% 的裝置支援 OpenGL ES 1.1 和 2.0 兩種版本。

註: 更多資訊,請參閱 http://developer.android.com/about/dashboards/index.html。

結論

You can implement graphics rendering on Android with OpenGL ES through the Android SDK, the NDK, or a combination of both using the JNI. SDK 方法需要在 Java 中編碼,且最適合新應用的開發,但是 NDK 對以 C/C++ 移植傳統 OpenGL 更實用。 大部分的遊戲移植項目需要結合使用 SDK 和 NDK 兩種組件。 對於新項目,應選擇 OpenGL ES 2.0 而非 1.1 版 — 除非您的傳統 OpenGL 代碼太舊而無法使用任何 GLSL 著色器代碼。

該系列的第二部分將討論您在開始這樣的項目之前必須瞭解的移植 OpenGL 遊戲存在的障礙,包括 OpenGL 擴充的差別、浮點支援、紋理壓縮格式和 GLU 庫。 此外,還介紹了藉助 OpenGL ES 如何為英特爾淩動處理器設定 Android 的開發系統,以及如何獲得 Android 虛擬裝置類比工具的最佳效能。

關於作者

Clay D. Montgomery 是在嵌入式系統上開發面向 OpenGL 的驅動程式和應用的主要開發人員。 他曾在 STB 系統、VLSI 技術、飛利浦半導體、諾基亞、德州儀器、AMX 以及作為獨立顧問從事跨平台圖形加速器硬體、圖形驅動程式、APIs 和 OpenGL 應用的設計。 他曾參與 Freescale i.MX 和 TI OMAP* 平台以及 Vivante、AMD 和 PowerVR* 首個 OpenGL ES、OpenVG* 和 SVG 驅動程式和應用的開發。 他開發了在嵌入式 Linux 上開發 OpenGL ES 並開設了研討班進行教授,且是 Khronos Group 多家公司的代表。

更多相關資訊
  • Google OpenGL ES 指南,“使用 OpenGL ES 展示顯卡 ”: http://developer.android.com/training/graphics/opengl/index.html
  • Vladimir Silva,專業 Android 遊戲: http://www.apress.com/9781430226475
  • Dan Ginsburg,“為基於 OpenGL 和 OpenGL ES 的行動裝置尋找 3D 應用”: http://software.intel.com/en-us/articles/targeting-3d-applications-for-mobile-devices-powered-by-opengl-and-opengl-es
  • Chris Pruett,“面向 Android 的遊戲開發: 快速入門”: http://android-developers.blogspot.com/2010/06/game-development-for-android-quick.html
  • Tewdew Software,“Android 紋理決策”: http://blog.tewdew.com/post/7362195285/the-android-texture-decision
  • Jack Palevich,“GLES Quake — Quake 向 Android 平台的移植”: http://grammerjack.blogspot.com/2009/10/gles-quake-port-of-quake-to-android.html
  • Romain Guy 和 Chet Haase, “Android 4.0 圖形和動畫”: http://android-developers.blogspot.com/2011/11/android-40-graphics-and-animations.html

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.