2017-03-01 114 views
3

我有對象PhotoString imageUrl = "foo.png"如何通過OkHttpClient攔截器將baseUrl(主機)添加到畢加索?

而且具有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

畢加索拒絕您的請求,因爲它試圖根據圖像URL找到合適的'RequestHandler'實現。如果'(SCHEME_HTTP.equals(scheme)|| SCHEME_HTTPS.equals(scheme))''NetworkRequestHandler'只接受請求,並且會拒絕請求。所以,如果你想達到你的'Interceptor',恐怕你必須先建立完整的URL - 然後添加一個頭文件應該不成問題。 –

+0

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

回答

2

這裏的問題是,Picasso被拒絕您的請求,因爲它不承認Request的類型。所以沒有攔截請求。

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

你不應該在你的Interceptor裏面改變你的URL,應該事先做。您可以將Picasso.RequestTransformer添加到您的Picasso.Builder。按文件一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如預期

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

這裏是如何我們的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

也許你可以嘗試concat基地網址與每張照片的照片網址。

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。

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(); 

... 並最終構建畢加索實例:

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

那麼你可以使用它像@faranjit告訴你:

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);