OData + RxJava + Retrofit 2 untuk aplikasi android

Menghadapi proyek dengan masalah yang sampai sekarang tidak terlihat. Saya harus merokok dokumentasi dan dalam artikel ini saya akan memberi tahu Anda bagaimana menggunakan RxJava dan Retrofit 2 - Anda dapat memecahkan masalah membuat klien Odata untuk aplikasi android.

Terima kasih banyak Jake Wharton karena menciptakan alat yang nyaman.

Selamat datang di dunia sihir


Kami memiliki aplikasi yang, sesuai dengan protokol Odata, harus mengekstrak data dari server, menampilkannya dalam daftar yang harus dimuat saat menggulir, dan mengirim data yang dibuat oleh pengguna ke server. Tugas sepele, tetapi tidak ada di sini, yang berfungsi tanpa masalah di Jawa - tidak ingin bekerja dengan android juga.

Dan perpustakaan dan dokumentasi di Odata hanya dari Apache - Olingo dan Microsoft di C #.

Pada artikel ini saya tidak akan mempertimbangkan protokol Odata , Microsoft memiliki dokumentasi yang sangat bagus dan saya akan meninggalkan tautan di akhir artikel.

Berikut adalah definisi singkat dengan Wiki Open_Data_Protocol

Open Data Protocol (OData)
Open Data Protocol (OData) โ€” - . , HTTP-, XML JSON.

4.0, OData โ€” , OASIS.

Dan di sini bagian yang paling menarik dimulai, Odata adalah sejenis SQL di REST API, dan itulah yang digunakan untuk data yang dihasilkan secara dinamis.

Tapi kami memiliki bahasa yang sangat diketik dan tanpa pengetahuan tentang model - pemrosesan dan penyimpanan data membuat tugas yang agak sulit.

Solusi yang tidak dapat standar dan berulang kali dijelaskan di jaringan.

Saya akan mengatakan lebih banyak lagi, kecuali tautan ini ke dokumentasi di jaringan - semuanya buruk pada topik.

Sekarang mari kita lakukan keajaiban:

Buat layanan untuk bekerja dengan jaringan.

Kami akan menggunakan Retrofit 2 dan produk Square terkait.

tambahkan dependensi ke file build.gradle
// Network
    implementation 'com.squareup.retrofit2:retrofit:2.7.1' //   Retrofit 2
    implementation 'com.squareup.retrofit2:converter-gson:2.7.1' //     JSON 
    implementation 'com.squareup.okhttp3:logging-interceptor:4.3.1' //  
    implementation 'com.squareup.retrofit2:adapter-rxjava2:2.7.1' //     RxJava
    implementation 'com.squareup.okhttp3:okhttp:4.3.1' // OkHttp -  HTTP-
listing 1

Semua dependensi ini adalah pustaka jaringan yang paling kuat di Jawa. Saya tidak mengerti maksud

menggambarkan cara bekerja dengan Retrofit 2 , ada manual yang bagus: Kami menggunakan Retrofit 2 dalam aplikasi Android .

Buat kelas NetworkService:
public class NetworkService {

    private static final String TAG = "NetworkService";

    private static final NetworkService
            mInstance = new NetworkService();

    private String mToken;
    private Retrofit mRetrofit;

    public static NetworkService getInstance() {
        return mInstance;
    }

    private NetworkService() {

        RxJava2CallAdapterFactory rxAdapter =
                RxJava2CallAdapterFactory
                        .createWithScheduler(Schedulers.io());

        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); 

        OkHttpClient.Builder okHttpClient =
                new OkHttpClient.Builder()
                        .addInterceptor(interceptor)
                        .addInterceptor(chain -> {
                            Request newRequest =
                                    chain.request().newBuilder()
                                           .addHeader("Accept",
                                                     "application/json,text/plain,*/*")
                                           .addHeader("Content-Type",
                                                    "application/json;odata.metadata=minimal")
                                           .addHeader("Authorization", mToken)
                                    .build();

                            return chain.proceed(newRequest);
                        });

        Gson gson = new GsonBuilder()
                .setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")
                .create();

        mRetrofit = new Retrofit.Builder()
                .baseUrl(Const.BASE_URL)
                .addConverterFactory(GsonConverterFactory.create(gson))
                .addCallAdapterFactory(rxAdapter)
                .client(okHttpClient.build())
                .build();
    }
    public ApiService getNetworkClient(){
        return mRetrofit.create(ApiService.class);
    }
}

listing 2

Buat API:
public interface ApiService {
//    
@GET("odata/product")
Observable<List<ProductsDto>> getProducts();
}
listing 3

Dan kami membuat beberapa jenis pengontrol untuk menarik permintaan:
public class ProductsController {

    private ApiService mApiService;

