Android Retrofit 다 중 이미지/파일,그림 업로드 기능 구현

9244 단어 androidretrofit
Retrofit 가 뭐 예요?
Retrofit 는 Square 가 개발 한 안 드 로 이 드 와 자바 의 REST 클 라 이언 트 라 이브 러 리 입 니 다.이 라 이브 러 리 는 매우 간단 하고 많은 특성 을 가지 고 있어 다른 네트워크 라 이브 러 리 에 비해 초보 자 들 이 신속하게 파악 할 수 있다.GET,POST,PUT,DELETE...등 요청 을 처리 할 수 있 고 picasso 로 그림 을 불 러 올 수 있 습 니 다.
1.다시 한번 Retrofit 경 배
Retrofit 는 성능 이 든 사용 편의 성 이 든 모두 대단 하 다...본 고 는 그 운영 원 리 를 소개 하지 않 고(알 고 싶 지만)다음 에 전문 적 인 글 을 통 해 Retrofit 의 내부 원 리 를 해석 할 것 이다.본 고 는 단지 Retrofit 를 사용 하여 다 중 이미지/파일,그림 업로드 기능 을 실현 하 는 것 을 분석 할 뿐이다.
개념 소개
1)주석@Multipart
말 그대로 멀티미디어 파일 과 관련 된 것 입 니 다.맞습니다.그림,파일 등의 업 로드 는 모두 이 주석 을 사용 해 야 합 니 다.그 중에서 각 부분 은@Part 로 주석 을 달 아야 합 니 다.주석 을 보다

/** 
 * Denotes that the request body is multi-part. Parts should be declared as parameters and 
 * annotated with {@link Part @Part}. 
 */ 
2)주해@PartMap
물론@PartMap 주석 을 사용 하여 여러 파 트 를 전달 하여 다 중 파일 업 로드 를 실현 하 는 것 으로 이해 할 수 있다.주석

/** 
 * Denotes name and value parts of a multi-part request. 
 * <p> 
 * Values of the map on which this annotation exists will be processed in one of two ways: 
 * <ul> 
 * <li>If the type is {@link okhttp3.RequestBody RequestBody} the value will be used 
 * directly with its content type.</li> 
 * <li>Other object types will be converted to an appropriate representation by using 
 * {@linkplain Converter a converter}.</li> 
 * </ul> 
 * <p> 
 * <pre><code> 
 * @Multipart 
 * @POST("/upload") 
 * Call<ResponseBody> upload( 
 * @Part("file") RequestBody file, 
 * @PartMap Map<String, RequestBody> params); 
 * </code></pre> 
 * <p> 
 * A {@code null} value for the map, as a key, or as a value is not allowed. 
 * 
 * @see Multipart 
 * @see Part 
 */ 
3)RequestBody
위의 주석 에서 보 듯 이 매개 변수 유형 은 RequestBody 이 고 요청 체 입 니 다.파일 을 업로드 하려 면 RequestBody 라 는 인자 가 필요 합 니 다.공식 사용 설명 은 다음 과 같다http://square.github.io/retrofit/.
Multipart parts use one of Retrofit's converters or they can implement RequestBody to handle their own serialization. 
4.기본 실현
이상 의 개념 을 이해 하면,아래 에서 하나하나 실현 한다.
1)인터페이스 정의

public interface IHttpService { 
@Multipart 
 @POST("nocheck/file/agree.do") 
 Call<BaseBean> upLoadAgree(@PartMap Map<String, RequestBody>params); 
} 
BaseBean 은 서버 에서 데 이 터 를 되 돌려 주 는 것 에 따라 정 의 됩 니 다.이 사용 시 자체 서버 에 따라 정의 할 수 있 습 니 다.
2)Retrofit 실현

/** 
 * Created by DELL on 2017/3/16. 
 *      (    ) 
 */ 
