OkHttp 3
Bài đăng này đã không được cập nhật trong 3 năm
Một trong những việc rất nhàn chán khi phát triển ứng dụng trên nền tảng Android đó là xử lý kết nối mạng, bắt lỗi và exception, kiểm soát kích thước file download và thời gian download file đó...vv.
Tuy nhiên có một thư viện giúp chúng ta giải quyết các vấn đề đó một cách nhanh gọn, đó là OkHttp
.
Hôm nay, tôi sẽ giới thiệu các bạn cách sử dụng OkHttp 3 để connect tới server và download ảnh về.
I. OkHttp là gì?
Bỏ qua định nghĩa khó hiểu từ nhà phát triển thì nó đơn giản là một thư viện cho phép kết nối internet sử dụng giao thức Http
một cách dễ dàng và nhanh chóng hơn.
- Kiểm soát kết nối tới server
- Kiểm soát các kết nối không tốt và thử kết nối lại khi có thể
- Nó sẽ thử thay thế server IP address nếu kết nối tới một IP nào đó bị thất bại vào IP thay thế được chuẩn bị sẵn
- Giảm độ trễ của request, giảm size của file cần download
- Tránh lặp lại các request đã được hoàn thành
II. Cài đặt OkHttp 3 như thế nào?
Cài đặt OkHttp 3
cho project Android rất đơn giản
Ở đây tôi mặc định rằng các bạn đã tạo một Project với tên Okhttp
và một Blank Activity
cho nó.
Step 1: Thêm compile vào phần quản lý dependencies trong file app/build.gradle
compile 'com.squareup.okhttp3:okhttp:3.2.0'
File app/build.gradle
mới chúng ta có được:
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.2"
defaultConfig {
applicationId "sonyama.okhttp"
minSdkVersion 14
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.android.support:design:23.1.1'
compile 'com.squareup.okhttp3:okhttp:3.2.0'
}
Step 2: Đồng bộ hoá project với file gradle vừa được edit
Android Studio sẽ download thư viện OkHttp 3
về và tự động cài đặt vào project của chúng ta.
Các bạn có thể đồng bộ theo 2 cách sau.
Cách 1: Click vào button Sync Project with Gradle Files Button trên tool bar
Cách 2: Tool → Android → Sync Project with Gradle Files
3. Ví dụ Download ảnh với OkHttp 3
Step 1: Sửa file res/layout/activity_main.xml
Ở đây chúng ta khai báo một vùng hiển thị ảnh và để vùng đó ở trạng thái người dùng chưa nhìn thấy
android:visibility="invisible"
Tiếp theo là một button để khi click vào button đó OkHttp 3
download ảnh từ server về, chúng ta sẽ hiển thị ảnh đó ở ImageView
đã khai báo ở trên.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<ImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:visibility="invisible" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:backgroundTint="@android:color/holo_blue_bright"
android:textColor="@android:color/white"
android:text="@string/download_button" />
</RelativeLayout>
File res/values/strings.xml
tương ứng
<resources>
<string name="app_name">Okhttp</string>
<string name="action_settings">Settings</string>
<string name="download_button">Click To Download Image</string>
</resources>
Step 2: Viết class OkHttpHandler
Class này có nhiệm vụ download ảnh và trả về data nhận được dưới dạng mảng byte[]
.
Về cơ bản, đối với những tác vụ tốn nhiều thời gian thực hiện hay không xác định chính xác được thời điển hoàn thành chúng ta nên để ở Background
.
package sonyama.okhttp;
import android.content.Context;
import android.os.AsyncTask;
import android.widget.Toast;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
/**
* Created by ngoson on 2016/02/29.
*/
public class OkHttpHandler extends AsyncTask<String, Void, byte[]> {
OkHttpClient client = new OkHttpClient();
Context c;
@Override
protected byte[] doInBackground(String... params) {
Request.Builder builder = new Request.Builder();
builder.url(params[0]);
Request request = builder.build();
try {
Response response = client.newCall(request).execute();
return response.body().bytes();
} catch (Exception e) {
Toast.makeText(c, "Connect failed", Toast.LENGTH_SHORT).show();
}
return null;
}
}
Đừng quên xin quyền truy cập Internet trong AndroidManifest.xml file nhé!
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
app/src/main/AndroidManifest.xml
đầy đủ sẽ là
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="sonyama.okhttp">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Step 3: Edit onCreate() ở MainActivity
Ở đây chúng ta khai báo URL
của ảnh muốn download
private final String URL = "http://i2.kym-cdn.com/photos/images/newsfeed/000/101/781/Y0UJC.png";
Tiếp theo là set onClick
cho button đã được khai báo tại res/layout/activity_main.xml
. Khi download ảnh thành công chúng ta set bitmap
cho ImageView
sau đó chuyển trạng thái của nó về VISIBLE
để hiển thị kết quả.
package sonyama.okhttp;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private final String URL = "http://i2.kym-cdn.com/photos/images/newsfeed/000/101/781/Y0UJC.png";
Button downloadBtn;
ImageView mImage;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
downloadBtn = (Button) findViewById(R.id.button);
mImage = (ImageView) findViewById(R.id.imageView);
downloadBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
downloadBtn.setVisibility(View.INVISIBLE);
OkHttpHandler handler = new OkHttpHandler();
byte[] image;
try {
image = handler.execute(URL).get();
if (image != null && image.length > 0) {
Bitmap bitmap = BitmapFactory.decodeByteArray(image, 0,
image.length);
mImage.setImageBitmap(bitmap);
mImage.setVisibility(View.VISIBLE);
}
} catch (Exception e) {
Toast.makeText(getApplicationContext(), "Connect Failed", Toast.LENGTH_SHORT).show();
}
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
Và đây là kết quả chúng ta có được.
Click vào button và enjoy kết quả ^^
P/S: Link source code cho bạn nào lười =))
All rights reserved