简单迅捷的Android网络模块范例:Volley
Volley 是一个提供给 Android 应用非常易用的网络库,更好的是这个库还加快了网络访问速度。本文会总览Volley库的主要功能,包括工作原理、常见工作模式以及如何使用该库从网络上并行加载缩略图到应用ListView中的流程。
Volley是 AsyncTask 的绝佳替代品。对于Android开发者来说,为了做好ListView和网络服务请求我们在AsyncTask上花了太多的时间。最近,我读了一篇关于AsyncTask非常棒的文章,我建议每一个 Android 开发者都去读一下+Fré Dumazy的 “Dark Side of AsyncTask”。AsyncTask 简直成为了所有项目中的冗余。多亏了Volley 这个框架,现在我们可以有效地减少在 AsyncTasks上花费的编码时间和精力了。
这篇文章演示了一个非常简单的 Volley的示例。例子中的VolleyTest 应用会从Yahoo Pipe上获取 JSON 文章数据并且显示在 ListView 中。
第一步: 从 Git 仓库把 Vollery 库克隆下来
git clone https://android.googlesource.com/platform/frameworks/volley
第二步: 在 Android Studio 中新建一个叫 “VolleyTest” 的项目
第三步: 将 Volley 的库源文件拷贝到 “VolleyTest”的项目中,在这里复制源码是最安全和简单的方法。
第四步: 在 AndroidManifest.xml 中添加网络权限
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.kpbird.volleytest" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="9" android:targetSdkVersion="14" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.kpbird.volleytest.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> <uses-permission android:name="android.permission.INTERNET"></uses-permission> </manifest>
第五步: 在 activity_main.xml 中添加一个 ListView
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"> <ListView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/listView" android:layout_alignParentTop="true" android:layout_alignParentLeft="true"/> </RelativeLayout>
第六步: 为 ListView 的行布局新建一个“row_listview.xml”
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="100dp"> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceLarge" android:text="Large Text" android:id="@+id/txtTitle" android:layout_gravity="left|center_vertical"/> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceMedium" android:text="Medium Text" android:id="@+id/txtDesc" android:layout_gravity="left|center_vertical" android:textColor="#929292" android:minLines="2" android:ellipsize="end" android:maxLines="2"/> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceSmall" android:text="Small Text" android:id="@+id/txtDate" android:layout_gravity="left|center_vertical" android:textColor="#d6d6d6"/> </LinearLayout>
第七步: 把如下代码添加到 MainActivity.java 文件中
通过 Volley 去请求网络需要分三步。
1、通过 Volley 类来新建一个新的请求队列:
private RequestQueue mRequestQueue; . . . mRequestQueue = Volley.newRequestQueue(this);
2、新建一个 JsonObjectRequest 对象,并且设置好各项具体参数,比如url、http method以及监听结果的listeners
JsonObjectRequest jr = new JsonObjectRequest(Request.Method.GET,url,null,new Response.Listener<JSONObject>() { @Override public void onResponse(JSONObject response) { Log.i(TAG,response.toString()); parseJSON(response); va.notifyDataSetChanged(); pd.dismiss(); ; } },new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Log.i(TAG,error.getMessage()); } });
3、将JsonObjectRequest添加到 JsonObjectRequest中:
mRequestQueue.add(jr);
下面的代码是带有Adapter,以及Model的完整代码,为了方便阅读我把所有的类都放到了一个Java文件中。
package com.kpbird.volleytest; import android.app.ProgressDialog; import android.os.Bundle; import android.app.Activity; import android.util.Log; import android.view.LayoutInflater; import android.view.Menu; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ListView; import android.widget.TextView; import com.android.volley.Request; import com.android.volley.RequestQueue; import com.android.volley.Response; import com.android.volley.VolleyError; import com.android.volley.toolbox.JsonObjectRequest; import com.android.volley.toolbox.Volley; import org.json.JSONArray; import org.json.JSONObject; import java.util.ArrayList; public class MainActivity extends Activity { private String TAG = this.getClass().getSimpleName(); private ListView lstView; private RequestQueue mRequestQueue; private ArrayList<NewsModel> arrNews ; private LayoutInflater lf; private VolleyAdapter va; private ProgressDialog pd; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); lf = LayoutInflater.from(this); arrNews = new ArrayList<NewsModel>(); va = new VolleyAdapter(); lstView = (ListView) findViewById(R.id.listView); lstView.setAdapter(va); mRequestQueue = Volley.newRequestQueue(this); String url = "http://pipes.yahooapis.com/pipes/pipe.run?_id=giWz8Vc33BG6rQEQo_NLYQ&_render=json"; pd = ProgressDialog.show(this,"Please Wait...","Please Wait..."); try{ Thread.sleep(2000); }catch(Exception e){ } JsonObjectRequest jr = new JsonObjectRequest(Request.Method.GET,url,null,new Response.Listener<JSONObject>() { @Override public void onResponse(JSONObject response) { Log.i(TAG,response.toString()); parseJSON(response); va.notifyDataSetChanged(); pd.dismiss(); ; } },new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Log.i(TAG,error.getMessage()); } }); mRequestQueue.add(jr); } private void parseJSON(JSONObject json){ try{ JSONObject value = json.getJSONObject("value"); JSONArray items = value.getJSONArray("items"); for(int i=0;i<items.length();i++){ JSONObject item = items.getJSONObject(i); NewsModel nm = new NewsModel(); nm.setTitle(item.optString("title")); nm.setDescription(item.optString("description")); nm.setLink(item.optString("link")); nm.setPubDate(item.optString("pubDate")); arrNews.add(nm); } } catch(Exception e){ e.printStackTrace(); } } class NewsModel{ private String title; private String link; private String description; private String pubDate; void setTitle(String title) { this.title = title; } void setLink(String link) { this.link = link; } void setDescription(String description) { this.description = description; } void setPubDate(String pubDate) { this.pubDate = pubDate; } String getLink() { return link; } String getDescription() { return description; } String getPubDate() { return pubDate; } String getTitle() { return title; } } class VolleyAdapter extends BaseAdapter{ @Override public int getCount() { return arrNews.size(); } @Override public Object getItem(int i) { return arrNews.get(i); } @Override public long getItemId(int i) { return 0; } @Override public View getView(int i, View view, ViewGroup viewGroup) { ViewHolder vh ; if(view == null){ vh = new ViewHolder(); view = lf.inflate(R.layout.row_listview,null); vh.tvTitle = (TextView) view.findViewById(R.id.txtTitle); vh.tvDesc = (TextView) view.findViewById(R.id.txtDesc); vh.tvDate = (TextView) view.findViewById(R.id.txtDate); view.setTag(vh); } else{ vh = (ViewHolder) view.getTag(); } NewsModel nm = arrNews.get(i); vh.tvTitle.setText(nm.getTitle()); vh.tvDesc.setText(nm.getDescription()); vh.tvDate.setText(nm.getPubDate()); return view; } class ViewHolder{ TextView tvTitle; TextView tvDesc; TextView tvDate; } } }
你也可以从 Github 上获取完整代码: https://github.com/kpbird/volley-example
原文链接: kpbird 翻译: 伯乐在线 - zerob13译文链接: http://blog.jobbole.com/71078/