    private List<ProductsDto> listProducts;
    private Gson gson;

    public ProductsController() {

        mApiService = App.getNetworkService().getNetworkClient();

        listProducts = new ArrayList<>();

        gson = new Gson();
    }

    public void productsBtnClick() {

        mApiService.getProducts()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new DisposableObserver<List<ProductsDto>>() {
                    @Override
                    public void onNext(List<ProductsDto> products) {

                        listProducts.addAll(listProducts);
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {
                    }
                });
    }
listing 4

Jadi, model data Poduct disimpan di server, yang memiliki beberapa parameter dan atribut. Semua data masuk dalam format JSON dan untuk pekerjaan kita membutuhkan kelas POJO.

Saya sarankan di HttpLoggingInterceptor untuk mengkonfigurasi level detail intersepsi - Level.BODY.

Kami membuat permintaan cantuman 4 untuk memaksimalkan struktur data dan jawabannya kira-kira dalam format ini:

//         
//   JSON
{
  "@odata.context":"https://example.xxx/api/odata/$metadata","value":[
    {
      "name":"product","kind":"EntitySet","url":"product" //  
    },{
      "name":"blogs","kind":"EntitySet","url":"blogs"  // 
    },{
      "name":"posts","kind":"EntitySet","url":"posts"  // 
    },{
      "name":"comments","kind":"EntitySet","url":"comments" // 
    },{
      "name":"rates","kind":"EntitySet","url":"rates" // 
    }
  ]
}

listing 5

Dan sudah berdasarkan data ini adalah mungkin untuk membentuk permintaan untuk manipulasi data lebih lanjut.

Artinya, ini adalah objek yang lengkap dengan beberapa jenis perilaku dan atribut, untuk mendapatkan informasi ini saat membuat permintaan, perlu menambahkan kondisi berdasarkan mana kami akan menerima DataSource kami tanpa menciptakan sepeda baru dan tanpa mengacaukan kruk.

Puncaknya dan kesenangan anak anjing dari kenyamanan instrumen


Dan di sini momennya benar, kekuatan, kekuatan, dan kesederhanaan perpustakaan Retrofit 2 . Sekarang Anda bisa mendapatkan properti menggunakan dokumen layanan Odata :

//   properties  product
@GET("odata/product?$filter=Id eq 111&$expand=dateReading($orderby=Date desc")
Observable<List<ProductsDto>> getProducts();

//  properties  blogs
@GET("odata/blogs?$orderby=Date desc")
Observable<List<BlogsDto>> getBlogs();

//        
@GET("odata/product?$filter=((Id eq 19) and (Name eq 'Available')) and ((Status eq 'OPEN') or ((Status eq 'CLOSED') and (Date ge 2020-02-13T06:39:48Z)))&$orderby=Status asc,Date desc&$top=10&$expand=AuthorId,CategoryId($expand=weight)&$count=true")
Observable<List<ProductsDto>> getProducts();
//        ,
//       . 

// :
@GET
Observable<List<ProductsDto>> getProducts(@Url String url);

listing 6

Ini dia perpustakaan heroik Silushka Retrofit 2 . Url dinamis mengambil semua parameter yang dapat Anda mainkan dalam kode selama Anda memiliki cukup imajinasi.

Akan terlihat seperti ini:
private void buttonGetProduct() {
//     
        String one = "odata/product?$filter=Id eq ";
        String id = "777";
        String tree = "&$expand=dateReading($orderby=Date desc)";
        String url = one + id + tree;

        mApiService.getProduct(url)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new DisposableObserver<List<ProductDto>>() {
                    @Override
                    public void onNext(List<ProductDto> products) {

//       ,     JSON,
//         
                        mProductsDto.addAll(countersDtos);
                    }

                    @Override
                    public void onError(Throwable e) {
                    }

                    @Override
                    public void onComplete() {
                    }
                });
    }
listing 7

Ringkasan


Itu adalah pengalaman yang berguna, yang dengan cepat saya bagikan, pada waktunya artikel ini akan benar-benar menghilangkan banyak masalah dan pertanyaan.

Dalam artikel itu, saya tidak masuk ke rincian yang tidak perlu tentang Retrofit 2 dan OData dan menunjukkan tautan ke dokumentasi jika ada kebutuhan untuk menggali lebih dalam.

Saya tidak dapat memberikan versi lengkap kode, yang untuknya saya minta maaf, produk ini komersial.

Dan, seperti yang dijanjikan, tautan:

โ†’  Dokumentasi Microsoft: Protokol Data Terbuka
โ†’  Dokumentasi OData 4.0 Java Library
โ†’  Buat aplikasi Internet yang berfungsi penuh menggunakan Protokol Data Terbuka

All Articles