AndroidのRetrofit 2使用に関する質問のまとめ

12203 ワード

Retrofit 2参照依存問題
    compile 'io.reactivex:rxjava:1.1.3'
    compile 'io.reactivex:rxandroid:1.1.0'
    compile 'com.squareup.retrofit2:retrofit:2.0.2'
    compile 'com.squareup.retrofit2:converter-gson:2.0.2'
    compile 'com.squareup.retrofit2:converter-scalars:2.0.2'
    compile 'com.squareup.retrofit2:adapter-rxjava:2.0.2'
    compile 'com.jakewharton:butterknife:7.0.1'
    compile 'com.squareup.okhttp3:okhttp:3.2.0'
    compile 'com.squareup.okio:okio:1.8.0'

ここでいくつかの穴に出会って、もし下の3つが1つ足りないならば、彼が支持しない結果を返す時、崩壊して、これも上がどうしてそんなに多くのバッグを導く原因です.
private static Retrofit getRetrofit(String url) {
        return new Retrofit.Builder().baseUrl(url)
                //      String   
                .addConverterFactory(ScalarsConverterFactory.create())
                //      Gson   (      )
                .addConverterFactory(GsonConverterFactory.create())
                //      Oservable<T>   
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .build();
    }

GETリクエスト
http://wthrcdn.etouch.cn/weather_mini?city=深セン
public interface IWeather {
        @GET("/weather_mini")
        Observable<Weather> getWeather(@Query("city") String city);
}
 public static final String url_weather = "http://wthrcdn.etouch.cn";
 public static IWeather getIWeather() {
        return getRetrofit(url_weather).create(IWeather.class);
    }
HttpUtil.getIWeather().getWeather("  ")
                        .subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe(new Action1<Weather>() {
                            @Override
                            public void call(Weather weather) {
                                tv.setText(weather.getData().getGanmao());
                            }
                        });

Postリクエスト
バックグラウンドによると、MultipartやFormUrlEncodedは、両方とも試したほうがいいと知らなかったら、私もここで大きな穴に遭遇しましたが、やり方が間違っていたら、全然postには上がらなかったです.
Multipart
http://122.114.38.95:8857 (これは自分のサーバーを使っていますが、後ろの人はこのブログを見てこのapiは使えないかもしれません)パラメータはactionで、action=bannerで正しい結果を返すことができます.そうしないと間違った結果になります.
 @Multipart @POST("/") Observable<String> getBanner(@Part("action") String action);
public static final String url_bannertest = "http://122.114.38.95:8857";
public static IBannerTest getBanner() {
        return getRetrofit(url_bannertest).create(IBannerTest.class);
    }
HttpUtil.getBanner().getBanner("banner")
                        .subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe(new Action1<String>() {
                            @Override
                            public void call(String s) {
                                tv.setText(s);
                            }
                        });

postアップロード画像
ここではimage++を使ったインタフェースです.http://apicn.imageplusplus.com/analyze? パラメータ:api_key,api_secret, img
@Multipart
    @POST("/analyze")
    Observable<String> upLoadImage( @Part("api_key") String api_key, @Part ("api_secret") String api_secret,@Part MultipartBody.Part file );
public static final String imagepp_url = "http://apicn.imageplusplus.com";
 public static IImagePP getIImagePP() {
        return getRetrofit(imagepp_url).create(IImagePP.class);
    }

 public static MultipartBody.Part postFileParams(String key, File file) {
        RequestBody fileBody = RequestBody.create(MediaType.parse("image/*"), file);
        return MultipartBody.Part.createFormData(key, file.getName(), fileBody);
    }
File file = new File(Environment.getExternalStorageDirectory()+"/123.png");
                HttpUtil.getIImagePP().upLoadImage("c1a2b3ab56a2f218aed9b2ab3c16ce88","be8318b73cef1c2bcafb6c8a77922436",HttpUtil.postFileParams("img", file))
                        .subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe(new Action1<String>() {
                            @Override
                            public void call(String s) {
                                tv.setText(s);
                            }
                        });

ここではokhttpの特性を用いたが,これもokhttpをインポートする理由である.
private static Retrofit getRetrofit(String url) {
        return new Retrofit.Builder().baseUrl(url)
                .addConverterFactory(ScalarsConverterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .build();
    }

Retrofitには3つの文が入っています.ScalarsConverterFactoryは、リターンStringタイプGsonConverterFactoryをサポートし、リターンエンティティークラスをサポートします.RxJavaCallAdapterFactoryは、rxJavaを返すことをサポートするObservableです.
上記の例Getリクエストは、GsonConverterFactoryおよびRxJavaCallAdapterFactoryを使用しています.PostはScalarsConverterFactoryとRxJavaCallAdapterFactoryのどちらも跳ぶことが少ないので、retrofitを使うには注意が必要です.
スレッド(Scheduler)
SchedulerはRxJavaのスレッドスケジューラで、コード実行のスレッドを指定できます.RxJavaにはいくつかのスレッドが内蔵されています.
Android Schedulers.mainThread()メインスレッド
Schedulers.immediate()現在のスレッド、すなわちデフォルトのScheduler
Schedulers.newThread()新規スレッドの有効化
Schedulers.io()IOスレッドは、ファイル、データベース、ネットワーク操作が可能な上限のないスレッドプールです.
Schedulers.computation()CPU計算用のスレッドは、内部にCPUコア数に固定されたスレッドプールがあり、CPU密集型計算に適しており、ファイル、データベース、ネットワークを操作できない.
実際のプロジェクトでは、SchedulersはnewThreadかioかを選択します.
一般的なネットワーク要求はioを使用するべきで、ioは無限のスレッドプールを使用しているため、newThreadはスレッドプールのメンテナンスがありません
参照先:http://blog.csdn.net/jdsjlzx/article/details/51497237
onNextメソッドに異常が発生しました
ObserverのonNextメソッドが呼び出された後、そのonErrorメソッドも呼び出されました・・・私の最初の反応はRxJavaのBug?...
もちろん違います
 @Override
    public void onNext(T args) {
        try {
            if (!done) {
                actual.onNext(args);
            }
        } catch (Throwable e) {
            // we handle here instead of another method so we don't add stacks to the frame
            // which can prevent it from being able to handle StackOverflow
            Exceptions.throwIfFatal(e);
            // handle errors if the onNext implementation fails, not just if the Observable fails
            onError(e);
        }
    }

//handle errors if the onNext implementation fails,not just if the Observable fails onNextで私たちの関数に異常が発生した場合、onErrorが呼び出されます
@Pathと@Query
@GET("{username}") Call<User> getUser(@Path("username") String username);
@POST("users") Call<List<User>> getUsersBySort(@Query("sort") String sort);

コードを比較すると違いがわかります.