Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Android

Truyền dữ liệu giữa Activity Android: Static Method

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:

  1. 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.
  2. Memory Leak: Nếu static giữ reference Context, View, Bitmap → không GC được.
  3. Concurrency: Không thread-safe, dễ race condition.
  4. 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.