編輯:關於android開發
Android系統中主要提供了兩種方式來進行HTTP通信,HttpURLConnection和HttpClient,幾乎在任何項目的代碼中我們都能看到這兩個類的身影,使用率非常高。
不過HttpURLConnection和HttpClient的用法還是稍微有些復雜的,如果不進行適當封裝的話,很容易就會寫出不少重復代碼
主要就是進行了以下三步操作:
創建一個RequestQueue對象。創建一個XXXXXRequest對象。將XXXXXXRequest對象添加到RequestQueue裡面。第一步獲取到RequestQuene對象
RequestQueue mQueue = Volley.newRequestQueue(context);
RequestQueue是一個請求隊列對象,它可以緩存所有的HTTP請求,然後按照一定的算法並發地發出這些請求。RequestQueue內部的設計就是非常合適高並發的,因此我們不必為每一次HTTP請求都創建一個RequestQueue對象,這是非常浪費資源的,基本上在每一個需要和網絡交互的Activity中創建一個RequestQueue對象就足夠了。
第二步創建StringRequest對象
第一個參數是url地址,第二個參數是請求成功處理返回來的數據 第三個參數是請求失敗進行的處理
StringRequest stringRequest = new StringRequest("http://www.baidu.com",
new Response.Listener() {
@Override
public void onResponse(String response) {
Log.d("TAG", response);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e("TAG", error.getMessage(), error);
}
});
第三步需要將stringRequest添加到mQuene裡面即可
mQueue.add(stringRequest);
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest("http://m.weather.com.cn/data/101010100.html", null,
new Response.Listener() {
@Override
public void onResponse(JSONObject response) {
Log.d("TAG", response.toString());
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e("TAG", error.getMessage(), error);
}
});
其中response.toString()
就是返回來的數據只需要處理器就行
ImageRequest request = new ImageRequest("http://www.2cto.com/uploadfile/Collfiles/20141103/201411030837265.png", new Response.Listener() {
@Override
public void onResponse(Bitmap bitmap) {
image.setImageBitmap(bitmap);
}
},0,0, ImageView.ScaleType.MATRIX,Bitmap.Config.ARGB_8888,new Response.ErrorListener(){
@Override
public void onErrorResponse(VolleyError volleyError) {
image.setImageResource(R.drawable.ic_empty);
}
});
ImageLoader也可以用於加載網絡上的圖片,並且它的內部也是使用ImageRequest來實現的,不過ImageLoader明顯要比ImageRequest更加高效,因為它不僅可以幫我們對圖片進行緩存,還可以過濾掉重復的鏈接,避免重復發送請求。
由於ImageLoader已經不是繼承自Request的了,所以它的用法也和我們之前學到的內容有所不同
總結起來大致可以分為以下四步:
創建一個RequestQueue對象。創建一個ImageLoader對象。獲取一個ImageListener對象。調用ImageLoader的get()方法加載網絡上的圖片。
ImageLoader imageLoader = new ImageLoader(mQueue, new ImageCache() {
@Override
public void putBitmap(String url, Bitmap bitmap) {
}
@Override
public Bitmap getBitmap(String url) {
return null;
}
});
ImageLoader的構造函數接收兩個參數,第一個參數就是RequestQueue對象,第二個參數是一個ImageCache對象
接下裡創建ImageListen對象
ImageListener listener = ImageLoader.getImageListener(imageView,
R.drawable.default_image, R.drawable.failed_image);
最後,調用ImageLoader的get()方法來加載圖片
imageLoader.get("http://www.2cto.com/uploadfile/2016/0413/20160413101119415.jpeg", listener);
可以控制其大小
imageLoader.get(“http://www.2cto.com/uploadfile/2016/0413/20160413101119415.jpeg“,
listener, 200, 200);
想要寫一個好的ImageCache對象 需要用到Android的LruCache功能了
public class BitmapCache implements ImageCache {
private LruCache mCache;
public BitmapCache() {
int maxSize = 10 * 1024 * 1024;
mCache = new LruCache(maxSize) {
@Override
protected int sizeOf(String key, Bitmap bitmap) {
return bitmap.getRowBytes() * bitmap.getHeight();
}
};
}
@Override
public Bitmap getBitmap(String url) {
return mCache.get(url);
}
@Override
public void putBitmap(String url, Bitmap bitmap) {
mCache.put(url, bitmap);
}
}
這裡我們將緩存圖片的大小設置為10M。接著修改創建ImageLoader實例的代碼,第二個參數傳入BitmapCache的實例,如下所示:
ImageLoader imageLoader = new ImageLoader(mQueue, new BitmapCache());
需要遵循以下五步:
創建一個RequestQueue對象。創建一個ImageLoader對象。在布局文件中添加一個NetworkImageView控件。在代碼中獲取該控件的實例。設置要加載的圖片地址。第一第二步
RequestQueue requestQueue = VolleyUtil.getQueue(getActivity());
ImageLoader loader = new ImageLoader(requestQueue,new LruImageCache());
首先修改布局文件中的代碼,在裡面加入NetworkImageView控件,如下所示:
然後獲取控件
networkImageView = (NetworkImageView) findViewById(R.id.network_image_view);
到了NetworkImageView控件的實例之後,我們可以調用它的setDefaultImageResId()方法、setErrorImageResId()方法和setImageUrl()方法來分別設置加載中顯示的圖片,加載失敗時顯示的圖片,以及目標圖片的URL地址,如下所示:
networkImageView.setDefaultImageResId(R.drawable.default_image);
networkImageView.setErrorImageResId(R.drawable.failed_image);
networkImageView.setImageUrl("http://www.2cto.com/uploadfile/Collfiles/20141103/201411030837265.png",
imageLoader);
NetworkImageView並不需要提供任何設置最大寬高的方法也能夠對加載的圖片進行壓縮。這是由於NetworkImageView是一個控件,在加載圖片的時候它會自動獲取自身的寬高,然後對比網絡圖片的寬度,再決定是否需要對圖片進行壓縮 即可以說有wrap_content
match_content
和 自定義高度寬度
可以說真的無從下手 不如我們先看一下birdersRequest的實現方法
例如StringRequest
public class StringRequest extends Request {
private Listener mListener;
public StringRequest(int method, String url, Listener listener, ErrorListener errorListener) {
super(method, url, errorListener);
this.mListener = listener;
}
public StringRequest(String url, Listener listener, ErrorListener errorListener) {
this(0, url, listener, errorListener);
}
protected void onFinish() {
super.onFinish();
this.mListener = null;
}
protected void deliverResponse(String response) {
if(this.mListener != null) {
this.mListener.onResponse(response);
}
}
protected Response parseNetworkResponse(NetworkResponse response) {
String parsed;
try {
parsed = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
} catch (UnsupportedEncodingException var4) {
parsed = new String(response.data);
}
return Response.success(parsed, HttpHeaderParser.parseCacheHeaders(response));
}
}
首先StringRequest是繼承自Request類的,Request可以指定一個泛型類,這裡指定的當然就是String了,接下來StringRequest中提供了兩個有參的構造函數,參數包括請求類型,請求地址,以及響應回調等,由於我們已經很熟悉StringRequest的用法了,相信這幾個參數的作用都不用再解釋了吧。但需要注意的是,在構造函數中一定要調用super()方法將這幾個參數傳給父類,因為HTTP的請求和響應都是在父類中自動處理的。另外,由於Request類中的deliverResponse()和parseNetworkResponse()是兩個抽象方法,因此StringRequest中需要對這兩個方法進行實現。deliverResponse()方法中的實現很簡單,僅僅是調用了mListener中的onResponse()方法,並將response內容傳入即可,這樣就可以將服務器響應的數據進行回調了。parseNetworkResponse()方法中則應該對服務器響應的數據進行解析,其中數據是以字節的形式存放在NetworkResponse的data變量中的,這裡將數據取出然後組裝成一個String,並傳入Response的success()方法中即可。
public class XmlRequest extends Request {
private final Response.Listener mListener;
public XmlRequest(int method, String url, Response.Listener listener, Response.ErrorListener errorListener) {
super(method, url, errorListener);
mListener = listener;
}
public XmlRequest(String url, Response.Listener listener, Response.ErrorListener errorListener) {
this(Method.GET, url, listener, errorListener);
}
// parseNetworkResponse()方法中則應該對服務器響應的數據進行解析,
// 其中數據是以字節的形式存放在NetworkResponse的data變量中的,
// 這裡將數據取出然後組裝成一個String,並傳入Response的success()方法中即可
@Override
protected Response parseNetworkResponse(NetworkResponse response) {
try {
String xmlString = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
XmlPullParser xmlPullParser = factory.newPullParser();
/**
* Set the input source for parser to the given reader and
* resets the parser. The event type is set to the initial value
* START_DOCUMENT.
* Setting the reader to null will just stop parsing and
* reset parser state,
* allowing the parser to free internal resources
* such as parsing buffers.
*/
// 為了給予閱讀器,設置輸入源給分析器。 和 重新設置 分析器 。事件類型會給一個初始值 START_DOCUMENT 開始文檔
// 設置的閱讀器如果為空會停止分析並且重新設置 分析器的狀態 允許分析器來解析釋放的內部資源 例如解析緩沖區
xmlPullParser.setInput(new StringReader(xmlString));
return Response.success(xmlPullParser, HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (XmlPullParserException e) {
return Response.error(new ParseError(e));
}
}
@Override
protected void deliverResponse(XmlPullParser response) {
mListener.onResponse(response);
}
@Override
public Map getHeaders() throws AuthFailureError {
// self-defined user agent
Map headerMap = new HashMap();
headerMap.put("User-Agent", "android-open-project-analysis/1.0");
return headerMap;
}
}
然後我們就可以像上面的一樣進行xml的請求
// 發起請求
XmlRequest request = new XmlRequest(StringUtil.preUrl(Constants.DEFAULT_XML_REQUEST_URL),
new Response.Listener() {
@Override
public void onResponse(XmlPullParser parser) {
try {
weatherDataList.clear();
int eventType = parser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
switch (eventType) {
case XmlPullParser.START_TAG:
String nodeName = parser.getName();
if ("city".equals(nodeName)) {
Map weatherMap = new HashMap();
weatherMap.put("city", parser.getAttributeValue(2));
weatherMap.put("detail", parser.getAttributeValue(5));
weatherMap.put("temp", parser.getAttributeValue(7)+"℃ 到 "+parser.getAttributeValue(6)+"℃");
weatherMap.put("wind", parser.getAttributeValue(8));
weatherDataList.add(weatherMap);
}
break;
}
eventType = parser.next();
}
adapter.notifyDataSetChanged();
} catch (XmlPullParserException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError arg0) {
ToastUtil.showToast(getActivity(), getResources().getString(R.string.request_fail_text));
}
});
public class GsonRequest extends Request {
private final Response.Listener mlisten;
private Gson gson;
private Class mClass;
public GsonRequest(int method, String url,Class clazz, Response.Listener listener, Response.ErrorListener errorListener) {
super(method, url, errorListener);
mClass = clazz;
gson = new Gson();
mlisten = listener;
}
public GsonRequest(String url, Class clazz,Response.Listener listener, Response.ErrorListener errorListener) {
this(Method.GET, url,clazz,listener, errorListener);
}
@Override
protected Response parseNetworkResponse(NetworkResponse networkResponse) {
try {
String jsonString = new String(networkResponse.data,
HttpHeaderParser.parseCharset(networkResponse.headers));
return Response.success(gson.fromJson(jsonString,mClass),
HttpHeaderParser.parseCacheHeaders(networkResponse));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
}
}
@Override
protected void deliverResponse(T t) {
mlisten.onResponse(t);
}
}
JSON格式數據
{“weatherinfo”:{“city”:”北京”,”cityid”:”101010100”,”temp”:”19”,”WD”:”南風”,”WS”:”2級”,”SD”:”43%”,”WSE”:”2”,”time”:”19:45”,”isRadar”:”1”,”Radar”:”JC_RADAR_AZ9010_JB”}}
需要創建
public class WeatherInfo {
private String city;
private String temp;
private String time;
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getTemp() {
return temp;
}
public void setTemp(String temp) {
this.temp = temp;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
}
另一個類
public class Weather {
private WeatherInfo weatherinfo;
public WeatherInfo getWeatherinfo() {
return weatherinfo;
}
public void setWeatherinfo(WeatherInfo weatherinfo) {
this.weatherinfo = weatherinfo;
}
}
然後像上面一樣進行請求
RequestQueue quene = VolleyUtil.getQueue(this);
GsonRequest gsonRequest = new GsonRequest(
"http://www.weather.com.cn/adat/sk/101010100.html", Weather.class,
new Response.Listener() {
@Override
public void onResponse(Weather weather) {
WeatherInfo WeatherInfo = weather.getWeatherinfo();
Log.d("TAG", "city is " + WeatherInfo.getCity());
Log.d("TAG", "temp is " + WeatherInfo.getTemp());
Log.d("TAG", "time is " + WeatherInfo.getTime());
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e("TAG", error.getMessage(), error);
}
});
quene.add(gsonRequest);
自定義類似於listView中Item背景,listviewitem方法一、 drawable/listitem_bk.xml Xml代碼
android 特殊用戶通知用法匯總--Notification源碼分析 一直用的android手機,用過這麼多的app,平時也會遇到有趣的通知提醒,在這裡先總結
一款面試復習應用源碼,面試復習源碼為了更好地准備面試android開發這一職位,於是就到應用市場查找相關的復習App,結果發現只有寥寥無幾的幾款,而且很不好用,Andro
Pulltorefresh使用中碰到的問題,pulltorefresh碰到第一 在使用XScrollView布局是,無法在該布局.xml文件,放置內容布局控件,假如放置了