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 quá trình làm việc, các thao tác xử lý bất đồng bộ thường là các 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 các bạn nên có kiến thức cơ bản về các 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 này, chúng ta sẽ cùng tìm hiểu các vấn đề:

  • 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 dữ liệu JSON. Ở đây chúng ta sẽ lấy dữ liệu từ trang này:

https://api.github.com/users

Đâ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 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

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="8dp"> <ImageView android:id="@+id/iv_avatar" android:layout_width="60dp" android:layout_height="60dp" android:layout_marginEnd="8dp" android:layout_marginRight="8dp"/> <TextView android:id="@+id/tv_login_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="8dp" android:layout_toRightOf="@id/iv_avatar"/> <TextView android:id="@+id/tv_id" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/tv_login_name" android:layout_toRightOf="@id/iv_avatar"/> </RelativeLayout>

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<UserAdapter.UserItemViewHolder> { private List<User> users; private Context context; public UserAdapter(List<User> 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

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" 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="com.howkteam.jsonexample.MainActivity"> <android.support.v7.widget.RecyclerView android:id="@+id/rv_users" android:layout_width="match_parent" android:layout_height="match_parent"/> </RelativeLayout>

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<List<User>> 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<User> 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:

<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.howkteam.jsonexample"> <uses-permission android:name="android.permission.INTERNET" /> <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"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> </application> </manifest>

Và chúng ta sẽ được kết quả:

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ông cho 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 chúng ta đã nắm được cách sử dụng OkHttp theo kiểu bất đồng bộ thay cho AsyncTask, kết hợp với Moshi để xử lý dữ liệu JSON đổ vào danh sách 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ó”.

Tải xuống

Tài liệu

Nhằm phục vụ mục đích học tập Offline của cộng đồng, Kteam hỗ trợ tính năng lưu trữ nội dung bài học JSON và web API trong lập trình Android cơ bản dưới dạng file PDF trong link bên dưới.

Ngoài ra, bạn cũng có thể tìm thấy các tài liệu được đóng góp từ cộng đồng ở mục TÀI LIỆU trên thư viện Howkteam.com

Đừng quên likeshare để ủng hộ Kteam và tác giả nhé!

Thảo luận

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

CỘNG ĐỒNG HỎI ĐÁP HOWKTEAM.COM GROUP THẢO LUẬN FACEBOOK

Từ khóa » Sử Dụng Json Trong Android