public class RetrofitHttpUpLoad { 
 /** 
 *     60s 
 */ 
 private static final long DEFAULT_TIMEOUT = 60; 
 private volatile static RetrofitHttpUpLoad mInstance; 
 public Retrofit mRetrofit; 
 public IHttpService mHttpService; 
 private Map<String, RequestBody> params = new HashMap<String, RequestBody>(); 
 private RetrofitHttpUpLoad() { 
 mRetrofit = new Retrofit.Builder() 
  .baseUrl(UrlConfig.ROOT_URL) 
  .client(genericClient()) 
  .addConverterFactory(GsonConverterFactory.create()) 
  .build(); 
 mHttpService = mRetrofit.create(IHttpService.class); 
 } 
 public static RetrofitHttpUpLoad getInstance() { 
 if (mInstance == null) { 
  synchronized (RetrofitHttpUpLoad.class) { 
  if (mInstance == null) 
   mInstance = new RetrofitHttpUpLoad(); 
  } 
 } 
 return mInstance; 
 } 
 /** 
 *         ,http     
 * 
 * @return 
 */ 
 public static OkHttpClient genericClient() { 
 HttpLoggingInterceptor logging = new HttpLoggingInterceptor(); 
 logging.setLevel(HttpLoggingInterceptor.Level.BODY); 
 OkHttpClient httpClient = new OkHttpClient.Builder() 
  .addInterceptor(logging) 
  .connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS) 
  .writeTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS) 
  .readTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS) 
  .build(); 
 return httpClient; 
 } 
 /** 
 *  call          
 * 
 * @param call     call 
 * @param retrofitCallBack    
 * @param method        ,    
 * @param <T>       
 */ 
 public static <T> void addToEnqueue(Call<T> call, final RetrofitCallBack retrofitCallBack, final int method) { 
 final Context context = MyApplication.getContext(); 
 call.enqueue(new Callback<T>() { 
  @Override 
  public void onResponse(Call<T> call, Response<T> response) { 
  LogUtil.d("retrofit back code ====" + response.code()); 
  if (null != response.body()) { 
   if (response.code() == 200) { 
   LogUtil.d("retrofit back body ====" + new Gson().toJson(response.body())); 
   retrofitCallBack.onResponse(response, method); 
   } else { 
   LogUtil.d("toEnqueue, onResponse Fail:" + response.code()); 
   ToastUtil.makeShortText(context, "      " + response.code()); 
   retrofitCallBack.onFailure(response, method); 
   } 
  } else { 
   LogUtil.d("toEnqueue, onResponse Fail m:" + response.message()); 
   ToastUtil.makeShortText(context, "      " + response.message()); 
   retrofitCallBack.onFailure(response, method); 
  } 
  } 
  @Override 
  public void onFailure(Call<T> call, Throwable t) { 
  LogUtil.d("toEnqueue, onResponse Fail unKnown:" + t.getMessage()); 
  t.printStackTrace(); 
  ToastUtil.makeShortText(context, "      " + t.getMessage()); 
  retrofitCallBack.onFailure(null, method); 
  } 
 }); 
 } 
 /** 
 *      
 *       Object      String  File      
 */ 
 public RetrofitHttpUpLoad addParameter(String key, Object o) { 
 if (o instanceof String) { 
  RequestBody body = RequestBody.create(MediaType.parse("text/plain;charset=UTF-8"), (String) o); 
  params.put(key, body); 
 } else if (o instanceof File) { 
  RequestBody body = RequestBody.create(MediaType.parse("multipart/form-data;charset=UTF-8"), (File) o); 
  params.put(key + "\"; filename=\"" + ((File) o).getName() + "", body); 
 } 
 return this; 
 } 
 /** 
 *   RequestBody 
 */ 
 public Map<String, RequestBody> bulider() { 
 return params; 
 } 
} 
그 중에서 Retrofit 인 스 턴 스 를 정의 하고 차단기 로 통 일 된 시간 초과 와 로그 인쇄 를 정의 합 니 다.콜 을 대기 열 에 추가 하고 리 셋 을 실현 합 니 다.가장 중요 한 것 은 파 라 메 터 를 추가 하 는 것 입 니 다.

/** *      
 *       Object      String  File      
 */ 
 public RetrofitHttpUpLoad addParameter(String key, Object o) { 
 if (o instanceof String) { 
  RequestBody body = RequestBody.create(MediaType.parse("text/plain;charset=UTF-8"), (String) o); 
  params.put(key, body); 
 } else if (o instanceof File) { 
  RequestBody body = RequestBody.create(MediaType.parse("multipart/form-data;charset=UTF-8"), (File) o); 
  params.put(key + "\"; filename=\"" + ((File) o).getName() + "", body); 
 } 
 return this; 
 } 
들 어 오 는 매개 변수 에 따라 RequestBody 를 되 돌려 줍 니 다.
3)사용

private void upLoadAgree() { 
 showWaitDialog(); 
 RetrofitHttpUpLoad retrofitHttpUpLoad = RetrofitHttpUpLoad.getInstance(); 
 if (!StringUtil.isEmpty(pathImage[0])){ 
  retrofitHttpUpLoad = retrofitHttpUpLoad.addParameter("pic1",new File(pathImage[0])); 
 } 
 if (!StringUtil.isEmpty(pathImage[1])){ 
  retrofitHttpUpLoad = retrofitHttpUpLoad.addParameter("pic2", new File(pathImage[1])); 
 } 
 if (!StringUtil.isEmpty(pathImage[2])){ 
  retrofitHttpUpLoad = retrofitHttpUpLoad.addParameter("zip", new File(pathImage[2])); 
 } 
 Map<String, RequestBody> params = retrofitHttpUpLoad 
  .addParameter("status", "4") 
  .addParameter("pickupId", tv_orderquality_pid.getText().toString()) 
  .addParameter("cause", reason) 
  .addParameter("connectname", et_orderquality_lxrname.getText().toString()) 
  .addParameter("connectphone", et_orderquality_lxrphone.getText().toString()) 
  .addParameter("details", et_orderquality_xqms.getText().toString()) 
  .bulider(); 
 RetrofitHttpUpLoad.addToEnqueue(RetrofitHttpUpLoad.getInstance().mHttpService.upLoadAgree(params), 
  this, HttpStaticApi.HTTP_UPLOADAGREE); 
 } 
주의해 야 할 것 은 그림 과 파일 경 로 를 공백 으로 판단 하 는 것 입 니 다.이상 W/System.err:java.io.FileNotFoundException:/:open failed:EISDIR(Is a directory)을 보고 합 니 다.
위 에서 말 한 것 은 소 편 이 소개 한 안 드 로 이 드 는 Retrofit 를 바탕 으로 다 중 이미지/파일,그림 업로드 기능 을 실현 하여 여러분 에 게 도움 이 되 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 메 시 지 를 남 겨 주세요.소 편 은 제때에 답 해 드 리 겠 습 니 다.여기 서도 저희 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!

좋은 웹페이지 즐겨찾기