Sobes.tech
Middle

Jak zaimplementowałbyś ładowanie plików do aplikacji serwerowej?

sobes.tech AI

Odpowiedź od AI

Aby przesłać pliki, użyłbym MultipartBody z biblioteki Retrofit.

  1. Przygotowanie interfejsu API: Tworzymy interfejs z adnotacjami @Multipart i @POST. Metoda przyjmuje @Part dla pliku i innych części żądania, jeśli istnieją.

    interface FileApi {
        @Multipart
        @POST("/upload")
        suspend fun uploadFile(
            @Part file: MultipartBody.Part,
            @Part("description") description: RequestBody? = null
        ): Response<ResponseBody>
    }
    
  2. Tworzenie MultipartBody.Part: Konwertujemy File lub Uri na RequestBody, a następnie na MultipartBody.Part.

    // Dla File
    val file = File("ścieżka/do/pliku")
    val requestFile = file.asRequestBody("multipart/form-data".toMediaTypeOrNull())
    val filePart = MultipartBody.Part.createFormData("file", file.name, requestFile)
    
    // Dla Uri
    val uri = Uri.parse("...") // Uzyskujemy Uri
    val inputStream = context.contentResolver.openInputStream(uri)
    val requestBody = inputStream!!.readBytes().toRequestBody("multipart/form-data".toMediaTypeOrNull(), 0, inputStream.available())
    val filePart = MultipartBody.Part.createFormData("file", "nazwa_pliku", requestBody)
    

    Nazwa "file" w createFormData musi odpowiadać nazwie parametru oczekiwanej przez serwer.

  3. Tworzenie RequestBody dla innych części: Jeśli trzeba wysłać inne dane (tekst, liczby), używamy RequestBody.

    val description = "Opis pliku".toRequestBody("text/plain".toMediaTypeOrNull())
    
  4. Wykonanie żądania: Wywołujemy metodę z interfejsu Retrofit, przekazując utworzone części.

    // Wstrzykiwanie lub pobieranie instancji FileApi
    val api: FileApi = ...
    
    // W coroutine lub innym asynchronicznym kontekście
    try {
        val descriptionPart = "Mój plik".toRequestBody("text/plain".toMediaTypeOrNull())
        val fileToUpload = File("ścieżka/do/pliku")
        val requestFile = fileToUpload.asRequestBody("multipart/form-data".toMediaTypeOrNull())
        val filePart = MultipartBody.Part.createFormData("file", fileToUpload.name, requestFile)
    
        val response = api.uploadFile(filePart, descriptionPart)
    
        if (response.isSuccessful) {
            // Plik pomyślnie przesłany
        } else {
            // Obsługa błędów
        }
    } catch (e: Exception) {
        // Obsługa wyjątku
    }
    

Dodatkowe aspekty:

  • Postęp przesyłania: Można zaimplementować RequestBody z monitorowaniem postępu, aby wyświetlić wskaźnik ładowania.
  • Duże pliki: Dla bardzo dużych plików rozważyć streaming lub dzielenie na części.
  • Obsługa błędów: Sprawdzanie kodów odpowiedzi serwera i obsługa błędów sieciowych.
  • Uprawnienia: Upewnić się, że aplikacja ma uprawnienie do odczytu plików (READ_EXTERNAL_STORAGE na starszych wersjach Androida).
  • ViewModel/Repository: Umieścić logikę przesyłania pliku w repozytorium lub ViewModel dla lepszej architektury.
  • WorkManager: Używać do przesyłania w tle, które ma kontynuować nawet po zamknięciu aplikacji.

Zalety MultipartBody:

  • Standardowa metoda wysyłania plików z dodatkowymi danymi.
  • Obsługiwane przez większość frameworków serwerowych.
  • Dobrze integruje się z Retrofit.

To niezawodne i szeroko stosowane podejście do przesyłania plików w Android.