iT邦幫忙

2025 iThome 鐵人賽

DAY 23
0
Mobile Development

Android 開發者養成計畫:從程式邏輯到作品集實戰系列 第 23

Day23- 讓 App 連結全世界:網路連線 (HttpURLConnection)

  • 分享至 

  • xImage
  •  

在第二十二天,你已經成功地製作出一個可以左右滑動切換頁籤的 App。

但一個真正的 App,除了能夠處理內部資料,更需要能夠從網路上取得資料。例如:天氣 App 要從氣象局網站取得資料,新聞 App 要從新聞網站取得文章。

這時,我們就需要一個 App 的「網路線」,也就是今天的重點:網路連線

什麼是網路連線?

簡單比喻:網路連線就像是 App 的 「電話」

  • 你的 App 是一個「發話者」,它可以打電話給網站(伺服器)。
  • 網站是一個「接話者」,它會回傳資料給你。
  • 這個「電話」的溝通方式,就是我們所說的 HTTP (HyperText Transfer Protocol)

HttpURLConnection:最簡單的網路連線工具

簡單比喻HttpURLConnection 就像是 Android 內建的 「基本款電話」

  • 它可以幫你發送 GETPOST 請求,從網站取得資料。
  • 雖然功能陽春,但對於初學者來說,是最容易理解和入門的工具。

實作時間:打造一個「簡單查詢 App」

今天,我們要製作一個 App:當使用者點擊按鈕,App 就會去一個固定的網站取得一段文字,並將其顯示出來。

1. 在你的專案中新增網路權限

在 Android 中,任何需要網路連線的 App,都必須在 AndroidManifest.xml 中宣告權限。

  • 打開你的 app/manifests/AndroidManifest.xml 檔案。
  • <manifest> 標籤中,加入以下一行程式碼:
`<uses-permission android:name="android.permission.INTERNET" />`

2. 修改你的 activity_main.xml

我們需要一個 Button 觸發網路連線,和一個 TextView 顯示回傳的文字。

`<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical"
    android:padding="16dp">

    <Button
        android:id="@+id/fetchButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="從網路獲取資料" />

    <TextView
        android:id="@+id/resultTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="32dp"
        android:text="結果將顯示在這裡"
        android:textSize="20sp" />

</LinearLayout>`

3. 修改你的 MainActivity.java

這是最關鍵的部分。我們需要在一個子執行緒 (background thread) 中進行網路連線。因為如果網路連線太久,會導致 App 卡住,甚至被系統強制關閉。

  • 我們會使用一個簡單的 Thread 來實現。
`import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class MainActivity extends AppCompatActivity {

    private TextView resultTextView;
    private Button fetchButton;

    // 用來處理主執行緒和子執行緒之間的訊息傳遞
    private Handler mainHandler = new Handler(Looper.getMainLooper());

    @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 -> {
            // 在子執行緒中執行網路連線
            new Thread(new Runnable() {
                @Override
                public void run() {
                    fetchDataFromUrl();
                }
            }).start();
        });
    }

    private void fetchDataFromUrl() {
        HttpURLConnection urlConnection = null;
        try {
            // 建立 URL 物件,這裡我們使用一個簡單的範例網站
            URL url = new URL("https://jsonplaceholder.typicode.com/posts/1");

            // 打開連線
            urlConnection = (HttpURLConnection) url.openConnection();

            // 讀取回傳的資料
            BufferedReader reader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
            StringBuilder stringBuilder = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                stringBuilder.append(line).append("\n");
            }

            final String result = stringBuilder.toString();

            // 將結果傳回主執行緒,更新 UI
            mainHandler.post(() -> {
                resultTextView.setText(result);
                Toast.makeText(MainActivity.this, "資料獲取成功!", Toast.LENGTH_SHORT).show();
            });

        } catch (Exception e) {
            e.printStackTrace();
            // 在發生錯誤時,將錯誤訊息傳回主執行緒
            mainHandler.post(() -> {
                resultTextView.setText("網路連線失敗!");
                Toast.makeText(MainActivity.this, "網路連線失敗!", Toast.LENGTH_SHORT).show();
            });
        } finally {
            if (urlConnection != null) {
                urlConnection.disconnect();
            }
        }
    }
}`

執行你的 App!

  • 點擊綠色的「」按鈕,執行 App。
  • 點擊「從網路獲取資料」按鈕。
  • 你會看到 TextView 中顯示出從網路上取得的 JSON 資料!

day23

今日總結

今天我們學會了:

  • 如何在 AndroidManifest.xml 中宣告網路權限。
  • 如何使用 HttpURLConnection 進行基本的網路連線。
  • 非常重要的概念:網路連線必須在子執行緒中進行,並且必須使用 Handler 或其他機制,在主執行緒中更新 UI。

現在已經掌握了 App 效能優化的基礎。接下來,我們將會進入更專業的網路連線世界,用更強大的工具來優化我們的程式!

明天見!


上一篇
Day22- 最強組合技:ViewPager2 + TabLayout + Fragment
下一篇
Day24- App 的多工處理:執行緒與 Handler
系列文
Android 開發者養成計畫:從程式邏輯到作品集實戰25
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言