原生Android也能做Web開發了

嚴振杰發表於2019-03-04

大家好,今天跟大家介紹一個讓原生Android也可以做Web開發的開源專案——AndServer

開源地址:github.com/yanzhenjie/…

AndServer是一個Android端的Web伺服器,類似Apache或者Tomcat,但又有不同,它是一個普通的Android Library,Android專案Gradle遠端依賴或者新增Jar包皆可引入該專案,然後就通過正常Android開發一樣開發App了。

AndServer是用純Android API寫一個庫,所以不用任何第三方的庫或者什麼硬體編譯,打成Jar包後僅僅580kb。

很多人看到這裡就有疑問了:它的使用場景是什麼?按照國際慣例,我舉個例子:

某公司公開了一款TV APP,可以安裝在電視或者盒子上,有一個功能是這樣的:
APP安裝在電視上開啟後,會生成一個唯一ID,使用者用微信掃碼通過公司提供的公眾號和該電視上的該APP繫結,使用者通過公眾號開啟一個H5頁面,這個頁面可以上傳圖片或者視訊到伺服器,伺服器檢測到該使用者和某個螢幕的APP繫結,動態把使用者傳送的圖片或者視訊傳送到電視播放。
這樣一個功能是很好的體驗,但是耗費伺服器資源、遠端上傳、遠端下載也都需要時間,還不如我直接用U盤拷貝到電視呢。那麼如果我通過網頁在區域網直接把視訊或者圖片傳送到電視上的APP播放,豈不是更加直接快捷?

當然大部分同學可能很少接觸到APP之間互相在區域網通訊、區域網上傳下載、區域網登入這樣的需求,還有很多栗子我就不舉了,下面開始正式安利。


特點

  1. 接受客戶端檔案上傳、下載檔案。
  2. 動態Http API,就像Java的Servlet一樣寫介面。
  3. 部署靜態網站,例如純Html,支援JS、CSS、Image分離。
  4. 部署動態網站,例如Html表單,當然可以結合上面的Android Http介面。

基本上和Java的Servlet一樣的功能,如果你做過Java開發或者其它語言的Web開發應該就很熟悉了。

依賴

  • Gradle

    compile `com.yanzhenjie:andserver:1.0.2`複製程式碼
  • Maven

    <dependency>
    <groupId>com.yanzhenjie</groupId>
    <artifactId>andserver</artifactId>
    <version>1.0.2</version>
    <type>pom</type>
    </dependency>複製程式碼
  • ADT,可以去AndServer主頁下載Jar包。

使用方法

最好的教程是sample,建議到AndServer主頁下載sample執行檢視效果,然後結合README就更加清晰了。

建立伺服器

AndServer andServer = new AndServer.Build()
    ...
    .build();

// 建立伺服器。
Server mServer = andServer.createServer();
...

// 啟動伺服器。
mServer.start();
...

// 停止伺服器。
mServer.stop();
...

// 伺服器正在執行嗎?
boolean running = mServer.isRunning();複製程式碼

埠號和響應超時設定

AndServer andServer = new AndServer.Build()
    .port(8080) // 預設是8080,Android平臺允許的埠號都可以。
    .timeout(10 * 1000) // 預設10 * 1000毫秒。
    ...
    .build();
...複製程式碼

部署網站

部署網站是通過Website介面,你也可以自己實現這個介面,當然AndServer已經提供了兩個預設實現:

如果用上面兩個實現註冊你的網站,那麼你的預設首頁(index.html)是:

http://ip:port/
http://ip:port/youPath
http://ip:port/youPath/index.html複製程式碼

註冊網站到AndServer

Wesite wesite = new AssetsWebsite(AssetManager, youPath);
// 或者
Wesite wesite = new StorageWebsite(youPath);

AndServer andServer = new AndServer.Build()
    ...
    .website(wesite);
    .build();複製程式碼

AssetsWebsite的使用

如果你的網站在assets下,那麼你就用AssetsWebsite來部署你的網站。

使用方法是:

//AssetManager不能被關閉。
AssetManager mAssetManager = getAssets();

Wesite wesite = new AssetsWebsite(mAssetManager, youPath);複製程式碼

上面我們看到new AssetsWebsite時需要傳一個AssetManager和一個path,path支援assets根目錄和子目錄,下面是這兩種情況的舉例。

  • 如果你的網站在assets根目錄下, 你的path就填"",比如:

