Retrofit Android Tutorial to Get JSON from Server
Nếu bạn chưa biết Retrofit là gì thì bạn nên biết rằng Retrofit là một Library của Android đã được phát triển bới square. Nó cũng đơn giản hoá các hoạt động kết nối Network trong Android. Trong bài viết ngắn này tôi sẽ cùng các bạn tìm hiểu về cách sử dụng của library này. Trong bài viết này ...
Nếu bạn chưa biết Retrofit là gì thì bạn nên biết rằng Retrofit là một Library của Android đã được phát triển bới square. Nó cũng đơn giản hoá các hoạt động kết nối Network trong Android. Trong bài viết ngắn này tôi sẽ cùng các bạn tìm hiểu về cách sử dụng của library này.
Trong bài viết này chúng ta sẽ tạo một ứng dụng đơn giản để giải thích về htpp để tạo ra request sử dụng Retrofit library.
Vậy chúng ta hãy băt đầu. Để minh hoạ cho việc sử dụng Retrofit. Tôi giả sử rằng chúng ta có một web API để trả về một chuỗi json đơn giản.
http://simplifiedcoding.16mb.com/RetrofitExample/books.json
Chúng ta sẽ tạo request tới Url trên và nhận về một chuỗi json đơn giản như bên dưới.
[ { "bookId":"1", "name":"Harry Potter and The Prisoner of Azkaban", "price":"INR 700.00", "inStock":"52" }, { "bookId":"2", "name":"Hamlet", "price":"INR 1700.00", "inStock":"47" }, { "bookId":"3", "name":"Willy Wonka and His Chocolate Factory", "price":"INR 500.00", "inStock":"48" }, { "bookId":"4", "name":"Before I Fall", "price":"INR 750.00", "inStock":"49" } ]
Như bạn nhìn thấy nó là một JSON Array có một vài detail của book. Chúng ta sẽ lấy chuỗi dữ liệu này vào trong ứng dụng mẫu của chúng ta sử dung Retrofit. Vậy chúng tao tạo một ứng dụng mới
Retrofit Android
Adding dependencies and Creating Layout
Tạo một Android Studio Project mới và thêm đoạn code dưới vào dependencies của bạn (trong build.gradle)
compile 'com.squareup.retrofit:retrofit:1.9.0'
Bởi vì trong ứng dụng của chúng ta sẽ làm những hoạt động Network nên chúng ta cần quyền truy cập Internet. Vậy add nó tới manifest.
<uses-permission android:name="android.permission.INTERNET" />
Bây giờ tới activity_main.xml và tạo một ListView. Trong tutorial này tôi sẽ hiển thị tên của những quyển sách trong ListView.
<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:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"> <ListView android:id="@+id/listViewBooks" android:layout_awidth="match_parent" android:layout_height="wrap_content"> </ListView> </RelativeLayout>
Tạo một file layout cho hiển thị mỗi item trong ListView.
<?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_awidth="fill_parent" android:layout_height="fill_parent" android:padding="10dp" android:textSize="20sp" > </TextView>
Creating Retrofit Model
Một điều tuyệt vời trong việc sử dụng Retrofit là bạn không cần phải parse Json bởi vì Retrofit sẽ làm điều đó cho bạn. Bạn chỉ cần tạo một model. Chúng ta sẽ tạo một class java với tên là Book.java và thêm đoạn code như bên dưới.
public class Book { //Variables that are in our json private int bookId; private String name; private String price; private int inStock; //Getters and setters public int getBookId() { return bookId; } public void setBookId(int bookId) { this.bookId = bookId; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPrice() { return price; } public void setPrice(String price) { this.price = price; } public int getInStock() { return inStock; } public void setInStock(int inStock) { this.inStock = inStock; } }
Bạn không cần phải làm quá nhiều thứ trong các class model. Bạn chỉ cần định nghĩa các biến trong json. Trong mỗi Json Object có 4 thuộc tính (id, name, price and stock) vậy tôi tạo ra 4 biến ở đây và sau đó định nghĩa các phương thức setters và getters cho mỗi biến. Bây giờ chúng ta sẽ tạo Retrofit Api.
Creating Interface to Send HTTP Request using Retrofit
Chúng ta sẽ tạo một interface để xử lý request của chúng ta. Chúng ta sẽ tạo BookAPI.java
import java.util.List; import retrofit.Callback; import retrofit.http.GET; /** * Created by Belal on 11/3/2015. */ public interface BooksAPI { /*Retrofit get annotation with our URL And our method that will return us the list ob Book */ @GET("/RetrofitExample/books.json") public void getBooks(Callback<List<Book>> response); }
- Ở trên chúng ta đã định nghĩa một GET Request. Nếu bạn còn đang nhầm lẫn vê URL trong request trên thì thực tế là trong Retrofit chúng ta không cần phải điền toàn bộ URL. Ở đây chúng ta chỉ bỏ phần root của URL là http://www.simplifiedcoding.16mb.com/. Chúng ta sẽ định nghĩa root của URL trong MainActivity.java
- Chúng ta cũng định nghĩa một phương thức có một đối số Callback. Chúng tao có một callback của một List dữ liệu chúng ta đã định nghĩa trong ví dụ này là Book. Phương thức này sẽ trả về cho chúng ta một List Book.
- Trong Activity đầu tiên chúng ta sẽ hiển thị duy nhât tên của những quển sách trong một list. Khi người dùng Click trên mỗi Item của List chúng ta sẽ hiển thị chi tiết trong Activity tiếp theo.
- Tôi sẽ tạo một ShowBookDetails.java và activity_show_book_details.xml trong .xml file. Tôi sẽ tạo 4 TextView để hiển thị các trường book id, name, price and stock.
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_awidth="match_parent" android:orientation="vertical" android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" tools:context="net.simplifiedcoding.androidretrofitexample.ShowBookDetails"> <TextView android:id="@+id/textViewBookId" android:textSize="24dp" android:layout_awidth="match_parent" android:layout_height="wrap_content" /> <TextView android:id="@+id/textViewBookName" android:textSize="24dp" android:layout_awidth="match_parent" android:layout_height="wrap_content" /> <TextView android:id="@+id/textViewBookPrice" android:textSize="24dp" android:layout_awidth="match_parent" android:layout_height="wrap_content" /> <TextView android:id="@+id/textViewBookInStock" android:textSize="24dp" android:layout_awidth="match_parent" android:layout_height="wrap_content" /> </LinearLayout>
Bây giờ trong MainActivity.java
import android.app.ProgressDialog; import android.content.Intent; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.ListView; import java.util.List; import retrofit.Callback; import retrofit.RestAdapter; import retrofit.RetrofitError; import retrofit.client.Response; //Class having OnItemClickListener to handle the clicks on list public class MainActivity extends AppCompatActivity implements ListView.OnItemClickListener { //Root URL of our web service public static final String ROOT_URL = "http://simplifiedcoding.16mb.com/"; //Strings to bind with intent will be used to send data to other activity public static final String KEY_BOOK_ID = "key_book_id"; public static final String KEY_BOOK_NAME = "key_book_name"; public static final String KEY_BOOK_PRICE = "key_book_price"; public static final String KEY_BOOK_STOCK = "key_book_stock"; //List view to show data private ListView listView; //List of type books this list will store type Book which is our data model private List<Book> books; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //Initializing the listview listView = (ListView) findViewById(R.id.listViewBooks); //Calling the method that will fetch data getBooks(); //Setting onItemClickListener to listview listView.setOnItemClickListener(this); } private void getBooks(){ //While the app fetched data we are displaying a progress dialog final ProgressDialog loading = ProgressDialog.show(this,"Fetching Data","Please wait...",false,false); //Creating a rest adapter RestAdapter adapter = new RestAdapter.Builder() .setEndpoint(ROOT_URL) .build(); //Creating an object of our api interface BooksAPI api = adapter.create(BooksAPI.class); //Defining the method api.getBooks(new Callback<List<Book>>() { @Override public void success(List<Book> list, Response response) { //Dismissing the loading progressbar loading.dismiss(); //Storing the data in our list books = list; //Calling a method to show the list showList(); } @Override public void failure(RetrofitError error) { //you can handle the errors here } }); } //Our method to show list private void showList(){ //String array to store all the book names String[] items = new String[books.size()]; //Traversing through the whole list to get all the names for(int i=0; i<books.size(); i++){ //Storing names to string array items[i] = books.get(i).getName(); } //Creating an array adapter for list view ArrayAdapter adapter = new ArrayAdapter<String>(this,R.layout.simple_list,items); //Setting adapter to listview listView.setAdapter(adapter); } //This method will execute on listitem click @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { //Creating an intent Intent intent = new Intent(this, ShowBookDetails.class); //Getting the requested book from the list Book book = books.get(position); //Adding book details to intent intent.putExtra(KEY_BOOK_ID,book.getBookId()); intent.putExtra(KEY_BOOK_NAME,book.getName()); intent.putExtra(KEY_BOOK_PRICE,book.getPrice()); intent.putExtra(KEY_BOOK_STOCK,book.getInStock()); //Starting another activity to show book details startActivity(intent); } }
Bây giờ chúng ta cần code cho Activity thứ 2 ShowBookDetails.java để hiện thi chi tiết.
import android.content.Intent; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.widget.TextView; public class ShowBookDetails extends AppCompatActivity { //Defining views private TextView textViewBookId; private TextView textViewBookName; private TextView textViewBookPrice; private TextView textViewBookInStock; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_show_book_details); //Initializing Views textViewBookId = (TextView) findViewById(R.id.textViewBookId); textViewBookName = (TextView) findViewById(R.id.textViewBookName); textViewBookPrice = (TextView) findViewById(R.id.textViewBookPrice); textViewBookInStock = (TextView) findViewById(R.id.textViewBookInStock); //Getting intent Intent intent = getIntent(); //Displaying values by fetching from intent textViewBookId.setText(String.valueOf(intent.getIntExtra(MainActivity.KEY_BOOK_ID, 0))); textViewBookName.setText(intent.getStringExtra(MainActivity.KEY_BOOK_NAME)); textViewBookPrice.setText(intent.getStringExtra(MainActivity.KEY_BOOK_PRICE)); textViewBookInStock.setText(String.valueOf(intent.getIntExtra(MainActivity.KEY_BOOK_STOCK,0))); } }
Trên tôi đã trình bày với các bạn một ví dụ rất đơn giản về cách sử dụng Retrofit.Ngoài ra các bạn có thể tham khảo link sau để hiểu chi tiết hơn. https://futurestud.io/blog/android-basic-authentication-with-retrofit