Ehs*_*san 18 android download retrofit
我需要在我的应用程序中使用Retrofit库下载所有类型的文件(二进制文件,图像,文本等).网上的所有示例都使用HTML GET方法.我需要使用POST来防止自动缓存.
我的问题是如何在Retrofit中使用POST方法下载文件?
Sur*_*nav 14
在kotlin,这样做:
在您的服务添加方法中:
@Streaming
@GET
suspend fun downloadFile(@Url fileUrl:String): Response<ResponseBody>
Run Code Online (Sandbox Code Playgroud)
要从 ViewModel 调用此方法:
viewModelScope.launch {
val responseBody=yourServiceInstance.downloadFile(url).body()
saveFile(responseBody,pathWhereYouWantToSaveFile)
}
Run Code Online (Sandbox Code Playgroud)
保存文件:
fun saveFile(body: ResponseBody?, pathWhereYouWantToSaveFile: String):String{
if (body==null)
return ""
var input: InputStream? = null
try {
input = body.byteStream()
//val file = File(getCacheDir(), "cacheFileAppeal.srl")
val fos = FileOutputStream(pathWhereYouWantToSaveFile)
fos.use { output ->
val buffer = ByteArray(4 * 1024) // or other buffer size
var read: Int
while (input.read(buffer).also { read = it } != -1) {
output.write(buffer, 0, read)
}
output.flush()
}
return pathWhereYouWantToSaveFile
}catch (e:Exception){
Log.e("saveFile",e.toString())
}
finally {
input?.close()
}
return ""
}
Run Code Online (Sandbox Code Playgroud)
笔记:
refrofit客户端的基本 url 和传递给 downloadFile 的 url 使文件 url 有效:Retrofit 的 Base url + downloadFile 的方法 url = File url
这里我之前使用 suspend 关键字downloadFile从 ViewModel 调用它,我已经使用过viewModelScope.launch {}你可以根据你的调用端使用不同的协程范围。
现在pathWhereYouWantToSaveFile,如果要将文件存储到项目的文件目录中,可以执行以下操作:
Run Code Online (Sandbox Code Playgroud)val fileName=url.substring(url.lastIndexOf("/")+1) val pathWhereYouWantToSaveFile = myApplication.filesDir.absolutePath+fileName
Nav*_*yle 13
使用@Streaming
异步
编辑1
//On your api interface
@POST("path/to/your/resource")
@Streaming
void apiRequest(Callback<POJO> callback);
restAdapter.apiRequest(new Callback<POJO>() {
@Override
public void success(POJO pojo, Response response) {
try {
//you can now get your file in the InputStream
InputStream is = response.getBody().in();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void failure(RetrofitError error) {
}
});
Run Code Online (Sandbox Code Playgroud)
同步
//On your api interface
@POST("path/to/your/resource")
@Streaming
Response apiRequest();
Response response = restAdapter.apiRequest();
try {
//you can now get your file in the InputStream
InputStream is = response.getBody().in();
} catch (IOException e) {
e.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud)
khc*_*tro 10
对于 Kotlin,这有点简单。
接口服务
@GET
@Streaming
fun download(@Url url: String): Call<ResponseBody>
Run Code Online (Sandbox Code Playgroud)
API客户端
object ApiClient {
private val retrofit = ...
val service: ApiService = retrofit.create(ApiService::class.java)
}
Run Code Online (Sandbox Code Playgroud)
下载功能
fun download(urlString: String, target: File) {
val response = ApiClient.service.download(urlString).execute()
response.body()?.byteStream()?.use {
target.parentFile?.mkdirs()
FileOutputStream(target).use { targetOutputStream ->
it.copyTo(targetOutputStream)
}
} ?: throw RuntimeException("failed to download: $urlString")
}
Run Code Online (Sandbox Code Playgroud)
小智 6
您可以使用以下代码进行进度下载(Kotlin)
改装API服务
@Streaming
@GET
fun downloadFile(@Url fileUrl: String): Observable<Response<ResponseBody>>
Run Code Online (Sandbox Code Playgroud)
确保您添加 @Streaming用于大文件下载
并在活动或片段中粘贴以下代码
fun downloadfileFromRetrofit() {
val retrofit = Retrofit.Builder()
.baseUrl("ENTER_YOUR_BASE_URL")
.client(OkHttpClient.Builder().build())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create()).build()
val downloadService = retrofit.create(RetrofitApi::class.java)
downloadService.downloadFile("FILE_URL_PATH").observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io()).subscribe({
val task = object : AsyncTask<Void, Integer, Void>() {
override fun doInBackground(vararg voids: Void): Void? {
val writtenToDisk =writeResponseBodyToDisk(it.body()!!)
println("file download was a success? $writtenToDisk")
return null
}
}
task.execute()
}, {
print(it.message)
})
}
Run Code Online (Sandbox Code Playgroud)
下面是writeResponseBodyToDisk方法
fun writeResponseBodyToDisk(body: ResponseBody): Boolean {
val appDirectoryName = "YOUR_DIRECTORY_NAME"
val filename = "YOUR_FILE_NAME"
val apkFile = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), filename)
try {
var inputStream: InputStream? = null
var outputStream: OutputStream? = null
try {
val fileReader = ByteArray(4096)
val fileSize = body.contentLength()
var fileSizeDownloaded: Long = 0
inputStream = body.byteStream()
outputStream = FileOutputStream(apkFile)
while (true) {
val read = inputStream!!.read(fileReader)
if (read == -1) {
break
}
outputStream.write(fileReader, 0, read)
fileSizeDownloaded += read.toLong()
calulateProgress(fileSize.toDouble(),fileSizeDownloaded.toDouble()
println("file downloading $fileSizeDownloaded of $fileSize")
outputStream.flush()
return true
} catch (e: Exception) {
println(e.toString())
return false
} finally {
if (inputStream != null) {
inputStream!!.close()
}
outputStream?.close()
}
} catch (e: Exception) {
println(e.toString())
return false
}
}
Run Code Online (Sandbox Code Playgroud)
下面的方法是用于计算进度
fun calulateProgress(totalSize:Double,downloadSize:Double):Double{
return ((downloadSize/totalSize)*100)
}
Run Code Online (Sandbox Code Playgroud)
这是如何在Retrofit 2中下载文件
public interface ServerAPI {
@GET
Call<ResponseBody> downlload(@Url String fileUrl);
Retrofit retrofit =
new Retrofit.Builder()
.baseUrl("http://192.168.43.135/retro/") // REMEMBER TO END with /
.addConverterFactory(GsonConverterFactory.create())
.build();
}
//How To Call
public void download(){
ServerAPI api = ServerAPI.retrofit.create(ServerAPI.class);
api.downlload("http://192.168.43.135/retro/pic.jpg").enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
try {
File path = Environment.getExternalStorageDirectory();
File file = new File(path, "file_name.jpg");
FileOutputStream fileOutputStream = new FileOutputStream(file);
IOUtils.write(response.body().bytes(), fileOutputStream);
}
catch (Exception ex){
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
34248 次 |
| 最近记录: |