JSON và web API trong lập trình Android cơ bản | How Kteam

Dẫn nhập

Ở các bài học trước, chúng ta đã cùng nhau tìm hiểu về CƠ CHẾ XỬ LÝ BẤT ĐỒNG BỘ TRONG ANDROID và cách sử dụng AsyncTask để dễ dàng thao tác xử lý bất đồng bộ.

Tuy nhiên trong quy trình thao tác, những thao tác giải quyết và xử lý bất đồng bộ thường là những thao tác với mạng. Và mỗi lần phải sử dụng AsyncTask để làm như vậy thì quả là dài .

Bài hôm nay chúng ta sẽ sử dụng một thư viện hỗ trợ mạng cực mạnh, cũng như một bộ xử lý thông tin dạng JSON mà các Web API hay sử dụng rất phổ biến.

Nội dung

Để đọc hiểu bài này tốt nhất những bạn nên có kiến thức và kỹ năng cơ bản về những phần :

  • Biết AsyncTask là gì, UI Thread là gì, Worker Thread là gì. Những khái niệm này đã được giải thích ở bài CƠ CHẾ XỬ LÝ BẤT ĐỒNG BỘ TRONG ANDROID.
  • Từng tiếp xúc với định dạng JSON.

Trong bài học kinh nghiệm này, tất cả chúng ta sẽ cùng khám phá những yếu tố :

  • Cài đặt thư viện OkHttp và Moshi.
  • Sử dụng 2 thư viện trên để lấy dữ liệu đổ vào ứng dụng.

Tạo project mới

Như thường lệ, chúng ta sẽ tạo một project mới với tên là JSONExample

JSON và web API trong lập trình Android cơ bản

Và chọn minSdk là 13 :

JSON và web API trong lập trình Android cơ bản

Cài đặt OkHttp và Moshi

Cài đặt thư viện OkHttp Moshi vào ứng dụng thật ra rất đơn giản. Do Android Studio đã tích hợp Gradle làm build system và chúng ta có thể lấy bất cứ thư viện nào lưu trên jCenter Maven Central (2 website chứa thư viện / dependencies cho Java lớn nhất hiện nay).

Bước 1: Mở file app/build.gradle. Các bạn nhìn ở cột trái sẽ thấy 2 file build.gradle, nhớ chọn cái (module: app) nhé:

JSON và web API trong lập trình Android cơ bản

Chúng ta thêm 2 dòng sau vào file build.gradle như thế này :
build.gradle

apply plugin: 'com.android.application'

android {
    compileSdkVersion 24
    buildToolsVersion "24.0.2"
    defaultConfig {
        applicationId "com.howkteam.jsonexample"
        minSdkVersion 13
        targetSdkVersion 24
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:24.2.1'
    testCompile 'junit:junit:4.12'

    compile 'com.android.support:recyclerview-v7:24.2.1'
    compile 'com.squareup.okhttp3:okhttp:3.4.1'
    compile 'com.squareup.moshi:moshi:1.2.0'
    compile 'com.squareup.picasso:picasso:2.5.2'
}

( Picasso là thư viện giúp hiển thị hình ảnh thuận tiện hơn, sẽ được sử dụng trong ví dụ ) .

Bước 2: Nhấn vào chữ Sync Now hoặc nút Sync như hình khoanh đỏ. Nhấn 1 lần thôi nhé, để Android Studio tự đồng bộ và download dependency về.

JSON và web API trong lập trình Android cơ bản

Nhắc lại về Model và JSON

Khi các bạn làm về Android tức là các bạn đã biết về Java cơ bản, mà đã là Java cơ bản thì chắc chắn không xa lạ gì khái niệm Model.

Model là một lớp mẫu cho đối tượng nào đó. Ví dụ model Person thì sẽ có 2 trường là String name và int age chẳng hạn.

Thứ 2 là về định dạng tài liệu JSON. Ở đây tất cả chúng ta sẽ lấy tài liệu từ trang này :

Đây là API public của Github, trả về một danh sách các người dùng Github. Và cái chúng ta muốn là đưa danh sách này hiển thị thành RecyclerView trong Android cho dễ xem.

Để cho đơn giản thì chúng ta chỉ lấy 3 trường trong json là login, id và avatar_url.

Bước 1: Đầu tiên chúng ta tạo một file .java mới để làm model, lấy tên là User.java:

package com.howkteam.jsonexample;

public class User {
    public String login;
    public int id;
    public String avatar_url;
}

Đó, chỉ cần vậy thôi .

Bước 2: Tạo layout cho item của RecyclerView mà chúng ta muốn cho hiển thị:

Item_user. xml




    

    

    


Bước 3: Tạo Adapter cho RecyclerView. Để biết cách tạo, các bạn xem lại bài RECYCLERVIEW & VIEWHOLDER:

UserAdapter. java

package com.howkteam.jsonexample;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.squareup.picasso.Picasso;

import java.util.List;

public class UserAdapter extends RecyclerView.Adapter {
    private List users;
    private Context context;

    public UserAdapter(List users, Context c) {
        this.users = users;
        this.context = c;
    }

    @Override
    public int getItemCount() {
        return users.size();
    }

    @Override
    public UserItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.item_user, parent, false);

        return new UserItemViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(UserItemViewHolder holder, int position) {
        User u = users.get(position);
        Picasso.with(context)
                .load(u.avatar_url)
                .into(holder.ivAvatar);
        holder.tvLoginName.setText(u.login);
        holder.tvId.setText(String.valueOf(u.id));
    }

    public static class UserItemViewHolder extends RecyclerView.ViewHolder {
        public TextView tvLoginName;
        public TextView tvId;
        public ImageView ivAvatar;

        public UserItemViewHolder(View itemView) {
            super(itemView);
            tvLoginName = (TextView) itemView.findViewById(R.id.tv_login_name);
            tvId = (TextView) itemView.findViewById(R.id.tv_id);
            ivAvatar = (ImageView) itemView.findViewById(R.id.iv_avatar);
        }
    }
}

