首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

Android Activity 與 Fragment 通信:文件路徑傳遞的三種標準模式

     編輯:程式設計疑難解答

場景定義

Activity 中獲取文件路徑(如選圖、拍照、下載完成),需傳遞給對應 Fragment 進行展示、處理或上傳。

三種傳遞模式

模式一:Fragment Arguments(靜態數據、創建時傳遞)⭐ 最常用

適用於:Fragment 尚未創建,或需隨 Activity 啟動時確定數據。

// Activity 中創建並傳遞
public void onFileSelected(String filePath) {
    MyFragment fragment = new MyFragment();
    Bundle args = new Bundle();
    args.putString("file_path", filePath);
    fragment.setArguments(args);
    
    getSupportFragmentManager().beginTransaction()
        .replace(R.id.container, fragment)
        .commit();
}

// Fragment 中接收
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (getArguments() != null) {
        String filePath = getArguments().getString("file_path");
        // 使用 filePath...
    }
}

模式二:接口回調(動態數據、Fragment 已存在)⭐ 靈活解耦

適用於:Fragment 已在容器中,Activity 異步獲得路徑(如權限請求後、網絡下載完成)。

// 1. 定義接口
public interface OnFilePathListener {
    void onFilePathReceived(String filePath);
}

// 2. Fragment 實現接口
public class MyFragment extends Fragment implements OnFilePathListener {
    @Override
    public void onFilePathReceived(String filePath) {
        // UI 線程更新
        requireActivity().runOnUiThread(() -> {
            // 更新 UI、啟動處理...
        });
    }
}

// 3. Activity 持有引用並回調
public class MainActivity extends AppCompatActivity {
    private OnFilePathListener fragmentListener;
    
    @Override
    public void onAttachFragment(@NonNull Fragment fragment) {
        super.onAttachFragment(fragment);
        if (fragment instanceof OnFilePathListener) {
            fragmentListener = (OnFilePathListener) fragment;
        }
    }
    
    // 文件獲取完成時
    private void onFileReady(String path) {
        if (fragmentListener != null) {
            fragmentListener.onFilePathReceived(path);
        }
    }
}

模式三:ViewModel 共享數據(生命週期感知、配置變更安全)⭐ 現代最佳實踐

適用於:Activity 與多個 Fragment 共享文件路徑,需跨配置變更(旋轉屏幕)保持數據。

// 1. 共享 ViewModel
public class SharedFileViewModel extends ViewModel {
    private final MutableLiveData _filePath = new MutableLiveData<>();
    public LiveData filePath = _filePath;
    
    public void setFilePath(String path) {
        _filePath.setValue(path);
    }
}

// 2. Activity 設置
public class MainActivity extends AppCompatActivity {
    private SharedFileViewModel viewModel;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        viewModel = new ViewModelProvider(this).get(SharedFileViewModel.class);
    }
    
    private void onFileReady(String path) {
        viewModel.setFilePath(path);
    }
}

// 3. Fragment 觀察
public class MyFragment extends Fragment {
    @Override
    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
        SharedFileViewModel viewModel = new ViewModelProvider(requireActivity())
            .get(SharedFileViewModel.class);
        
        viewModel.filePath.observe(getViewLifecycleOwner(), filePath -> {
            if (filePath != null) {
                // 使用 filePath...
            }
        });
    }
}

方案選擇決策樹

是否需要跨配置變更保持數據?
  是 → ViewModel (模式三)
  否 → Fragment 是否已創建?
         是 → 接口回調 (模式二)
         否 → Arguments (模式一)

最佳實踐清單

  1. ✅ 優先使用 ViewModel + LiveData:生命週期安全、自動處理配置變更、易測試
  2. ✅ 接口回調定義在單獨文件,避免循環依賴
  3. ✅ Arguments 只傳遞可序列化數據(String、Parcelable、Serializable)
  4. ✅ 異步操作結果回調時檢查 isAdded() / getViewLifecycleOwner() 確保 Fragment 存活
  5. ✅ 大文件路徑傳遞 Uri 而非 String:Uri.fromFile() / FileProvider 適配 Android 7.0+

參考資源

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved