2017-03-01 10 views
3

나는 String imageUrl = "foo.png"OkHttpClient Interceptor를 통해 Picasa에 baseUrl (호스트)을 추가하는 방법은 무엇입니까?

와 객체 Photo이 내가 가진 이미지를로드하기 위해 노력하고있어 String host = "http://example.com/photos/"

있습니다

mPicasso.load(photo.getImageUrl()).into(mImageView);

public Picasso providesPicasso(OkHttp3Downloader okHttpDownloader) { 
     return new Picasso.Builder(context).listener(new Picasso.Listener() { 
      @Override 
      public void onImageLoadFailed(Picasso picasso, Uri uri, Exception exception) { 
       exception.printStackTrace(); 
      } 
     }).downloader(okHttpDownloader) 
      .executor(Executors.newSingleThreadExecutor())//avoid OutOfMemoryError 
      .build(); 
    } 

    public OkHttp3Downloader providesPicassoOkHttpClient(Context context) { 
      File cacheDir = createDefaultCacheDir(context, BIG_CACHE_PATH); 
      long cacheSize = calculateDiskCacheSize(cacheDir); 
      OkHttpClient okHttpClient = new OkHttpClient.Builder() 
        .cache(new Cache(cacheDir, cacheSize)) 
        .addInterceptor(new Interceptor() { 
         @Override 
         public Response intercept(Chain chain) throws IOException { 
          Request request = chain.request(); 
          String host = "http://example.com/photos/"; 
          HttpUrl newUrl = request.url().newBuilder().host(host + request.url()).build(); 

          request = request.newBuilder().url(newUrl).build(); 
          return chain.proceed(request); 
         } 
        }) 
        .build(); 
      return new OkHttp3Downloader(okHttpClient); 
     } 
