原生 Android 也能做 Web 開發了

SamElmslie 7年前發布 | 10K 次閱讀 Java 安卓開發 Android開發 移動開發

原生Android也能做Web開發了

Features Image

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

開源地址: https://github.com/yanzhenjie/AndServer

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();</code></pre>

端口號和響應超時設置

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();</code></pre>

AssetsWebsite的使用

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

使用方法是:

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

Wesite wesite = new AssetsWebsite(mAssetManager, youPath);</code></pre>

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

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

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 的相對目錄地址就好了比如你的網站在 assets 下 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);</code></pre>

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

像Servlet一樣寫Http接口

Http API是通過 RequestHandler 接口來注冊的,它是一個 java interface ,它和 Java 的 Servlet 一樣。

你需要實現這個接口,然后在 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);
    }
}

}</code></pre>

然后在 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端

在 Html 的 form 的 action 中填入你注冊 RequestHandler 時的 key 就可以了,然后在 RequestHandler 的

handle(HttpRequest, HttpResponse, HttpContext)

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

比如我們上面注冊 Login RequestHandler 在 form 中這樣使用:

<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();</code></pre>

 

 

 

 本文由用戶 SamElmslie 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!