واجهت مشروع مع مشكلة غير مرئية حتى الآن. اضطررت إلى تدخين الوثائق وفي هذه المقالة سأخبرك بكيفية استخدام RxJava و Retrofit 2 - يمكنك حل مشكلة إنشاء عميل Odata لتطبيق Android.شكرا جزيلا جيك وارتون لخلق هذه الأدوات المريحة.مرحبا بكم في عالم السحر
لدينا تطبيق ، وفقًا لبروتوكول Odata ، يجب أن يستخرج البيانات من الخادم ، ويعرضها في قوائم يجب تحميلها أثناء التمرير ، وإرسال البيانات التي أنشأها المستخدم إلى الخادم. مهمة تافهة ، لكنها لم تكن هنا ، ما يعمل بدون مشكلة في Java - لا يريد العمل مع android أيضًا.والمكتبات والوثائق على Odata فقط من Apache - Olingo و Microsoft في C #.في هذه المقالة لن أفكر في بروتوكول Odata ، لدى Microsoft وثائق جيدة للغاية وسأترك الروابط في نهاية المقالة.فيما يلي تعريف موجز باستخدام Wiki Open_Data_Protocolبروتوكول البيانات المفتوحة (OData)Open Data Protocol (OData) — - . , HTTP-, XML JSON.
4.0, OData — , OASIS.
وهنا يبدأ الجزء الأكثر إثارة للاهتمام ، Odata هو نوع من SQL في واجهة برمجة تطبيقات REST ، وهذا ما هو عليه للبيانات التي يتم إنشاؤها ديناميكيًا.ولكن لدينا لغة مكتوبة بقوة وبدون معرفة النموذج - تعمل معالجة البيانات وتخزينها على إنشاء مهمة صعبة إلى حد ما.الحل الذي لا يمكن أن يكون قياسيًا وموصوفًا بشكل متكرر على الشبكة.سأقول أكثر من ذلك ، باستثناء هذه الروابط للوثائق على الشبكة - كل شيء سيئ في الموضوع.لنقم بالسحر الآن:قم بإنشاء خدمة للعمل مع الشبكة.سنستخدم Retrofit 2 ومنتجات Square ذات الصلة.أضف تبعيات إلى ملف build.gradle
implementation 'com.squareup.retrofit2:retrofit:2.7.1'
implementation 'com.squareup.retrofit2:converter-gson:2.7.1'
implementation 'com.squareup.okhttp3:logging-interceptor:4.3.1'
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.7.1'
implementation 'com.squareup.okhttp3:okhttp:4.3.1'
listing 1 كل هذه التبعيات هي أقوى مكتبة شبكة في Java. لا أرى فائدة منوصف كيفية العمل مع Retrofit 2 ، هنا دليل جيد: نحن نستخدم Retrofit 2 في تطبيق Android .إنشاء فئة 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 إنشاء API:public interface ApiService {
@GET("odata/product")
Observable<List<ProductsDto>> getProducts();
}
listing 3 وننشئ نوعًا من وحدة التحكم لسحب الطلبات: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 لذلك ، يتم تخزين نموذج بيانات Poduct على الخادم ، الذي يحتوي على بعض المعلمات والسمات. يتم نقل جميع البيانات بتنسيق JSON وللعمل نحتاج إلى فصل POJO.أوصي في HttpLoggingInterceptor لتكوين مستوى تفاصيل الاعتراض - Level.BODY.نقدم طلبًا مدرجًا بالقائمة رقم 4 لزيادة بنية البيانات إلى أقصى حد وستكون الإجابة تقريبًا بهذا التنسيق:
{
"@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"
}
]
}
قائمة 5وبالفعل على أساس هذه البيانات من الممكن تشكيل طلب لمزيد من التلاعب بالبيانات.أي أن هذا كائن كامل مع نوع من السلوك والسمات ، من أجل الحصول على هذه المعلومات عند إنشاء طلب ، من الضروري إضافة الشروط التي على أساسها سوف نتلقى مصدر البيانات الخاص بنا دون اختراع دراجة جديدة وبدون ثبات العكازات عليها.ذروة وجرو فرحة الصك راحة
والآن هو لحظة حقيقية ، قوة وقوة وبساطة مكتبة التحديثية 2 . يمكنك الآن الحصول على خصائص باستخدام وثيقة خدمة Odata :
@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);
قائمة 6هنا مكتبة سيلوشكا البطولية التحديثية 2 . يأخذ Dynamic Url كل هذه الكتلة من المعلمات التي يمكنك اللعب بها في الكود طالما كان لديك ما يكفي من الخيال.سيبدو شيئا من هذا القبيل: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) {
mProductsDto.addAll(countersDtos);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
}
listing 7 ملخص
لقد كانت تجربة مفيدة ، والتي سارعت إلى مشاركتها ، في الوقت المناسب ستزيل هذه المقالة بالفعل مجموعة من المشاكل والأسئلة.في المقالة ، لم أخوض في التفاصيل غير الضرورية حول التحديث التحديثي 2 و OData ، وأشرت إلى الروابط إلى الوثائق إذا كانت هناك حاجة إلى التعمق أكثر.لا يمكنني تقديم النسخة الكاملة من الشفرة ، التي أعتذر عنها ، المنتج تجاري.وكما هو متوقع ، الروابط:← وثائق Microsoft: بروتوكول البيانات المفتوح← الوثائق مكتبة OData 4.0 Java← إنشاء تطبيقات إنترنت تعمل بكامل طاقتها باستخدام بروتوكول البيانات المفتوح