Bài viết tập trung minh họa cách dùng phương thức static để truyền dữ liệu giữa hai Activity. Đây là kỹ thuật cơ bản nhưng không khuyến khích cho production do rủi ro mất dữ liệu và memory leak.
Ví dụ minh họa
Bước 1: Tạo project Android Studio
File → New Project → Empty Activity → Finish.
Bước 2: Layout chính (res/layout/activity_main.xml)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="16dp"
android:orientation="vertical"
tools:context=".MainActivity">
<EditText
android:id="@+id/edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:hint="Nhập văn bản"
android:inputType="text" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="16dp"
android:text="Chuyển Activity" />
</LinearLayout>
Bước 3: MainActivity.java - Static holder
package com.example.myapplication;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
// Biến static lưu trữ tạm
private static String sharedData;
// Getter static để Activity khác truy cập
public static String getSharedData() {
return sharedData;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final EditText editText = findViewById(R.id.edit_text);
Button button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
sharedData = editText.getText().toString().trim();
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
startActivity(intent);
}
});
}
}
Bước 4: Layout phụ (res/layout/activity_second.xml)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="16dp"
android:orientation="vertical"
tools:context=".SecondActivity">
<TextView
android:id="@+id/text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textSize="18sp"
android:gravity="center" />
</LinearLayout>
Bước 5: SecondActivity.java - Gọi static getter
package com.example.myapplication;
import android.os.Bundle;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class SecondActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
TextView textView = findViewById(R.id.text_view);
// Truy cập trực tiếp phương thức static
String data = MainActivity.getSharedData();
textView.setText("Dữ liệu static: " + (data != null ? data : "null"));
}
}
Bước 6: AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
package="com.example.myapplication">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
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>
<activity android:name=".SecondActivity" />
</application>
</manifest>
Phân tích rủi ro
❌ Vấn đề nghiêm trọng:
- Process Death: Android có thể kill process app khi chạy background. Biến static reset về null. User quay lại app → crash hoặc dữ liệu mất.
- Memory Leak: Nếu static giữ reference Context, View, Bitmap → không GC được.
- Concurrency: Không thread-safe, dễ race condition.
- Testing: Global state khiến unit test khó kiểm soát, dễ flaky test.
Giải pháp thay thế an toàn
1. Intent + Bundle (Chuẩn)
// Sender
intent.putExtra("key", value);
// Receiver
getIntent().getStringExtra("key")
2. ViewModel (Kiến trúc MVVM - Khuyên dùng)
// SharedViewModel.kt
class SharedViewModel : ViewModel() {
val data = MutableLiveData<String>()
}
// Activity A
viewModel.data.value = "Hello"
startActivity(Intent(this, B::class.java))
// Activity B
viewModel.data.observe(this) { tv.text = it }
3. Application Class (Singleton toàn app)
class MyApp : Application() {
var globalData: String? = null
}
// Truy cập: (application as MyApp).globalData
Kết luận
Static method dễ hiểu cho người mới nhưng không phù hợp ứng dụng thực tế. Hãy thói quen dùng Intent cho navigation đơn giản, và ViewModel cho chia sẻ dữ liệu phức tạp, survive configuration change.