Androidネットワークオープンソースライブラリ-Retrofit(3)一括アップロードおよびアップロード進捗リスニング
25748 ワード
1.はじめに
前回のブログでは、Retrofitのファイルアップロード、ファイルダウンロード、および進捗リスニングについて説明しましたが、このブログでは、次の一括アップロードおよびアップロードの進捗のリスニングについて説明します.
2.一括アップロード
一括アップロードを実現するには、HTMLで一括アップロードを実現する方法を考え、Formフォームを利用するので、Formフォームを利用して一括アップロードを実現することもできます.
2.1 HTML FORMフォームの書き方
<html>
<body>
<form action="http://localhost/fileabout.php" enctype="multipart/form-data" method="post">
<p>First name: <input type="file" name="file[]" id="name1" />p>
<p>First name: <input type="file" name="file[]" id="name2" />p>
<p>First name: <input type="file" name="file[]" id="name3" />p>
<input type="submit" value="Submit" />
form>
body>
html>
header('Content-Type:text/html;charset=utf-8');
$fileArray = $_FILES['file'];// , : []
$upload_dir = "D:\WWW"."\\"; //
foreach ( $fileArray['error'] as $key => $error) {
if ( $error == UPLOAD_ERR_OK ) { //PHP UPLOAD_ERR_OK=0,
$temp_name = $fileArray['tmp_name'][$key];
$file_name = $fileArray['name'][$key];
move_uploaded_file($temp_name, $upload_dir.$file_name);
echo ' [ '.$file_name.'] !
';
}else {
echo ' [ '.$key.'] !
';
}
}
array(1) {
["file"]=> array(5) {
["name"]=> array(3) {
[0]=> string(5) "1.txt"
[1]=> string(5) "2.txt"
[2]=> string(5) "3.txt" }
["type"]=> array(3) {
[0]=> string(10) "text/plain"
[1]=> string(10) "text/plain"
[2]=> string(10) "text/plain" }
["tmp_name"]=> array(3) {
[0]=> string(27) "C:\Windows\Temp\phpB829.tmp"
[1]=> string(27) "C:\Windows\Temp\phpB82A.tmp"
[2]=> string(27) "C:\Windows\Temp\phpB82B.tmp" }
["error"]=> array(3) {
[0]=> int(0)
[1]=> int(0)
[2]=> int(0) }
["size"]=> array(3) {
[0]=> int(11)
[1]=> int(13)
[2]=> int(13) }
}
*私のphpは毛皮の中の毛皮しか点けませんので、上の内容ははっきりしないか正しくないかもしれません.*私のphpは毛皮の中の毛皮しか点けませんので、上の内容ははっきりしないか正しくないかもしれません.*私のphpは毛皮の中の毛皮しか点けませんので、上の内容ははっきりしないか正しくないかもしれません.*を指摘してください.*
2.3プレゼンテーション結果
ブログ見えない?私に図を見せて
2.4 Androidでの実装-方法一(low)
```
@Multipart
@POST("/fileabout.php")
Call upload_2(@Part("filedes") String des,@Part("file[]\"; filename=\"1.txt") RequestBody imgs,@Part("file[]\"; filename=\"2.txt") RequestBody imgs_2,@Part("file[]\"; filename=\"3.txt") RequestBody imgs_3) ;
File file = new File(Environment.getExternalStorageDirectory() + "/" + "1.txt");
File file2 = new File(Environment.getExternalStorageDirectory() + "/" + "2.txt");
File file3 = new File(Environment.getExternalStorageDirectory() + "/" + "3.txt");
final RequestBody requestBody =
RequestBody.create(MediaType.parse("multipart/form-data"),file);
final RequestBody requestBody2 =
RequestBody.create(MediaType.parse("multipart/form-data"),file2);
final RequestBody requestBody3 =
RequestBody.create(MediaType.parse("multipart/form-data"),file3);
Call<String> model = service.upload_2("this is txt",requestBody,requestBody2,requestBody3);
上記の方法は柔軟性のある科学研究がないので、使用価値がありません.では、私たちは次の方法を使う必要があります.
2.5 Androidでの実現方法(二)
対応するapiインタフェースがこのようになりました
@Multipart
@POST("/fileabout.php")
Call upload_3(@Part("filedes") String des,@PartMap Map params) ;
Map<String,RequestBody> params = new HashMap<String, RequestBody>();
params.put("file[]\"; filename=\""+file.getName()+"", requestBody);
params.put("file[]\"; filename=\""+file2.getName()+"", requestBody2);
params.put("file[]\"; filename=\""+file3.getName()+"", requestBody3);
Call<String> model = service.upload_3("hello",params);
柔軟性が向上したのではないでしょうか.これでformフォームのように、自由に構成できます.
2.6結果表示
ブログ見えない?私はここまで図を见て、私达のロットのアップロードは终わって、もし各位の友达は何かもっと良い方法があるならば、私に教えてもらいます...
3.アップロード進捗の傍受
この問題を考えたとき、全く考えがなかったので、気まずい思いをしました.よく考えてみると、やはり考えがありません.では、githubで公式に与えられたいくつかのクラスを見てみましょう.この類を見てこの類恩を見て、私は2枚の図をあげて、みんなは自分でブログを観察して見えませんか?ブログを見ても見えませんか?図を見て気づいたか?変換器にRequestBodyが現れて、これは私に瞬間的に考えさせて、間違いなく、私たちはダウンロードの方法を真似て、同じように、この種類を改造します.
3.1 ChunkingConverterFactoryの改造
まず、私たちは中のRequestBodyを捨てて、私たちは手動で中に伝えます.つまり、次のコードを削除します.
final RequestBody realBody = delegate.convert(value)
第2ステップでは,return new RequestBody()関連コードに長さ情報がないことを見出した.コードを追加します.
@Override
public long contentLength() throws IOException {
return requestBody.contentLength();
}
第3部はダウンロードの過程をまねて、アップロードの過程を書いて、コードは以下の通りです
@Override
public void writeTo(BufferedSink sink) throws IOException{
// realBody.writeTo(sink);
if (bufferedSink == null) {
//
bufferedSink = Okio.buffer(sink(sink));
}
//
requestBody.writeTo(bufferedSink);
// flush,
bufferedSink.flush();
}
private Sink sink(Sink sink) {
return new ForwardingSink(sink) {
//
long bytesWritten = 0L;
// , contentLength()
long contentLength = 0L;
@Override
public void write(Buffer source, long byteCount) throws IOException {
super.write(source, byteCount);
if (contentLength == 0) {
// contentLength ,
contentLength = contentLength();
}
//
bytesWritten += byteCount;
//
listener.onProgress(bytesWritten, contentLength, bytesWritten == contentLength);
}
};
}
最後に、このクラスはこのようになりました.皆さんも私のgithubに行ってこのクラスをダウンロードすることができます.リンクアドレス
public class ChunkingConverterFactory extends Converter.Factory {
@Target(PARAMETER)
@Retention(RUNTIME)
@interface Chunked {
}
private BufferedSink bufferedSink;
private final RequestBody requestBody;
private final ProgressListener listener;
public ChunkingConverterFactory(RequestBody requestBody,ProgressListener listener){
this.requestBody = requestBody;
this.listener = listener ;
}
@Override
public Converter, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
boolean isBody = false;
boolean isChunked = false;
for (Annotation annotation : parameterAnnotations){
isBody |= annotation instanceof Body;
isChunked |= annotation instanceof Chunked;
}
final Converter
3.2アップロードの進行状況を監視する
ダウンロードするように、私たちはbuilderでbuildオブジェクトに行きます.もちろん普通の方法も使えますが、RequestBodyを前に書かなければなりません.これは少し変に見えます.コード全体は次のとおりです.
private void uploadProgress(){
Retrofit.Builder builder = new Retrofit.Builder()
.baseUrl("http://192.168.56.1");
File file = new File(Environment.getExternalStorageDirectory() + "/" + "text_img.png");
final RequestBody requestBody =
RequestBody.create(MediaType.parse("multipart/form-data"),file);
uploadfileApi api = builder.addConverterFactory(new ChunkingConverterFactory(requestBody, new ProgressListener() {
@Override
public void onProgress(long progress, long total, boolean done) {
Log.e(TAG, "onProgress: " + progress + "total ---->" + total );
Log.e(TAG, "onProgress: " + Looper.myLooper());
}
})).addConverterFactory(GsonConverterFactory.create()).build().create(uploadfileApi.class);
Call model = api.upload("hh",requestBody);
model.enqueue(new Callback() {
@Override
public void onResponse(Call call, Response response) {
}
@Override
public void onFailure(Call call, Throwable t) {
}
});
}
3.3結果のプレゼンテーション
ブログ見えない?私に図を見せて
3.4一括アップロードの進捗監視
私たちはどのように単一のファイルのアップロードの進度を傍受するかを知っていて、複数のファイル、うん、言わないでください、(複数の変換器を追加します).
4.まとめ
Retrofitはとても强大で、ある学友は私にRxjavaに协力して书きたいと思って、ああ、友达、メンツをあげて、どうにか私の第1篇の基础の使い方を见てみます.まだたくさんの机能が绍介されていないので、友达が何か必要なものがあるかを见て、私に伝言を残して、一绪に研究を终えましょう.