+8

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à 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

Sync Project with Gradle Files.png

Cách 2: Tool → Android → Sync Project with Gradle Files

スクリーンショット 2016-02-29 午後11.35.26.png

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 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. Screen Shot 2016-03-01 at 09.17.53.png

Click vào button và enjoy kết quả ^^ Screen Shot 2016-03-01 at 09.18.01.png

P/S: Link source code cho bạn nào lười =))

https://github.com/ngoduyson/Okhttp


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí