編輯:關於Android編程
參考:《第一行代碼》
布局文件:
主體代碼:
MainActivity中的代碼也很短,首先使用 findViewById()方法獲取到了 WebView的實例, 然後調用 WebView的 getSettings()方法可以去設置一些浏覽器的屬性,這裡我們並不去設置過多的屬性,只是調用了setJavaScriptEnabled()方法來讓 WebView支持 JavaScript腳本。 接下來是非常重要的一個部分,我們調用了 WebView的setWebViewClient()方法,並傳入了 WebViewClient的匿名類作為參數,然後重寫了 shouldOverrideUrlLoading()方法。這就表明當需要從一個網頁跳轉到另一個網頁時,我們希望目標網頁仍然在當前 WebView中顯示,而不是打開系統浏覽器。 最後一步就非常簡單了,調用 WebView的loadUrl()方法,並將網址傳入,即可展示相應網頁的內容。
權限設置:
在 Android上發送 HTTP請求的方式一般有兩種,HttpURLConnection和HttpClient
首先需要獲取到 HttpURLConnection的實例,一般只需 new出一個 URL對象,並傳入目標的網絡地址,然後調用一下 openConnection()方法即可,如下所示:
URL url = new URL("http://www.baidu.com");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
得到了HttpURLConnection的實例之後,我們可以設置一下 HTTP請求所使用的方法。常用的方法主要有兩個,GET和 POST。GET表示希望從服務器那裡獲取數據,而 POST則表示希望提交數據給服務器。寫法如下:
connection.setRequestMethod("GET");
接下來就可以進行一些自由的定制了,比如設置連接超時、讀取超時的毫秒數,以及服務器希望得到的一些消息頭等。這部分內容根據自己的實際情況進行編寫,示例寫法如下:
connection.setConnectTimeout(8000);
connection.setReadTimeout(8000);
之後再調用 getInputStream()方法就可以獲取到服務器返回的輸入流了,剩下的任務就是 對輸入流進行讀取,如下所示:
InputStream in = connection.getInputStream();
最後可以調用 disconnect()方法將這個 HTTP連接關閉掉,如下所示:
connection.disconnect();
整體代碼:
首先你需要知道,HttpClient是一個接口,因此無法創建它的實例,通常情況下都會創建一個 DefaultHttpClient的實例,如下所示:
HttpClient httpClient = new DefaultHttpClient();
接下來如果想要發起一條GET請求,就可以創建一個HttpGet對象,並傳入目標的網絡地址,然後調用 HttpClient的execute()方法即可:
HttpGet httpGet = new HttpGet("http://www.baidu.com");
httpClient.execute(httpGet);
如果是發起一條 POST請求會比 GET稍微復雜一點,我們需要創建一個HttpPost對象, 並傳入目標的網絡地址,如下所示:
HttpPost httpPost = new HttpPost("http://www.baidu.com");
然後通過一個NameValuePair集合來存放待提交的參數,並將這個參數集合傳入到一個 UrlEncodedFormEntity中,然後調用 HttpPost的 setEntity()方法將構建好的 UrlEncodedFormEntity 傳入,如下所示:
List
params.add(new BasicNameValuePair("username", "admin"));
params.add(new BasicNameValuePair("password", "123456"));
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params, "utf-8"); httpPost.setEntity(entity);
接下來的操作就和 HttpGet一樣了,調用 HttpClient的 execute()方法,並將 HttpPost對象傳入即可:
httpClient.execute(httpPost);
執行 execute()方法之後會返回一個 HttpResponse對象,服務器所返回的所有信息就會包含在這裡面。通常情況下我們都會先取出服務器返回的狀態碼,如果等於響應都成功了,如下所示:
if (httpResponse.getStatusLine().getStatusCode() == 200) {
// 請求和響應都成功了
}
接下來在這個 if判斷的內部取出服務返回的具體內容,可以調用 getEntity()方法獲取到一個 HttpEntity實例,然後再用 EntityUtils.toString()這個靜態方法將 HttpEntity轉換成字符串即可,如下所示:
HttpEntity entity = httpResponse.getEntity();
String response = EntityUtils.toString(entity);
注意如果服務器返回的數據是帶有中文的,直接調用EntityUtils.toString()方法進行轉換會有亂碼的情況出現,這個時候只需要在轉換的時候將字符集指定成 utf-8就可以了,如下所示:
String response = EntityUtils.toString(entity, "utf-8");
整體代碼:
Android系統提供了兩種HTTP通信類,HttpURLConnection和HttpClient。
關於HttpURLConnection和HttpClient的選擇,盡管Google在大部分安卓版本中推薦使用HttpURLConnection,但是這個類相比HttpClient實在是太難用,太弱爆了。OkHttp是一個相對成熟的解決方案,據說Android4.4的源碼中可以看到HttpURLConnection已經替換成OkHttp實現了。所以我們更有理由相信OkHttp的強大。
OkHttp 處理了很多網絡疑難雜症:會從很多常用的連接問題中自動恢復。如果您的服務器配置了多個IP地址,當第一 個IP連接失敗的時候,OkHttp會自動嘗試下一個IP。OkHttp還處理了代理服務器問題和SSL握手失敗問題。
使用 OkHttp 無需重寫您程序中的網絡代碼。OkHttp實現了幾乎和java.net.HttpURLConnection一樣的API。如果你用了ApacheHttpClient,則OkHttp也提供了一個對應的okhttp-apache 模塊。
http是現在主流應用使用的網絡請求方式, 用來交換數據和內容, 有效的使用HTTP可以使你的APP 變的更快和減少流量的使用。
OkHttp 是一個很棒HTTP客戶端:
·支持SPDY, 可以合並多個到同一個主機的請求
·使用連接池技術減少請求的延遲(如果SPDY是可用的話)
·使用GZIP壓縮減少傳輸的數據量
·緩存響應避免重復的網絡請求
當你的網絡出現擁擠的時候,就是OKHttp 大顯身手的時候, 它可以避免常見的網絡問題,如果你的服務是部署在不同的IP上面的,如果第一個連接失敗, OkHTtp會嘗試其他的連接. 這個對現在IPv4+IPv6 中常見的把服務冗余部署在不同的數據中心上. OkHttp 將使用現在TLS特性(SNI ALPN) 來初始化新的連接. 如果握手失敗, 將切換到SLLv3
使用OkHttp很容易,同時支持異步阻塞請求和回調.
如果你使用OkHttp ,你不用重寫你的代碼, okhttp-urlconnection模塊實現了java.net.HttpURLConnection中的API, okhttp-apache模塊實現了HttpClient中的API。
(一)Http Get
對了網絡加載庫,那麼最常見的肯定就是http get請求了,比如獲取一個網頁的內容。
//創建okHttpClient對象 OkHttpClient mOkHttpClient = new OkHttpClient(); //創建一個Request final Request request = new Request.Builder() .url("https://github.com/hongyangAndroid") .build(); //new call Call call = mOkHttpClient.newCall(request); //請求加入調度 call.enqueue(new Callback() { @Override public void onFailure(Request request, IOException e) { } @Override public void onResponse(final Response response) throws IOException { //String htmlStr = response.body().string(); } });
以上就是發送一個get請求的步驟,首先構造一個Request對象,參數最起碼有個url,當然你可以通過Request.Builder設置更多的參數比如:header、method等。
然後通過request的對象去構造得到一個Call對象,類似於將你的請求封裝成了任務,既然是任務,就會有execute()和cancel()等方法。
最後,我們希望以異步的方式去執行請求,所以我們調用的是call.enqueue,將call加入調度隊列,然後等待任務執行完成,我們在Callback中即可得到結果。
ok,需要注意幾點:
1. onResponse回調的參數是response,一般情況下,比如我們希望獲得返回的字符串,可以通過response.body().string()獲取;如果希望獲得返回的二進制字節數組,則調用response.body().bytes();如果你想拿到返回的inputStream,則調用response.body().byteStream()
看到這,你可能會奇怪,竟然還能拿到返回的inputStream,看到這個最起碼能意識到一點,這裡支持大文件下載,有inputStream我們就可以通過IO的方式寫文件。不過也說明一個問題,這個onResponse執行的線程並不是UI線程。的確是的,如果你希望操作控件,還是需要使用handler等,例如:
@Override public void onResponse ( final Response response)throws IOException { final String res = response.body().string(); runOnUiThread(new Runnable() { @Override public void run() { mTv.setText(res); } }); }
2. 我們這裡是異步的方式去執行,當然也支持阻塞的方式,上面我們也說了Call有一個execute()方法,你也可以直接調用call.execute()通過返回一個Response。
(二) Http Post 攜帶參數
看來上面的簡單的get請求,基本上整個的用法也就掌握了,比如post攜帶參數,也僅僅是Request的構造的不同。
Request request = buildMultipartFormRequest( url, new File[]{file}, new String[]{fileKey}, null); FormEncodingBuilder builder = new FormEncodingBuilder(); builder.add("username","張鴻洋"); Request request = new Request.Builder() .url(url) .post(builder.build()) .build(); mOkHttpClient.newCall(request).enqueue(new Callback() { });
大家都清楚,post的時候,參數是包含在請求體中的;所以我們通過FormEncodingBuilder。添加多個String鍵值對,然後去構造RequestBody,最後完成我們Request的構造。後面的就和上面一樣了。
(三)基於Http的文件上傳
接下來我們在介紹一個可以構造RequestBody的Builder,叫做MultipartBuilder。當我們需要做類似於表單上傳的時候,就可以使用它來構造我們的requestBody。
File file = new File(Environment.getExternalStorageDirectory(), "balabala.mp4"); RequestBody fileBody = RequestBody.create(MediaType.parse("application/octet-stream"), file); RequestBody requestBody = new MultipartBuilder() .type(MultipartBuilder.FORM) .addPart(Headers.of( "Content-Disposition", "form-data; name=\"username\""), RequestBody.create(null, "張鴻洋")) .addPart(Headers.of( "Content-Disposition", "form-data; name=\"mFile\"; filename=\"wjd.mp4\""), fileBody) .build(); Request request = new Request.Builder() .url("http://192.168.1.103:8080/okHttpServer/fileUpload") .post(requestBody) .build(); Call call = mOkHttpClient.newCall(request); call.enqueue(new Callback() { //... });
上述代碼向服務器傳遞了一個鍵值對username:張鴻洋和一個文件。我們通過MultipartBuilder的addPart方法可以添加鍵值對或者文件。
ok,對於我們最開始的目錄還剩下圖片下載,文件下載;這兩個一個是通過回調的Response拿到byte[]然後decode成圖片;文件下載,就是拿到inputStream做寫文件操作,我們這裡就不贅述了。
如圖所示為程序效果動畫圖地圖滾動的原理在本人之前博客的文章中介紹過人物在屏幕中的移動方式,因為之前拼的游戲地圖是完全填充整個手機屏幕的,所以無需處理地圖的平滑滾動。這篇文
一:Log日志工具類 一個android應用程序運行後 並不會在 ide的控制台內輸出任何信息. 不能在控制台輸出。但是android提供的Log類。 在程序中輸出日志
策略模式其實特別簡單(聽到這句話,大家是不是心裡一下子放松了?)。比如排序,官方告訴大家我這裡有一個排序的接口ISort的sort()方法,然後民間各盡其能,實現這個排序
這是對ListView上拉加載的一個簡單封裝繼承自ListView,同時提供加載接口原理就是通過對FooterView的控制實現上劃加載的效果public class L