在實習期間因爲要求使用volley,因此第一次開始接觸volley,從一開始的迷茫陌生,到瘋狂的查找各類資料,經過在項目中用到的實際問題,我想作一些總結,因此寫了這篇文章。下面我將介紹我理解的用戶登陸的一套詳細流程,涉及到volley請求以及json數據的解析。android
登陸流程的總結:首先經過EditText獲取到用戶名和密碼,而後再執行登陸請求 LoginToServer()裏面發送用戶名和密碼,服務器返回給我json數據(若是用到Oauth 認證這裏返回的json數據就應該是Token的一套東西,若是隻是簡單的登陸,能夠和服務器約定返回的內容,提取出對應的內容,包裝起來作判斷反饋給用戶登陸是否成功),我須要把這些json數據解析出來,而後再反饋給用戶「登陸成功」或者「登陸失敗」。web
LoginActivity.class這裏是在登陸界面調用到 LoginToServer()這個方法,這裏我把 User_Local.class 裏面寫了基本的set,get方法,而後是裏面是全局(public static)的方法。數據庫
1 public void onClick(View v) { 2 switch (v.getId()) { 3 case R.id.login_button: 4 if (checkEdit()) { 5 //這裏記得必定要先get得到數據 6 User_Local.setUsername(username.getText().toString()); 7 User_Local.setPassword(password.getText().toString()); 8 // LoginToServer(); 9 new LoginSupport(LoginActivity.this).LoginToServer(); 10 } 11 break;
這裏是User_Local.class ,首先這裏爲何要寫成public static,寫成這種是說這是全局變量。全局的引用方法就是類名直接引用,不用再new 一個對象。好比這裏就是引用直接就是上述的 User_Local.setUsername(username.getText().toString());。何時用全局的,何時不用,這個你們能夠百度一下。好比在接受服務器傳過來的json數據我要再建一套類去匹配解析,這個時候就不要用全局的。json
1 public class User_Local { 2 3 public static String username = " " ;//用戶名 4 public static String password =" ";//密碼 5 6 public static String getUsername() { 7 return username; 8 } 9 10 public static void setUsername(String username) { 11 User_Local.username = username; 12 } 13 14 public static String getPassword() { 15 return password; 16 } 17 18 public static void setPassword(String password) { 19 User_Local.password = password; 20 } 21 LoginSupport.class 這個類裏面我寫了volley的登陸請求,還有服務器返回的json數據解析(這裏使用的是Gson來解析json數據),還有反饋給用戶登陸成功失敗與否 22 23 volley請求簡單說就三步:1.添加url地址。2.new 一個請求(請求裏面有成功和失敗的接口)3.添加請求到請求隊列裏面去 24 25 這裏我只用了volley 裏面的StringRequest這個請求,這個請求向服務器發送的應該是字符串吧,我理解的是這樣的。而後至於volley的其餘請求你們能夠參考其餘的博客和專業資料。 26 27 public void LoginToServer( ) { 28 String url = "http://XXXXX";//1.這裏就是你要向服務器發送請求的地址 29 StringRequest loginRequest = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {//2.new 一個請求 30 @Override 31 public void onResponse(String s) {//這裏是返回正確反饋的接口(只要請求成功反饋的數據都這這裏) 32 //數據處理反饋(能夠這這裏處理服務器返回的數據) 33 DealResponseFromServer(s);//json數據的解析和用戶反饋 34 Log.i("TAG",s); 35 } 36 }, new Response.ErrorListener() { 37 @Override 38 public void onErrorResponse(VolleyError volleyError) { 39 //volley 有專門處理error的庫,下面就是調用了其中的一些,能夠方便調試的時候查找到錯誤 40 Log.d(TAG, "Volley returned error________________:" + volleyError); 41 Class klass = volleyError.getClass(); 42 if(klass == com.android.volley.AuthFailureError.class) { 43 Log.d(TAG,"AuthFailureError"); 44 Toast.makeText(context,"未受權,請從新登陸",Toast.LENGTH_LONG).show(); 45 } else if(klass == com.android.volley.NetworkError.class) { 46 Log.d(TAG,"NetworkError"); 47 Toast.makeText(context,"網絡鏈接錯誤,請從新登陸",Toast.LENGTH_LONG).show(); 48 } else if(klass == com.android.volley.NoConnectionError.class) { 49 Log.d(TAG,"NoConnectionError"); 50 } else if(klass == com.android.volley.ServerError.class) { 51 Log.d(TAG,"ServerError"); 52 Toast.makeText(context,"服務器未知錯誤,請從新登陸",Toast.LENGTH_LONG).show(); 53 } else if(klass == com.android.volley.TimeoutError.class) { 54 Log.d(TAG,"TimeoutError"); 55 Toast.makeText(context,"鏈接超時,請從新登陸",Toast.LENGTH_LONG).show(); 56 } else if(klass == com.android.volley.ParseError.class) { 57 Log.d(TAG,"ParseError"); 58 } else if(klass == com.android.volley.VolleyError.class) { 59 Log.d(TAG,"General error"); 60 } 61 Toast.makeText(context,"登陸失敗",Toast.LENGTH_LONG).show(); 62 } 63 }) 64 { 65 //這裏是添加請求頭的地方重寫了getHeaders() 方法(發送設麼請求頭要根據本身實際開發須要設定) 66 @Override 67 public Map<String, String> getHeaders() { 68 HashMap<String, String> header = new HashMap<String, String>(); 69 header.put("Accept","application/json"); 70 header.put("Content-Type","application/x-www-form-urlencoded"); 71 return header; 72 } 73 74 //這裏是發送參數的地方,重寫了 getParams() 方法(傳什麼參數給服務器也是實際你本身修改) 75 @Override 76 protected Map<String, String> getParams() { 77 HashMap<String, String> map = new HashMap<String, String>(); 78 79 //若是出現空指針異常或者是登陸失敗,先檢查這裏有木有傳進來你要發送的用戶名和密碼。 80 //因此在執行get數據方法以前必定要先存數據(set方法) 81 map.put("username", User_Local.getUsername()); 82 map.put("password", User_Local.getPassword()); 83 return map; 84 } 85 }; 86 //設置超時從新請求 87 loginRequest.setRetryPolicy(new DefaultRetryPolicy(5000, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, 88 DefaultRetryPolicy.DEFAULT_BACKOFF_MULT)); 89 //設置標籤,方便在stop(){}裏面取消對應的volley 請求 90 loginRequest.setTag("POST"); 91 //3.把請求添加到全局請求隊列裏面 92 MyApplication.getHttpQueue().add(loginRequest); 93 }
1 //創建一個全局請求隊列 2 public class MyApplication extends Application { 3 public static RequestQueue requestQueue;// 4 5 @Override 6 public void onCreate() { 7 super.onCreate(); 8 requestQueue = Volley.newRequestQueue(getApplicationContext()); 9 } 10 11 public static RequestQueue getHttpQueue(){ 12 return requestQueue; 13 } 14 }
Gson解析json數據的精華就是:
gson.fromJson(就是把json數據解析成普通數據)和gson.toJson(把普通數據轉化成json類型的數據格式)
要注意的是,這裏解析到服務器的數據必須有一套模型和服務器裏面的各類數據類型匹配,也就是你須要根據傳過來的json數據建一個類來把解析的數據保存起來。服務器
1 //解析服務器返回的json字符串反饋給用戶 2 public void DealResponseFromServer(String s) { 3 Gson gson = new Gson();//第一步,實例化 4 User_Service user_service = gson.fromJson(s, User_Service.class);//第二步,解析數據 5 if (s!=null) {//這裏的s就是上面成功回調接口裏面的參數 6 //這裏我保存了從服務器返回的token的信息,至於token就涉及到oauth2.0的內容了,不懂得能夠百度, 7 //固然這裏能夠保持你須要保存的服務器返回的數據 8 PreferenceUtils.setPrefString(context,User_Service.userKey, "access_token", user_service.getAccess_token());//保存令牌(這裏我用的是本身寫的一套SharedPreferences的工具類來保存token) 9 PreferenceUtils.setPrefString(context,User_Service.userKey, "refresh_token", user_service.getRefresh_token());//保存刷新令牌 10 Toast.makeText(context, "登陸成功", Toast.LENGTH_SHORT).show();//反饋給用戶登陸成功 11 } 12 }
這個就是用於接收服務器返回的json數據類型所創建的類,專門用於解析json數據的。這裏的變量就不用設置成全局的變量。
這裏面的關係我捋一下,1.從服務器解析的json數據保存到本地數據庫裏面2.而後本地須要調用數據的時候,再去數據庫裏面去取。網絡
1 //用於接收解析服務器返回數據所給的數據 2 public class User_Service { 3 public static final String userKey = "user_service";//用於保存服務器端傳回的數據文件 4 private String access_token;//令牌 5 private String refresh_token;//刷新令牌 6 7 public String getAccess_token() { 8 return access_token; 9 } 10 11 public void setAccess_token(String access_token) { 12 this.access_token = access_token; 13 } 14 15 public void setRefresh_token(String refresh_token) { 16 this.refresh_token = refresh_token; 17 } 18 19 public String getRefresh_token() { 20 return refresh_token; 21 }