本次实验主要是针对于开源项目AsyncHttpClient的使用和JSON解析来进行。
首先我们先来了解一下什么是开源项目,访问网络是一个耗时的操作,并且访问网络的操作都在子线程中进行,但在Android中,发送、处理HTTP请求十分常见,每次与数据进行交互都需要开启一个子线程,这样非常麻烦,为了解决这个问题,就开发出了开源项目——AsyncHttpClient,它的特点有:发送异步HTTP请求、HTTP请求是发生在UI线程外、内部采用了线程池来处理并发请求。要使用AsyncHttpClient首先github要下载它的源代码,在这里向大家介绍一个网站:http://www.github.com.下载完成之后,将其复制到libs文件夹下,然后为其添加路径,右击Add as Library。如果要使用AsyncHttpClient,首先要创建AsyncHttpClient实力,然后u设置参数,接着通过AsyncHttpClient的实例对象访问网络。如果访问成功则会回调AsyncHttpResponseHandler接口中的OnSucess方法,失败则会回调OnFailure方法。
然后我们来了解一下Json,JSon的格式分为两种,一种是包含键值对的Object类型,另一种就是Array类型,这两种可以相互嵌套,但一定要分清楚。其中Object类型的最大特点是最外面有一对花括号,内部的数据多为键值对的形式,键和值用冒号隔开,多个键值对用逗号分隔;Array最大的特点是外层以中括号包围,值之间用逗号隔开。解析Json数据有很多方法,可以使用官方提供的JSONObject,也可以使用谷歌的开源库GSON。在下面的案例中,我们是用GSON库来进行解析的。
接下来我们来进行新闻客户端这个案例,用来实现获取服务器的XML文件并将其解析出来捆绑显示到LisView中。
最后实现效果如下所示:
(1)用户交互界面的设计与实现
主布局activity_main.xml文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
tools:context=".MainActivity"
android:orientation="vertical">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/loading"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:visibility="invisible">
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="正在加载信息..." />
</LinearLayout>
<ListView
android:id="@+id/lv_news"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
</LinearLayout>
ListView控件子布局news_item.xml文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="65dp">
<com.loopj.android.image.SmartImageView
android:id="@+id/siv_icon"
android:layout_width="80dp"
android:layout_height="60dp"
android:scaleType="centerCrop"
android:src="@mipmap/ic_launcher"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"></com.loopj.android.image.SmartImageView>
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginTop="10dp"
android:layout_toRightOf="@id/siv_icon"
android:ellipsize="end"
android:maxLength="20"
android:singleLine="true"
android:text="我是标题"
android:textColor="#000000"
android:textSize="18sp" />
<TextView
android:id="@+id/tv_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/tv_title"
android:layout_marginLeft="5dp"
android:layout_marginTop="5dp"
android:layout_toRightOf="@id/siv_icon"
android:ellipsize="end"
android:maxLength="16"
android:maxLines="1"
android:text="我是描述"
android:textColor="#99000000"
android:textSize="14sp" />
<TextView
android:id="@+id/tv_type"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_marginBottom="5dp"
android:layout_marginRight="10dp"
android:text="评论"
android:textColor="#99000000"
android:textSize="12sp" />
</RelativeLayout>
(2)创建实体类NewsInfo
public class NewsInfo {
private String iconPath;
private String title;
private String description;
private int type;
private long comment;
public String getIconPath() {
return iconPath;
}
public void setIconPath(String iconPath) {
this.iconPath = iconPath;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public long getComment() {
return comment;
}
public void setComment(long comment) {
this.comment = comment;
}
}
(3)创建工具类JsonParse负责解析JSON数据
public class JsonParse { public static List<NewsInfo> getNewsInfo(String json){ Gson gson=new Gson(); Type listType=new TypeToken<List<NewsInfo>>(){}.getType(); List<NewsInfo> newsInfos=gson.fromJson(json,listType); return newsInfos; } }
(4)创建适配器NewsAdapter类
(5)界面逻辑代码的设计与实现public class NewsAdapter extends ArrayAdapter<NewsInfo>{ public NewsAdapter(Context context, List<NewsInfo> objects){ super(context, R.layout.news_item,objects); } public View getView(int position, View convertView, ViewGroup parent){ NewsInfo newsInfo=getItem(position); ViewHolder viewHolder; View view=null; if(convertView==null){ view=View.inflate(getContext(),R.layout.news_item,null); viewHolder=new ViewHolder(); ViewHolder.siv=(SmartImageView) view.findViewById(R.id.siv_icon); ViewHolder.tv_title=(TextView) view.findViewById(R.id.tv_title); ViewHolder.tv_description=(TextView) view.findViewById(R.id.tv_description); ViewHolder.tv_type=(TextView) view.findViewById(R.id.tv_type); } else{ view=convertView; viewHolder=(viewHolder)view.getTag(); } } }
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } private void fillData(){ AsyncHttpClient client=new AsyncHttpClient(); client.get("http://10.3.24.176:8080/NewsInfo.json",new AsyncHttpResponseHandler(){ public void onSuccess(int i,org.apache.http.Header[] headers,byte[] bytes){ try { String json=new String(bytes,"utf-8"); newsInfos=JsonParse.getNewsInfo(json); if(newsInfo==null){ Toast.makeText(MainActivity.this, "解析失败", Toast.LENGTH_SHORT).show(); lvNews.setAdapter(new NewsAdapter(MainActivity.this.newsInfo)); } }catch(Exception e){ e.printStackTrace(); } } public void onFailare(int i,org.apache.http.Header[] headers,byte[] bytes,Throwable throwable){ } }); } }
(6)由于需要从服务器上下载一个XML,需要开启tomcat服务器。在tomcat根目录下找到bin文件夹,运行该文件夹中的startup.bat文件即可开启服务器。打开tomcat的安装目录中的webapps文件夹,将NwsInfo.xml文件放置在ROOT文件夹中。