? ? 面試使人能夠更正確的認識自己,通過這一輪的面試,我發現自己的基礎知識還是有欠缺的。而且我的記性是真不好,很多寫過的代碼,通過很長時間的思考和摸索才做出來的效果,過不了多久都忘了,因此我決定把平時常用的,我寫項目的過程中遇到的困難,解決的方法都一一記錄下來,同時,也把平時學習新知識的筆記寫在這里。
這是簡書第一篇,上一個項目我都寫在了博客園的個人主頁。
這一篇記錄我學習okhttp3 分以下幾個內容:
1.okhttp3的使用
2.http協議詳解
3.okhttp3的簡單封裝
1.okhttp3的快速使用:
1.使用前準備:
Android Studio配置:
compile'com.squareup.okhttp3:okhttp:3.2.0'
compile'com.squareup.okio:okio:1.7.0'
添加網絡權限:
uses-permission android:name="android.permission.INTERNET"
2.get請求:
private void getAsynHttp() {
mOkHttpClient=new OkHttpClient();
Request.Builder requestBuilder = new Request.Builder()
.url("http://www.baidu.com"); //可以省略,默認是GET請求
requestBuilder.method("GET",null);
Request request = requestBuilder.build();
Call mcall= mOkHttpClient.newCall(request);
mcall.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) { }
@Override
public void onResponse(Call call, Response response) throws IOException {
if (null != response.cacheResponse()) {
String str = response.cacheResponse().toString();
Log.i("kimliu", "cache---" + str);
} else {
response.body().string();
String str = response.networkResponse().toString();
Log.i("kimliu", "network---" + str); }
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), "請求成功", Toast.LENGTH_SHORT).show(); } }); } }); }
2.異步POST請求
private void postAsynHttp() {
mOkHttpClient=new OkHttpClient();
RequestBody formBody = new FormBody.Builder()
.add("size", "10")
.build();
Request request = new Request.Builder()
.url("http://api.1-blog.com/biz/bizserver/article/list.do")
.post(formBody)
.build();
Call call = mOkHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) { }
@Override
public void onResponse(Call call, Response response) throws IOException {
String str = response.body().string();
Log.i("kimliu", str);
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), "請求成功", Toast.LENGTH_SHORT).show(); } }); } }); }
3.異步上傳文件
上傳文件本身也是一個POST請求,首先定義上傳文件類型:
public static final MediaType MEDIA_TYPE_MARKDOWN = MediaType.parse("text/x-markdown; charset=utf-8");
將sdcard根目錄的test.txt文件上傳到服務器上:
private void postAsynFile() {
mOkHttpClient=new OkHttpClient();
File file = new File("/sdcard/test.txt");
Request request = new Request.Builder()
.url("https://api.github.com/markdown/raw") .post(RequestBody.create(MEDIA_TYPE_MARKDOWN, file))
.build();
mOkHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) { }
@Override
public void onResponse(Call call, Response response) throws IOException { Log.i("kimliu",response.body().string()); } }); }
當然如果想要改為同步的上傳文件只要調用 mOkHttpClient.newCall(request).execute()就可以了。
當然不要忘了添加如下權限:
uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
4.異步下載文件
private void downAsynFile() {
mOkHttpClient = new OkHttpClient();
String url = "http://img.my.csdn.net/uploads/201603/26/1458988468_5804.jpg";
Request request = new Request.Builder().url(url).build(); mOkHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) { }
@Override
public void onResponse(Call call, Response response) {
InputStream inputStream = response.body().byteStream();
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream(new File("/sdcard/wangshu.jpg"));
byte[] buffer = new byte[2048];
int len = 0;
while ((len = inputStream.read(buffer)) != -1) {
fileOutputStream.write(buffer, 0, len);
}
fileOutputStream.flush();
} catch (IOException e) {
Log.i("wangshu", "IOException"); e.printStackTrace();
}
Log.d("kimliu", "文件下載成功"); } }); }
5.異步上傳Multipart文件
這種場景很常用,我們有時會上傳文件同時還需要傳其他類型的字段,OkHttp3實現起來很簡單,需要注意的是沒有服務器接收我這個Multipart文件,所以這里只是舉個例子,具體的應用還要結合實際工作中對應的服務器。
首先定義上傳文件類型:
private static final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");
private void sendMultipart(){
mOkHttpClient = new OkHttpClient();RequestBody requestBody = new MultipartBody.Builder().setType(MultipartBody.FORM).addFormDataPart("title","wangshu").addFormDataPart("image","wangshu.jpg",
RequestBody.create(MEDIA_TYPE_PNG, new File("/sdcard/wangshu.jpg"))).build();Request request = new Request.Builder().header("Authorization","Client-ID "+"...").url("https://api.imgur.com/3/image").post(requestBody).build();mOkHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Callcall, IOException e) {
}
@Override
public void onResponse(Callcall, Response response) throws IOException {
Log.i("wangshu", response.body().string());}
});}
6.設置超時時間和緩存
和OkHttp2.x有區別的是不能通過OkHttpClient直接設置超時時間和緩存了,而是通過OkHttpClient.Builder來設置,通過builder配置好OkHttpClient后用builder.build()來返回OkHttpClient,所以我們通常不會調用new OkHttpClient()來得到OkHttpClient,而是通過builder.build():
File sdcache = getExternalCacheDir();
int cacheSize =10*1024*1024;
OkHttpClient.Builderbuilder = new OkHttpClient.Builder()
.connectTimeout(15, TimeUnit.SECONDS)
.writeTimeout(20, TimeUnit.SECONDS)
.readTimeout(20, TimeUnit.SECONDS)
.cache(new Cache(sdcache.getAbsoluteFile(), cacheSize));
OkHttpClient mOkHttpClient=builder.build();
2.http協議詳解
http協議中通信的兩方稱作Client和Server,Client向Server端經過http協議發送一個request,server端收到Request后經過一系列的處理返回client一個Response。
Http:
超文本傳輸協議
作用:設計之初是為了將超文本標記語言(html)文檔從Web服務器傳送到客戶端的瀏覽器。現在http的作用已不局限于html的傳輸。
URL:
Schema:指定底層使用的協議:http/https/ftp
Host:http服務器的IP地址或者域名www.baidu.com
port:http服務器默認端口是80,這種情況下端口號可以省略。如果用了別的端口,必須指明
path:訪問的資源路徑:/st/test
query-string:發送給http服務器的數據 name=user&pwd=123456
http是無狀態的,同一個客戶端的這次請求和上次請求是沒有對應關系的,對http服務器來說,它并不知道這兩個請求來自同一個客戶端,這時候就需要cookie機制來維護狀態。
Request:請求
由三部分組成:
Request line (請求行), http header ,body
請求行:包括http請求的種類,請求資源的路徑,http協議版本
http header:http頭部信息
body:發送給服務器的query信息(當使用GET時,body是空的,GET只能讀取服務器上的信息,post能寫入)
Response:響應 三部分
Request line :協議版本
Requeset header :request頭信息
Body:返回的請求資源主體,就是服務器返回的內容
GET 和 POST的區別
http協議定義了許多與服務器交互的方法,最基本的有4種,分別是GET,POST,PUT,DELETE.一個URL地址用于描述一個網絡上的資源,而HTTP中的GET POST PUT DELETE對應著查,改,增,刪4個操作。最常見的GET和POST.GET一般用于獲取/查詢信息,POST一般用于更新資源信息。
1. GET提交的數據會放在URL之后,以?分割URL和傳輸數據,參數之間以&相連。POST是吧提交的數據放在HTTP包的Body中。
2. GET提交的數據大小有限制(因為瀏覽器對于URL的長度有限制)而POST方法提交的數據沒有限制。
3. GET方式提交數據,會帶來安全問題,比如一個登錄頁面,通過GET方式提交數據時,用戶名和密碼將出現在URL上,如果頁面可以被緩存或者其他人可以訪問這臺機器,就可以從歷史記錄獲取該賬號密碼
狀態碼:
HTTP1.1中定義了5類狀態碼,狀態碼又三位數字組成,第一個數字定義了響應的類別。
1xx:指示信息 表示請求已接受,繼續處理
2xx:成功 表示請求已被成功接收,理解,接受。
3xx:重定向 要完成請求必須進行進一步的操作
4xx:客戶端錯誤 請求有語法錯誤或請求無法實現
5xx:服務器端錯誤,服務器未能實現合法的請求
常見:
200 OK
400 Bad Request 客戶端請求有語法錯誤,不能被服務器理解。
401 請求未經授權,這個狀態碼必須和www-authenticate報頭域一起使用
403 服務器收到請求,但是拒絕提供服務
404 請求資源不存在 可能是輸入了錯誤的URL
500 服務器發生不可預期的錯誤
505 服務器當前不能出了客戶端的請求,一段時間后可能恢復