` 

오류 :

java.lang.IllegalStateException: Unrecognized type of request: Request{foo.png} 
03-01 14:06:49.856 19150-19150/com.basicflags W/System.err:  at com.squareup.picasso.BitmapHunter$2.load(BitmapHunter.java:66) 
03-01 14:06:49.856 19150-19150/com.basicflags W/System.err:  at com.squareup.picasso.BitmapHunter.hunt(BitmapHunter.java:206) 
03-01 14:06:49.856 19150-19150/com.basicflags W/System.err:  at com.squareup.picasso.BitmapHunter.run(BitmapHunter.java:159) 
03-01 14:06:49.856 19150-19150/com.basicflags W/System.err:  at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:423) 
03-01 14:06:49.856 19150-19150/com.basicflags W/System.err:  at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
03-01 14:06:49.856 19150-19150/com.basicflags W/System.err:  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) 
03-01 14:06:49.856 19150-19150/com.basicflags W/System.err:  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) 
03-01 14:06:49.856 19150-19150/com.basicflags W/System.err:  at java.lang.Thread.run(Thread.java:818) 
+0

Picasso는 이미지 URL을 기반으로 적절한 'RequestHandler' 구현을 찾으려고하기 때문에 요청을 거부합니다. 'NetworkRequestHandler'는'(SCHEME_HTTP.equals (scheme) || SCHEME_HTTPS.equals (scheme))'만 요청을 받아들이고 요청을 거부합니다. 그래서, 만약 당신이 당신의'Interceptor'에 도달하기를 원한다면, 앞장서 서 완전한 URL을 만들어야 할 것입니다 - 헤더가 문제가되지 않아야합니다. –

+0

https://gist.github.com/swankjesse/8571a8207a5815cca1fb – pouya

답변

2

Picasso가 여기에 문제가 있는지 : @faranjit 당신에게처럼

public Picasso providePicasso() { 
     return new Picasso.Builder(context) 
       .downloader(new OkHttp3Downloader(getOkHttpClient())) 
       .build(); 
    } 

그때 당신이 그것을 사용할 수 있습니다

public OkHttpClient getOkHttpClient() throws IOException { 
     OkhttpClient.Builder builder = new Builder() 
         .readTimeout(BuildConfig.CONNECTION_READ_TIMEOUT, TimeUnit.SECONDS) 
         .connectTimeout(BuildConfig.CONNECT_TIMEOUT, TimeUnit.SECONDS) 
         .addInterceptor(getDefaultHeaderInterceptor()) 
         .build(); 

... 그리고 마지막으로 피카소의 인스턴스를 생성 유형이 Request을 인식하지 못하기 때문에 요청을 거부합니다. 그래서 요격하라는 요구가 없습니다.

W/System.err: java.lang.IllegalStateException: Unrecognized type of request: Request{img_fjords.jpg} 

당신은 당신의 Interceptor 내부 URL을 변환하지 말아야하고 사전에 있음을해야한다. Picasso.BuilderPicasso.RequestTransformer을 추가 할 수 있습니다. 문서 당 같이 RequestTransformer은 다음과 같습니다

A transformer that is called immediately before every request is submitted. This can be used to modify any information about a request. For example, if you use a CDN you can change the hostname for the image based on the current location of the user in order to get faster download speeds.

public Picasso providesPicasso(OkHttp3Downloader okHttpDownloader) { 
    return new Picasso.Builder(context).listener(new Picasso.Listener() { 
     @Override 
     public void onImageLoadFailed(Picasso picasso, Uri uri, Exception exception) { 
      exception.printStackTrace(); 
     } 
    }) 
      .downloader(okHttpDownloader) 
      .requestTransformer(new Picasso.RequestTransformer() { 
       @Override 
       public com.squareup.picasso.Request transformRequest(com.squareup.picasso.Request request) { 
        Log.d(TAG, "nonTransformedRequest: " + request.uri.toString()); 

        String host = "https://www.w3schools.com/w3css/"; 
        com.squareup.picasso.Request build = new com.squareup.picasso.Request.Builder(Uri.parse(host + request.uri.toString())).build(); 

        Log.d(TAG, "transformedRequest: " + build.uri.toString()); 
        return build; 
       } 
      }) 
      .executor(Executors.newSingleThreadExecutor())//avoid OutOfMemoryError 
      .build(); 
} 

그리고 당신은에 나머지를 처리 ​​할 수 ​​Interceptor

public OkHttp3Downloader providesPicassoOkHttpClient(Context context) { 
     File cacheDir = createDefaultCacheDir(context, BIG_CACHE_PATH); 
     long cacheSize = calculateDiskCacheSize(cacheDir); 
     OkHttpClient okHttpClient = new OkHttpClient.Builder() 
       .cache(new Cache(cacheDir, cacheSize)) 
       .addInterceptor(new Interceptor() { 
        @Override 
        public Response intercept(Chain chain) throws IOException { 
         Request request = chain.request(); 
         Log.d(TAG, "URL in Interceptor: "+request.url()); 
         request = request.newBuilder().build(); //ADD HEADERS HERE 
         return chain.proceed(request); 
        } 
       }) 
       .build(); 
     return new OkHttp3Downloader(okHttpClient); 
    } 

이제 막 사용하여 여기에 어떻게

mPicasso.load(photo.getImageUrl()).into(mImageView); 

의도 mPicasso로 우리 LOG보기

02-15 15:10:14.767 6531-6531/com.smk.stack D/TAG: nonTransformedRequest: img_fjords.jpg 
02-15 15:10:14.767 6531-6531/com.smk.stack D/TAG: transformedRequest: https://www.w3schools.com/w3css/img_fjords.jpg 
02-15 15:10:14.828 6531-6590/com.smk.stack D/TAG: URL in Interceptor: https://www.w3schools.com/w3css/img_fjords.jpg 
+1

'request = request.buildUpon() 사용 필요 setUri 변환 손실을 피하기 위해 Uri.parse (host + request.uri.toString())). build();' – NickUnuchek

3

어쩌면 당신은 각 사진의 사진 URL로 concat 기본 URL을 시도 할 수 있습니다.

public static final String BASE_IMAGE_URL = "//your image host" 

... 

Picasso.with(getContext()).load(BASE_IMAGE_URL + "image url").into(your imageview); 
+0

그래, 그럴 수 있지만 요청할 헤더를 추가해야합니다 – NickUnuchek

2

우선, 인터셉터를 통해 요청에 헤더를 추가 할 수 있습니다.

private Interceptor getDefaultHeaderInterceptor() throws IOException { 
     return new Interceptor() { 
      @Override 
      public Response intercept(Chain chain) throws IOException { 
       Request.Builder requestBuilder = chain.request().newBuilder(); 
       requestBuilder.header(ApiConstants.ACCEPT_LANGUAGE, Locale.getDefault().getLanguage()); 
       requestBuilder.header(ApiConstants.AUTHORIZATION, oauthTokenStore.getAccessToken()); 
       return chain.proceed(requestBuilder.build()); 
      } 
     }; 
    } 

이와 같이 OkHttpClient를 만들 수 있습니다.

providePicasso().load(BASE_IMAGE_URL + "image url").into(your imageview); 
1

간단하게 유지하십시오! 수업이 Photo입니까? 문자열 리소스에 호스트 정의를 이동하는 방법 그것에

public String getFullUrl(Context context) { 
    return context.getString(R.string.host) + imageUrl; 
} 

추가 (보너스 : 당신은, 생산 등 준비 지금 예를 들면, 다른 구성을 위해 그것을 대체 할 수 있습니다).

추가 헤더가 필요한 경우 Interceptor에 추가하십시오.피카소의 경우 새로운 방법을 사용하십시오 :

mPicasso.load(photo.getFullUrl(getContext())).into(mImageView);