通常情況下我們在與服務器進行通信的時候,不一定就不會出錯,有時會出現其他的錯誤,這個時候我們只要和服務器約定好各種異常,在返回結果處進行判斷,到底是執行錯誤,還是返回正常數據。具體的思路大致就是這樣。這里我們定義exceptionhandle,這里我參考網上的東西,然后稍微做了一些改動。
exceptionhandle
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
public class exceptionhandle { private static final int unauthorized = 401 ; private static final int forbidden = 403 ; private static final int not_found = 404 ; private static final int request_timeout = 408 ; private static final int internal_server_error = 500 ; private static final int bad_gateway = 502 ; private static final int service_unavailable = 503 ; private static final int gateway_timeout = 504 ; public static responseexception handleexception(throwable e){ //轉換成responseexception,根據狀態碼判定錯誤信息 responseexception ex; if (e instanceof httpexception){ httpexception httpexception=(httpexception)e; /** * 傳入狀態碼,根據狀態碼判定錯誤信息 */ ex= new responseexception(e,error.http_error); switch (httpexception.code()){ case unauthorized: ex.message= "未驗證" ; break ; case forbidden: ex.message= "服務禁止訪問" ; break ; case not_found: ex.message= "服務不存在" ; break ; case request_timeout: ex.message= "請求超時" ; break ; case gateway_timeout: ex.message= "網關超時" ; break ; case internal_server_error: ex.message= "服務器內部錯誤" ; break ; case bad_gateway: break ; case service_unavailable: break ; default : ex.message = "網絡錯誤" ; break ; } return ex; } else if (e instanceof jsonparseexception || e instanceof jsonexception || e instanceof parseexception){ ex= new responseexception(e,error.parse_error); ex.message= "解析錯誤" ; return ex; } else if (e instanceof connectexception){ ex= new responseexception(e,error.netword_error); ex.message= "連接失敗" ; return ex; } else if (e instanceof javax.net.ssl.sslhandshakeexception){ ex= new responseexception(e,error.ssl_error); ex.message= "證書驗證失敗" ; return ex; } else { ex= new responseexception(e,error.unknown); ex.message= "未知錯誤" ; return ex; } } /** * 約定異常 */ public static class error{ /** * 自定義異常 */ private static final int unauthorized = 401 ; //請求用戶進行身份驗證 private static final int unrequest= 403 ; //服務器理解請求客戶端的請求,但是拒絕執行此請求 private static final int unfindsource= 404 ; //服務器無法根據客戶端的請求找到資源 private static final int severerror= 500 ; //服務器內部錯誤,無法完成請求。 /** * 協議出錯 */ public static final int http_error = 1003 ; /** * 未知錯誤 */ public static final int unknown = 1000 ; /** * 解析錯誤 */ public static final int parse_error = 1001 ; /** * 網絡錯誤 */ public static final int netword_error = 1002 ; /** * 證書出錯 */ public static final int ssl_error = 1005 ; } /** * 自定義throwable */ public static class responsethrowable extends exception{ public int code; public string message; public responsethrowable(throwable throwable, int code){ super (throwable); this .code=code; } } /** * 服務器異常 */ public class serverexception extends runtimeexception{ public int code; public string message; } /** * 統一異常類,便于處理 */ public static class responseexception extends exception{ public int code; public string message; public responseexception (throwable throwable, int code){ super (throwable); this .code=code; } } } |
然后自己定義了一個observer
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
public abstract class baseobserver<t> implements observer<t> { private context context; public baseobserver(context context){ this .context=context; } @override public void onsubscribe(disposable d) { } @override public void onnext(t t) { } @override public void onerror(throwable e) { if (e instanceof exceptionhandle.responseexception){ onerror((exceptionhandle.responseexception)e); } else { onerror( new exceptionhandle.responseexception(e,exceptionhandle.error.unknown)); } } @override public void oncomplete() { } public abstract void onerror(exceptionhandle.responseexception exception); } |
這里發生錯誤時,observerble會先調用onerror(throwable e),按照我的寫法呢,會繼續調用自定義onerror。
那么什么時候我們對服務器的返回結果進行判斷,什么時候該發出異常了,請繼續往下看:
這里我們打算用到observabletransformer,transformer其實就是就是對observable進行一定的變換。
先看代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
public static class handlefuc<t> implements function<userguidesoftconfigrform<userguidesoftconfigpageinfo<list<userguidesoftconfig>>>, t> { @override public t apply(userguidesoftconfigrform<userguidesoftconfigpageinfo<list<userguidesoftconfig>>> response) { if (!response.getcode().equals( "200" )){ throwable e= new throwable( "約定錯誤" ); /** * 可以根據不同的狀態嘛返回不同的提示信息 * 與服務器約定返回異常信息 */ exceptionhandle.responseexception responseexception = new exceptionhandle.responseexception(e, exceptionhandle.error.http_error); return (t) observable.error(responseexception); //發出錯誤異常 } return (t) observable.just(response); //發出服務器數據,返回observable<response> } } //處理錯誤的變換 public static class errortransformer<t> implements observabletransformer { @override public observable<t> apply(observable upstream) { return (observable<t>) upstream.flatmap( new handlefuc<t>()); //flatmap會重新創建一個observable,當它處理完事件后會匯入原先的observable對象。 } } |
說明:我們的handlefuc其實就是對服務器返回來的結果進行判斷,邏輯很簡單了,錯誤就拋出異常直接執行error方法。如果沒有錯誤,就發送正常數據。這里值的說明一點的是,flatmap會重新創建一個observable,當它處理完事件后會重新匯入初始的observerble并開始發送事件。
使用起來其實就很簡單了:
1
2
3
4
5
6
7
8
9
10
11
12
|
@provides errortransformer provideerrortransformer(){ return new errortransformer(); } public observable<userguidesoftconfigrform<userguidesoftconfigpageinfo<list<userguidesoftconfig>>>> getapplication(pageparmform pageparmform){ return retrofit.create(service. class ) .getapplicationlist(pageparmform) .compose(errortransformer) .subscribeon(schedulers.io()) .observeon(androidschedulers.mainthread()); } |
直接用compose方法包裹起來即可。
最后看看activity:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
new netrepository().getapplication( new pageparmform(constant.orderstr,constant.pagenum,constant.pagesize)) .subscribe( new baseobserver<userguidesoftconfigrform<userguidesoftconfigpageinfo<list<userguidesoftconfig>>>>(networkactivity. this ) { @override public void onerror(exceptionhandle.responseexception exception) { mytoast.showtoast(networkactivity. this ,exception.getmessage()); log.d( "carhandbook" ,exception.getmessage()); } @override public void onnext(userguidesoftconfigrform<userguidesoftconfigpageinfo<list<userguidesoftconfig>>> response) { data=response.getdata().getlist(); code=response.getcode(); mytoast.showtoast(networkactivity. this ,code); generateadapter.setdata(data); generateadapter.notifydatasetchanged(); } }); |
好了對網絡請求的異常處理整個思路大致就是這樣了。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:https://www.jianshu.com/p/860945e0de5b