Bước 4: Cuối cùng, chỉnh sửa lại file activity_main.xml, MainActivity.java và thêm permission INTERNET cho AndroidManifest:

activity_main. xml




    


MainActivity. java

package com.howkteam.jsonexample;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;

import com.squareup.moshi.JsonAdapter;
import com.squareup.moshi.Moshi;
import com.squareup.moshi.Types;

import java.io.IOException;
import java.lang.reflect.Type;
import java.util.List;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Khởi tạo RecyclerView.
        final RecyclerView rvUsers = (RecyclerView) findViewById(R.id.rv_users);
        rvUsers.setLayoutManager(new LinearLayoutManager(this));

        // Khởi tạo OkHttpClient để lấy dữ liệu.
        OkHttpClient client = new OkHttpClient();

        // Khởi tạo Moshi adapter để biến đổi json sang model java (ở đây là User)
        Moshi moshi = new Moshi.Builder().build();
        Type usersType = Types.newParameterizedType(List.class, User.class);
        final JsonAdapter> jsonAdapter = moshi.adapter(usersType);

        // Tạo request lên server.
        Request request = new Request.Builder()
                .url("https://api.github.com/users")
                .build();

        // Thực thi request.
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.e("Error", "Network Error");
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                
                // Lấy thông tin JSON trả về. Bạn có thể log lại biến json này để xem nó như thế nào.
                String json = response.body().string();
                final List users = jsonAdapter.fromJson(json);
                
                // Cho hiển thị lên RecyclerView.
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        rvUsers.setAdapter(new UserAdapter(users, MainActivity.this));
                    }
                });
            }
        });
    }
}

Và trong AndroidManifest :





    

    
        
            
                

                
            
        
    


Và tất cả chúng ta sẽ được tác dụng :

JSON và web API trong lập trình Android cơ bản

Vậy lợi ích ở đây là gì?

Về bản chất, việc sử dụng 2 thư viện OkHttp và Moshi không khác gì so với dùng AyncTask kèm JSONObject – 2 thư viện có sẵn của Android, nhưng…

  • Android khôngcho phép thao tác mạng trên UI Thread, do đó phải thực hiện theo kiểu bất đồng bộ. OkHttp hỗ trợ rất tốt việc này, mà code lại ngắn hơn do không phải viết class AsyncTask.
  • Moshi giúp chúng ta chuyển đổi thẳng từ tên các trường trong Model ra JSON.
  • Kết hợp cả 2 thư viện này với Picasso để hỗ trợ load ảnh, chúng ta đã viết được một chương trình con rất nhanh.

Kết luận

Qua bài này tất cả chúng ta đã nắm được cách sử dụng OkHttp theo kiểu bất đồng bộ thay cho AsyncTask, phối hợp với Moshi để giải quyết và xử lý tài liệu JSON đổ vào list trong Android .

Bài sau chúng ta sẽ tìm hiểu về PERMISSION TRONG ANDROID, vấn đề tưởng chừng nhỏ nhưng cũng có phần phức tạp.

Cảm ơn các bạn đã theo dõi bài viết. Hãy để lại bình luận hoặc góp ý của mình để phát triển bài viết tốt hơn. Đừng quên “Luyện tập – Thử thách – Không ngại khó”.

Thảo luận

Nếu bạn có bất kể khó khăn vất vả hay vướng mắc gì về khóa học, đừng ngần ngại đặt câu hỏi trong phần bên dưới hoặc trong mục HỎI và ĐÁP trên thư viện Howkteam. com để nhận được sự tương hỗ từ hội đồng .