ภาพรวม
ตัวอย่างนี้สาธิตการใช้ StringRequest ของ Volley Library สำหรับ HTTP Request แบบ GET เพื่อดึงข้อมูล JSON/String จาก Server คล้ายกับ ID 1004061234 แต่เน้นรายละเอียด StringRequest โดยเฉพาะ
ขั้นตอนการสร้างโปรเจกต์
ขั้นตอนที่ 1: สร้างโปรเจกต์ใหม่
Android Studio → File → New Project → Empty Activity
ขั้นตอนที่ 2: เพิ่ม Dependency (build.gradle)
dependencies {
implementation 'com.android.volley:volley:1.2.1'
implementation 'com.android.support:appcompat-v7:28.0.0'
}
ขั้นตอนที่ 3: Layout (res/layout/activity_main.xml)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:app="https://schemas.android.com/apk/res-auto"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
tools:context=".MainActivity">
<TextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="16sp"
android:gravity="center"
android:padding="16dp"
android:text="Loading..." />
</LinearLayout>
ขั้นตอนที่ 4: โค้ดหลัก (src/MainActivity.java)
package com.example.myapplication;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.RequiresApi;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
public class MainActivity extends AppCompatActivity {
TextView textView;
RequestQueue queue;
String URL = "https://jsonplaceholder.typicode.com/posts/1";
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.text);
queue = Volley.newRequestQueue(this);
// StringRequest - GET
StringRequest stringRequest = new StringRequest(Request.Method.GET, URL,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
// Response มาเป็น Raw String (JSON Text)
textView.setText("Raw Response:\n" + response);
// Parse JSON เองหากต้องการ
try {
JSONObject json = new JSONObject(response);
String title = json.getString("title");
String body = json.getString("body");
textView.append("\n\n---\nParsed:\nTitle: " + title + "\nBody: " + body);
} catch (JSONException e) {
Log.e("Volley", "Parse error", e);
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
String errorMsg = "Error: ";
if (error.networkResponse != null) {
errorMsg += "HTTP " + error.networkResponse.statusCode;
}
errorMsg += " - " + error.getMessage();
textView.setText(errorMsg);
Log.e("Volley", errorMsg, error);
}
}
) {
// Override getHeaders() เพื่อเพิ่ม Headers (เช่น Authorization)
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = new HashMap<>();
headers.put("Authorization", "Bearer YOUR_TOKEN");
headers.put("Accept", "application/json");
return headers;
}
// Override getParams() สำหรับ POST Request
@Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
params.put("key1", "value1");
params.put("key2", "value2");
return params;
}
};
// ตั้งค่า Retry Policy
stringRequest.setRetryPolicy(new DefaultRetryPolicy(
10000, // Timeout 10 วินาที
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT
));
// เพิ่ม Tag เพื่อ Cancel ได้ภายหลัง
stringRequest.setTag("GET_POST_1");
queue.add(stringRequest);
}
@Override
protected void onStop() {
super.onStop();
// Cancel ทุก Request ที่มี Tag นี้ เมื่อ Activity หยุด
queue.cancelAll("GET_POST_1");
}
}
ขั้นตอนที่ 5: AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <application android:usesCleartextTraffic="true" ...> <!-- HTTP only -->
StringRequest vs JsonObjectRequest vs JsonArrayRequest
| Request Type | เหมาะสำหรับ | Response Parsing |
|---|---|---|
StringRequest | Plain text, HTML, XML, JSON (Raw) | Manual (JSONObject/JSONArray) |
JsonObjectRequest | JSON Object ({...}) | Auto (JSONObject) |
JsonArrayRequest | JSON Array ([...]) | Auto (JSONArray) |
StringRequest POST Example
StringRequest postRequest = new StringRequest(Request.Method.POST, LOGIN_URL,
response -> { /* Success */ },
error -> { /* Error */ }
) {
@Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<>();
params.put("username", "user123");
params.put("password", "pass123");
return params;
}
@Override
public Map<String, String> getHeaders() {
Map<String, String> headers = new HashMap<>();
headers.put("Content-Type", "application/x-www-form-urlencoded");
return headers;
}
};
Volley Request Lifecycle
1. new Request() → 2. queue.add() → 3. Cache Thread (Check Cache)
→ Hit: Parse & Deliver to Main Thread
→ Miss: Network Thread → HTTP Request → Response
→ Parse → Cache → Deliver to Main Thread
แนวทางปัจจุบัน (Modern Alternative)
Retrofit + OkHttp + Coroutines (Kotlin) เป็นมาตรฐานอุตสาหกรรม:
// Retrofit Interface
interface ApiService {
@GET("posts/{id}")
suspend fun getPost(@Path("id") id: Int): Response<Post>
}
// Usage
lifecycleScope.launch {
val response = apiService.getPost(1)
if (response.isSuccessful) {
textView.text = response.body()?.title
}
}
ข้อควรระวัง
- Volley Deprecated ไม่ได้ แต่ไม่ได้รับ Active Development มากนัก
- เหมาะสำหรับ Legacy Projects หรือ Simple Requests
- ใหญ่โปรเจกต์ใหม่ ใช้ Retrofit/Ktor + OkHttp + Coroutines/RxJava
- StringRequest ให้ Raw String ต้อง Parse เอง (Error-prone)
- จำเป็นต้อง Cancel Request ใน onStop/onDestroy ป้องกัน Memory Leak/Update UI หลัง Destroy