OkHttp 3
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à ...
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ề.
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
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
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_awidth="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_awidth="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_awidth="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 URLcủ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 =))
https://github.com/ngoduyson/Okhttp