原生Android也能做Web開發了
Assets根目錄

Wesite wesite = new AssetsWebsite(mAssetManager, "");複製程式碼

那麼你的預設首頁訪問地址就是:

http://ip:port
http://ip:port/index.html複製程式碼

那麼你的其它頁面訪問地址是:

http://ip:port/login.html
http://ip:port/error.html複製程式碼

比如:

http://192.168.1.12:8080/index.html  
http://192.168.1.12:8080/login.html複製程式碼
  • 如果你的網站根目錄在assets的子目錄下,那麼你傳入assets的相對目錄地址就好了比如你的網站在assetsweb目錄,例如:

原生Android也能做Web開發了
Assets子目錄

Wesite wesite = new AssetsWebsite(mAssetManager, "web");複製程式碼

那麼你的預設首頁訪問地址就是:

http://ip:port
http://ip:port/web
http://ip:port/web/index.html複製程式碼

那麼你的其它頁面訪問地址是:

http://ip:port/web/login.html 
http://ip:port/web/error.html複製程式碼

例如:

http://192.168.1.12:8080/
http://192.168.1.12:8080/index.html
http://192.168.1.12:8080/web/index.html
http://192.168.1.12:8080/web/index.html  
http://192.168.1.12:8080/web/login.html複製程式碼

StorageWebsite的使用

如果你的網站在記憶體裝置下,只要以檔案的形式可以讀取到,那麼你就用StorageWebsite來部署你的網站,比如你的網站在SD卡下時。

使用方法是:

Wesite wesite = new StorageWebsite(youPath);複製程式碼

它很簡單,只要傳入你的網站的儲存目錄地址即可,例如你的網站在SD卡下的www目錄:

File file = new File(Environment.getExternalStorageDirectory(), "www");
String websiteDirectory = file.getAbsolutePath();

Wesite wesite = new StorageWebsite(websiteDirectory);複製程式碼

訪問地址和AssetsWebsite的道理相同。

像Servlet一樣寫Http介面

Http API是通過RequestHandler介面來註冊的,它是一個java interface,它和JavaServlet一樣。

你需要實現這個介面,然後在AndServer註冊即可,例如:

public class RequestLoginHandler implements RequestHandler {

    @Override
    public void handle(HttpRequest req, HttpResponse res, HttpContext con) {
        Map<String, String> params = HttpRequestParser.parse(request);

        // Request params.        
        String userName = params.get("username");
        String password = params.get("password");

        if ("123".equals(userName) && "123".equals(password)) {
            StringEntity stringEntity = new StringEntity("Login Succeed", "utf-8");
            response.setEntity(stringEntity);
        } else {
            StringEntity stringEntity = new StringEntity("Login Failed", "utf-8");
            response.setEntity(stringEntity);
        }
    }
}複製程式碼

然後在AndServer中註冊:

AndServer andServer = new AndServer.Build()
    ...
    .registerHandler("login", new RequestLoginHandler())
    .build();複製程式碼

現在你就得到了一個唯一的訪問地址:http://ip:port/login, 例如:

http://192.168.1.12:8080/login?username=123&password=123複製程式碼

檔案下載和檔案上傳的例子請下載sample檢視。

提交Html表單到Android端

Htmlformaction中填入你註冊RequestHandler時的key就可以了,然後在RequestHandler

handle(HttpRequest, HttpResponse, HttpContext)複製程式碼

方法就可以獲取form提交的引數了。

比如我們上面註冊Login RequestHandlerform中這樣使用:

<form id="form1" method="post" action="login">
...
</form>複製程式碼

監聽伺服器的狀態

伺服器一般情況下有三種狀態:成功啟動、啟動時失敗、成功停止伺服器,失敗時會返回一個異常,一般情況下是網路問題或者埠被佔用。

private Server.Listener mListener = new Server.Listener() {
    @Override
    public void onStarted() {
        // 伺服器啟動成功.
    }

    @Override
    public void onStopped() {
        // 伺服器停止了,一般是開發者呼叫server.stop()才會停止。
    }

    @Override
    public void onError(Exception e) {
        // 伺服器啟動發生錯誤,一般是埠被佔用。
    }
};

AndServer andServer = new AndServer.Build()
    ...
    .listener(mListener)
    .build();複製程式碼

如果你覺得還不錯,請關注我的微信公眾號吧

原生Android也能做Web開發了
嚴振杰

相關文章