在第二十四天,你已經成功讓你的 App 擁有了「網路連線」的能力,可以從網路上獲取資料了!
但你可能也發現,用 HttpURLConnection
進行網路連線,需要寫很多程式碼(例如:建立 Thread
、讀取 InputStream
、處理 Handler
)。如果我們每次要連線都要重複寫這些程式碼,會非常麻煩。
這時,我們就需要一個更專業、更自動化的「網路電話」,也就是今天的重點:Retrofit
。
Retrofit
?Retrofit
就像是 App 的 「智慧型網路電話」。
Retrofit
會自動處理網路連線、錯誤處理、資料轉換等工作。今天,我們要用 Retrofit
來改造昨天的專案,讓 App 依然去同一個網站取得資料,但程式碼會變得更簡潔。
Retrofit
函式庫build.gradle (Module: app)
檔案。dependencies
區塊中,加入以下幾行程式碼:`dependencies {
// ... 其他 dependencies ...
// Retrofit 函式庫
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
// 將 JSON 轉換成 Java 物件的函式庫 (與 Retrofit 搭配使用)
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
}`
然後點擊右上角的 Sync Now
。
MainActivity.java
所在的資料夾,選擇 New
-> Java Class
-> Interface
。ApiService
。`import retrofit2.Call;
import retrofit2.http.GET;
public interface ApiService {
// 定義一個 GET 請求,用來取得文章
// @GET 註解告訴 Retrofit,這是一個 GET 請求
// "posts/1" 是相對於網址的「電話號碼」
@GET("posts/1")
Call<Post> getPost(); // Call 是 Retrofit 的回傳型別,<Post> 是我們要接收的資料型別
}`
userId
, id
, title
, body
這幾個欄位。我們需要建立一個對應的 Java 類別來接收。Post
。`import com.google.gson.annotations.SerializedName;
public class Post {
@SerializedName("userId")
private int userId;
@SerializedName("id")
private int id;
@SerializedName("title")
private String title;
@SerializedName("body")
private String body;
// 這裡可以加上 getter 方法,方便我們取得資料
public String getTitle() {
return title;
}
}`
MainActivity.java
這是最後一步。我們只需要用 Retrofit
建立一個實例,然後呼叫我們定義好的方法即可!
`import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class MainActivity extends AppCompatActivity {
private TextView resultTextView;
private Button fetchButton;
// 網站的「總機」號碼
private static final String BASE_URL = "https://jsonplaceholder.typicode.com/";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
resultTextView = findViewById(R.id.resultTextView);
fetchButton = findViewById(R.id.fetchButton);
fetchButton.setOnClickListener(v -> fetchDataWithRetrofit());
}
private void fetchDataWithRetrofit() {
// 1. 建立 Retrofit 實例
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL) // 你的網站總機號碼
.addConverterFactory(GsonConverterFactory.create()) // 啟用 JSON 資料轉換
.build();
// 2. 建立 ApiService 介面實例
ApiService apiService = retrofit.create(ApiService.class);
// 3. 呼叫你的「電話號碼」 (getPost 方法)
Call<Post> call = apiService.getPost();
// 4. 非同步執行請求
call.enqueue(new Callback<Post>() {
@Override
public void onResponse(Call<Post> call, Response<Post> response) {
if (response.isSuccessful() && response.body() != null) {
// 請求成功!自動將 JSON 轉換成 Post 物件
Post post = response.body();
resultTextView.setText(post.getTitle()); // 取得 title 並顯示
Toast.makeText(MainActivity.this, "資料獲取成功!", Toast.LENGTH_SHORT).show();
} else {
resultTextView.setText("資料獲取失敗!");
}
}
@Override
public void onFailure(Call<Post> call, Throwable t) {
// 網路連線失敗
resultTextView.setText("網路連線失敗!");
t.printStackTrace();
}
});
}
}`
Retrofit.Builder()
:用來建立 Retrofit
實例,你只需要設定好網站的「總機號碼」(baseUrl
)。create(ApiService.class)
:這會自動幫你創建 ApiService
介面的實例。call.enqueue(...)
:這就是非同步請求的關鍵。Retrofit
會自動在背景執行請求,並在成功 (onResponse
) 或失敗 (onFailure
) 時回傳結果。TextView
中顯示出從網路上取得的 title
文字!今天我們學會了:
Retrofit
的概念,以及它比 HttpURLConnection
的優勢。Retrofit
和 Gson
來處理網路連線和資料轉換。你已經掌握了 App 開發最核心的幾大技能!接下來的幾天,我們將會進入綜合實作,將所有學過的知識串聯起來,完成一個更完整的 App 專案。
明天見!