Retrofit+Rxjava هو بالفعل إطار الشبكة الأكثر سائدة في السوق. من السهل للغاية استخدامه لطلب طلبات الشبكة العادية. لقد استخدمت Retrofit لتحميل الملفات وتنزيل الملفات من قبل ، لكنني وجدت أن استخدام Retrofit to Download لا يدعم عمليات استدعاء التقدم بشكل افتراضي ، لكن المنتج يتطلب عرض تقدم التنزيل عند تنزيل الملفات ، لذلك يجب أن أذهب إليه.
بعد ذلك ، دعنا نغلفها معًا ونستخدم Retrofit+Rxjava لتنزيل الملفات مع التقدم.
Github: JsDownload
دعنا نلقي نظرة على مخطط UML أولاً:
قد لا تكون متأكدًا من كيفية التعامل معها. لا تقلق ، لنأخذ الأمر خطوة بخطوة:
1. من الضروري إضافة الاعتماد
compile 'io.reactivex: rxjava: 1.1.0'Compile' io.Reactivex: rxandroid: 1.1.0'Compile 'com.squareup.retrofit2: retrofit: 2.0.0-beta4'compile' com.squareup.retrofit2: "com.squareup.retrofit2: Converter-Gson: 2.0.0-beta4'Compile 'com.squareup.retrofit2: Adapter-Rxjava: 2.0.0-beta4' '
انتبه إلى رقم الإصدار عند استخدامه
2. اكتب رد الاتصال
/*** الوصف: تنزيل Progress Callback* تم إنشاؤه بواسطة JIA في 2017/11/30. * السبب في أن الناس يمكنهم القيام بذلك هو أنهم يعتقدون أنهم يمكنهم*/واجهة عامة JSDownloadListener {void onStartDownload () ؛ void onprogress (int progress) ؛ void onfinishDownload () ؛ void onFail (سلسلة errorInfo) ؛}وغني عن القول ، يجب أن يكون رد الاتصال الذي تم تنزيله على الأقل أربع طرق رد اتصال: ابدأ في تنزيل ، تنزيل التقدم ، تنزيل الانتهاء ، وفشل التنزيل.
لاحظ أن نسبة التقدم يتم إرجاعها في طريقة OnProgress ويتم إرجاع سبب الفشل في OnFail.
3. أعد كتابة الاستجابة وحساب نسبة التنزيل
/*** الوصف: تنزيل جسم طلب مع تقدم* تم إنشاؤه بواسطة JIA في 2017/11/30. * السبب في أن الناس يمكنهم القيام بذلك هو أنهم يعتقدون أنهم يمكنهم*/الطبقة العامة jsresponseBody يمتد ResponseBody {private receptionbody ؛ Private JSDownloadListener DownloadListener ؛ // BufferedSource هو دفق الإدخال في مكتبة Okio ، والذي يتم استخدامه هنا كإدخال. خاص BufferedSource BufferedSource ؛ public jsresponseBody (استجابة ResponseBody ، jsDownloadListener تنزيل) {this.responseBody = reponseBody ؛ this.downloadListener = downloadListener ؛ } Override Public MediaType contentType () {return responseBody.contentType () ؛ } Override Public ContentLength () {return responsebody.contentLength () ؛ } Override Public BufferedSource Source () {if (BufferedSource == null) {bufferedSource = Okio.buffer (source (responsebody.source ())) ؛ } إرجاع BufferedSource ؛ } مصدر خاص (مصدر المصدر) {return New TalleringingSource (Source) {Long TotalByTesRead = 0L ؛ Override Public Read Long (Sink Buffer ، Long Bytecount) يلقي ioException {long bytesread = super.read (sint ، bytecount) ؛ // read () إرجاع عدد البايتات القراءة ، أو -1 إذا تم استنفاد هذا المصدر. TotalBytesRead += bytesread! = -1؟ bytesread: 0 ؛ log.e ("download" ، "read:"+ (int) (TotalByTesRead * 100 / responseBody.ContentLength ())) ؛ if (null! = downloadListener) {if (bytesRead! = -1) {downloadListener.onprogress ((int) (TotalByTesRead * 100 / responseBody.ContentLength ())) ؛ }} إرجاع bytesread ؛ }}} ؛ }}تمرير ResponseBody و JSDownloadListener لطلب الشبكة في البناء.
الأساسية هنا هي طريقة المصدر ، التي تُرجع كائن TollingingSource ، حيث نقوم بتجاوز طريقة القراءة الخاصة به ، وحساب النسبة المئوية في طريقة القراءة ، ونقلها إلى قائمة تنزيل رد الاتصال.
4. اعتراض
لا يكفي لتغليف ResponseBody فقط. المفتاح هو أننا نحتاج إلى الحصول على استجابة مطلوبة ، هنا نستخدم التقاطع.
/*** الوصف: تنزيل Interceptor مع تقدم* تم إنشاؤه بواسطة JIA في 2017/11/30. * السبب في أن الناس يمكنهم القيام بذلك هو أنهم يعتقدون أنهم يمكنهم*/فئة عامة JSDownloadInterceptor يمنع Interceptor {private jsDownloadListener DownloadListener ؛ public jsDownloadInterceptor (jsDownloadListener downloadListener) {this.downloadListener = downloadListener ؛ } Override Public Response Intercept (سلسلة سلسلة) يلقي ioException {استجابة الاستجابة = chain.proceed (chain.request ()) ؛ Return Response.NewBuilder (). Body (New JSresponseBody (Response.body () ، downloadListener)). Build () ؛ }}عادةً ، يتم استخدام المعترضات لإضافة معلومات الطلب أو تحويلها أو تحويلها.
إرجاع ResponseBody الذي تم تغليفه للتو في اعتراض طريقة التقاطع.
5. خدمة طلب الشبكة
/** * الوصف: * تم إنشاؤه بواسطة JIA في 2017/11/30. * السبب في أن الناس يمكنهم القيام بذلك هو أنهم يعتقدون أنهم يمكنهم*//الواجهة العامة تنزيلات {streamingget يمكن ملاحظته <reponseBody> تنزيل (url url url) ؛}يلاحظ:
هنا url هو تمرير عنوان URL التنزيل الكامل ؛ لا تحتاج إلى اعتراض طريقة التعليق التوضيحي @
6. يبدأ الطلب النهائي
/** 1. الوصف: تنزيل أداة الفئة 2. تم إنشاؤه بواسطة JIA في 2017/11/30. 3. السبب وراء قدرة الناس على القيام بذلك هو أنهم يعتقدون أنهم يمكنهم*/فئة عامة تنزيل {private static final string tag = "downloadUtils" ؛ خاص ثابت نهائي int default_timeout = 15 ؛ التحديثية الخاصة التحديثية ؛ مستمع JSDownloadListener الخاص ؛ سلسلة خاصة baseurl ؛ سلسلة خاصة تنزيل ؛ Public DownloadUtils (String Baseurl ، JSDownloadListener Bearner) {this.baseurl = baseurl ؛ this.listener = المستمع ؛ jsDownLoftroceptor minterceptor = new jsDownloadInterceptor (المستمع) ؛ OKHTTPCLIENT httpclient = new OKHTTPCLIENT.BUILDER () .AddInterceptor (minterceptor) .retryonConnectionFailure (true) .ConnectTimeout (default_timeout ، timeUnit.seconds) .build () ؛ retrofit = جديد retrofit.builder () .baseurl (baseurl) .client (httpclient) .addcalladapterfactory (rxjavacalladapterfactory.create ()) .build () ؛ } / ** * ابدأ التنزيل * * param url * param filepath * param المشترك * / تنزيل void العام (url url url string ، السلسلة النهائية ، المشترك المشترك) // cumpcribon () يغير مؤشر ترابط الكود قبل أن يسمى // observeon () يغير مؤشر ترابط الكود بعد أن يسمى retrofit.create (downloadService.class) .Download (url) .Subscribeon call (responsebodybody) {return responsebody.bytestream () ؛ .Observeon (AndroidsChedulers.MainThread ()) .Subscribe (مشترك) ؛ } / ** * اكتب دفق الإدخال إلى الملف * * param inputString * param filepath * / private void writefile (inputStream inputString ، string filepath) {file file = file new (filepath) ؛ if (file.exists ()) {file.delete () ؛ } fileOutputStream fos = null ؛ حاول {fos = fileOutputStream (ملف جديد) ؛ بايت [] ب = بايت جديد [1024] ؛ int len ؛ بينما ((len = inpectString.Read (b))! = -1) {fos.write (b ، 0 ، len) ؛ } inputString.Close () ؛ fos.close () ؛ } catch (fileNotfoundException e) {leader.onfail ("fileNotfoundException") ؛ } catch (ioException e) {leader.onfail ("ioException") ؛ }}}بالطبع ، تحتاج أيضًا إلى الانتباه إلى كل موقع رد الاتصال.
ما سبق هو كل محتوى هذه المقالة. آمل أن يكون ذلك مفيدًا لتعلم الجميع وآمل أن يدعم الجميع wulin.com أكثر.