(转载)Android之三种网络请求解析数据(最佳案例)
时间:2022-03-13 20:00
2016-07-25 18:02 4725人阅读 (0) 分类:
版权声明:本文为博主原创文章,未经博主允许不得转载。
目录
小武:相信大家都用过网络请求解析数据,只是方法不一样而已,但是,逻辑都是差不多的:
一:AsyncTask解析数据
AsyncTask主要用来更新UI线程,比较耗时的操作可以在AsyncTask中使用。
AsyncTask是个抽象类,使用时需要继承这个类,然后调用execute()方法。注意继承时需要设定三个泛型Params,Progress和Result的类型,如AsyncTask<Void,Inetger,Void>:
- Params是指调用execute()方法时传入的参数类型和doInBackgound()的参数类型
- Progress是指更新进度时传递的参数类型,即publishProgress()和onProgressUpdate()的参数类型
- Result是指doInBackground()的返回值类型
- doInBackgound() 这个方法是继承AsyncTask必须要实现的,运行于后台,耗时的操作可以在这里做
- publishProgress() 更新进度,给onProgressUpdate()传递进度参数
- onProgressUpdate() 在publishProgress()调用完被调用,更新进度
1.下面我们来看看主函数的布局:activity_main.xml,其中,这几个方法除了主函数不一样之外,其他的代码都一样。
[html]
- <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" >
- <EditText
- android:id="@+id/et_name"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentLeft="true"
- android:layout_alignParentTop="true"
- android:layout_marginLeft="15dp"
- android:layout_marginTop="28dp"
- android:ems="10" >
- <requestFocus />
- </EditText>
- <Button
- android:id="@+id/bt_search"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignBottom="@+id/et_name"
- android:layout_toRightOf="@+id/et_name"
- android:onClick="search"
- android:text="搜索" />
- <ListView
- android:id="@+id/listView"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_alignParentLeft="true"
- android:layout_below="@+id/et_name"
- android:layout_marginTop="26dp" >
- </ListView>
- </RelativeLayout>
2.适配器的布局:list_item.xml
[html]
- <?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="match_parent"
- >
- <ImageView
- android:id="@+id/imageView"
- android:layout_width="60dp"
- android:layout_height="60dp"
- android:layout_alignParentLeft="true"
- android:layout_alignParentTop="true"
- android:src="@drawable/ic_launcher" />
- <TextView
- android:id="@+id/textView1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentTop="true"
- android:layout_toRightOf="@+id/imageView"
- android:text="TextView" />
- <TextView
- android:id="@+id/textView2"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignLeft="@+id/textView1"
- android:layout_below="@+id/textView1"
- android:text="TextView" />
- <TextView
- android:id="@+id/textView3"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignLeft="@+id/textView2"
- android:layout_below="@+id/textView2"
- android:text="TextView" />
- </RelativeLayout>
3. 主函数 MainActivity.java
[java]
- import java.io.IOException;
- import java.io.InputStream;
- import java.net.HttpURLConnection;
- import java.net.URL;
- import java.util.ArrayList;
- import android.app.Activity;
- import android.os.AsyncTask;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.EditText;
- import android.widget.ListView;
- import com.bwie.test.Data1.MyData;
- import com.google.gson.Gson;
- import com.lidroid.xutils.HttpUtils;
- import com.lidroid.xutils.exception.HttpException;
- import com.lidroid.xutils.http.ResponseInfo;
- import com.lidroid.xutils.http.callback.RequestCallBack;
- import com.lidroid.xutils.http.client.HttpRequest.HttpMethod;
- public class MainActivity extends Activity {
- private EditText et_search;
- private ListView listView;
- private String trim;
- protected static final int SUCEESS = 0;
- private MyBaseAdapter adapter;
- ArrayList<MyData> myList = new ArrayList<MyData>();
- private Button bt_search;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- et_search = (EditText) findViewById(R.id.et_name);
- bt_search = (Button) findViewById(R.id.bt_search);
- listView = (ListView) findViewById(R.id.listView);
- // "http://93.gov.cn/93app/get_search.do?key=九三"
- bt_search.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- // TODO Auto-generated method stub
- trim = et_search.getText().toString().trim();
- String path = "http://93.gov.cn/93app/get_search.do?key="
- + trim;
- MyAsyncTask task = new MyAsyncTask();
- task.execute(path);
- }
- });
- }
- class MyAsyncTask extends AsyncTask<String, Void, String> {
- @Override
- protected String doInBackground(String... params) {
- try {
- URL url = new URL(params[0]);
- HttpURLConnection openConnection = (HttpURLConnection) url
- .openConnection();
- openConnection.setConnectTimeout(5000);
- openConnection.setReadTimeout(5000);
- int responseCode = openConnection.getResponseCode();
- if (responseCode == 200) {
- InputStream inputStream = openConnection.getInputStream();
- StreamUtils streamUtils = new StreamUtils();
- String parseStream = streamUtils.parseSteam(inputStream);
- System.out.println("-----------parseStream------------"
- + parseStream);
- return parseStream;
- }
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- return null;
- }
- @Override
- protected void onPostExecute(String result) {
- super.onPostExecute(result);
- Gson gson = new Gson();
- Data1 fromJson = gson.fromJson(result,
- Data1.class);
- System.out.println("-----------fromJson------------" + fromJson);
- ArrayList<MyData> data = fromJson.getData();
- listView.setAdapter(new MyBaseAdapter(
- MainActivity.this, data));
- }
- }
- }
4.适配器 MyBaseAdapter.java
[java]
- import java.util.ArrayList;
- import com.bwie.test.Data1.MyData;
- import com.nostra13.universalimageloader.core.DisplayImageOptions;
- import com.nostra13.universalimageloader.core.ImageLoader;
- import android.content.Context;
- import android.view.View;
- import android.view.ViewGroup;
- import android.widget.BaseAdapter;
- import android.widget.ImageView;
- import android.widget.TextView;
- public class MyBaseAdapter extends BaseAdapter {
- private Context context;
- private ArrayList<MyData> list;
- private DisplayImageOptions initOptions;
- public MyBaseAdapter(Context context, ArrayList<MyData> list) {
- this.context = context;
- this.list = list;
- //创建initOptions
- initOptions = ImageLoaderUtils.initOptions();
- }
- @Override
- public int getCount() {
- return list.size();
- }
- @Override
- public Object getItem(int arg0) {
- return null;
- }
- @Override
- public long getItemId(int arg0) {
- return 0;
- }
- @Override
- public View getView(int position, View convertView, ViewGroup viewGroup) {
- View view = View.inflate(context, R.layout.list_item, null);
- ImageView imageView = (ImageView) view.findViewById(R.id.imageView);
- TextView textView1 = (TextView) view.findViewById(R.id.textView1);
- TextView textView2 = (TextView) view.findViewById(R.id.textView2);
- TextView textView3 = (TextView) view.findViewById(R.id.textView3);
- textView1.setText(list.get(position).FROMNAME);
- textView2.setText(list.get(position).TITLE);
- textView3.setText(list.get(position).SHOWTIME);
- //图片缓存机制
- ImageLoader.getInstance().displayImage(list.get(position).IMAGEURL, imageView,initOptions);
- return view;
- }
- }
5.实体类 Data1.class
[java]
- import java.util.ArrayList;
- public class Data1 {
- public ArrayList<MyData> data;
- public class MyData{
- public String FROMNAME;
- public String IMAGEURL;
- public String SHOWTIME;
- public String TITLE;
- }
- public ArrayList<MyData> getData() {
- return data;
- }
- public void setData(ArrayList<MyData> data) {
- this.data = data;
- }
- }
6.图片缓存工具类 ImageLoaderUtils.java
[java]
- import android.content.Context;
- import com.nostra13.universalimageloader.core.DisplayImageOptions;
- import com.nostra13.universalimageloader.core.ImageLoader;
- import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
- import com.nostra13.universalimageloader.core.ImageLoaderConfiguration.Builder;
- public class ImageLoaderUtils {
- public static void initConfiguration(Context context) {
- Builder builder = new ImageLoaderConfiguration.Builder(context);
- ImageLoader.getInstance().init(builder.build());
- }
- public static DisplayImageOptions initOptions() {
- DisplayImageOptions displayImageOptions = new DisplayImageOptions.Builder()
- .showImageOnLoading(R.drawable.ic_launcher)
- .showImageForEmptyUri(R.drawable.ic_launcher)
- .cacheInMemory(true).cacheOnDisk(true).build();
- return displayImageOptions;
- }
- }
7. MyApplication.java
[java]
- import android.app.Application;
- public class MyApplication extends Application {
- public void onCreate() {
- //初始化操作
- ImageLoaderUtils.initConfiguration(getApplicationContext());
- };
- }
8. 工具类 StreamUtils.java
[java]
- import java.io.ByteArrayOutputStream;
- import java.io.IOException;
- import java.io.InputStream;
- public class StreamUtils {
- public static String parseSteam(InputStream inputStream) {
- try {
- // 定义一个字节数组输出流
- ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();
- // 定义一个字节数组
- byte[] buffer = new byte[1024];
- // 定义初始长度
- int len = 0;
- while ((len = inputStream.read(buffer)) != -1) {
- // 将读的内容,写到字节数组输出流中
- arrayOutputStream.write(buffer, 0, len);
- }
- // 将字节输出流转成字符串
- return arrayOutputStream.toString("utf-8");
- // utf-8 大小写都可以,gbk 必须大写
- } catch (IOException e) {
- e.printStackTrace();
- }
- return null;
- }
- }
到这里,一个案例就结束啦,下面的两个主函数是其他两个网络请求方法,只是主函数代码不同,其他的代码是相同的哦。
二.HttpURLConnection解析数据
针对JDK中的URLConnection连接Servlet的问题,网上有虽然有所涉及,但是只是说明了某一个或几个问题,是以FAQ的方式来解决的,而且比较零散,现在对这个类的使用就本人在项目中的使用经验做如下总结:
1:> URL请求的类别:
分为二类,GET与POST请求。二者的区别在于:
a:) get请求可以获取静态页面,也可以把参数放在URL字串后面,传递给servlet,
b:) post与get的不同之处在于post的参数不是放在URL字串里面,而是放在http请求的正文内。
请求响应流程
设置连接参数的方法
- setAllowUserInteraction
- setDoInput
- setDoOutput
- setIfModifiedSince
- setUseCaches
- setDefaultAllowUserInteraction
- setDefaultUseCaches
设置请求头或响应头
HTTP请求允许一个key带多个用逗号分开的values,但是HttpURLConnection只提供了单个操作的方法:
- setRequestProperty(key,value)
- addRequestProperty(key,value)
setRequestProperty和addRequestProperty的区别就是,setRequestProperty会覆盖已经存在的key的所有values,有清零重新赋值的作用。而addRequestProperty则是在原来key的基础上继续添加其他value。
发送URL请求
建立实际连接之后,就是发送请求,把请求参数传到服务器,这就需要使用outputStream把请求参数传给服务器:
- getOutputStream
获取响应
请求发送成功之后,即可获取响应的状态码,如果成功既可以读取响应中的数据,获取这些数据的方法包括:
- getContent
- getHeaderField
- getInputStream
对于大部分请求来说,getInputStream和getContent是用的最多的。
相应的信息头用以下方法获取:
- getContentEncoding
- getContentLength
- getContentType
- getDate
- getExpiration
- getLastModifed
HttpURLConnection
任何网络连接都需要经过socket才能连接,HttpURLConnection不需要设置socket,所以,HttpURLConnection并不是底层的连接,而是在底层连接上的一个请求。这就是为什么HttpURLConneciton只是一个抽象类,自身不能被实例化的原因。HttpURLConnection只能通过URL.openConnection()方法创建具体的实例。
虽然底层的网络连接可以被多个HttpURLConnection实例共享,但每一个HttpURLConnection实例只能发送一个请求。请求结束之后,应该调用HttpURLConnection实例的InputStream或OutputStream的close()方法以释放请求的网络资源,不过这种方式对于持久化连接没用。对于持久化连接,得用disconnect()方法关闭底层连接的socket。
1.主函数 MaActivity.class
[java]
- import java.io.InputStream;
- import java.net.HttpURLConnection;
- import java.net.URL;
- import java.util.ArrayList;
- import android.app.Activity;
- import android.os.Bundle;
- import android.os.Handler;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.EditText;
- import android.widget.ListView;
- import com.bwie.test.Data1.MyData;
- import com.google.gson.Gson;
- import com.lidroid.xutils.HttpUtils;
- import com.lidroid.xutils.exception.HttpException;
- import com.lidroid.xutils.http.ResponseInfo;
- import com.lidroid.xutils.http.callback.RequestCallBack;
- import com.lidroid.xutils.http.client.HttpRequest.HttpMethod;
- public class MainActivity extends Activity {
- private EditText et_search;
- private ListView listView;
- private String trim;
- protected static final int SUCEESS = 0;
- private MyBaseAdapter adapter;
- ArrayList<MyData> myList = new ArrayList<MyData>();
- Handler handler = new Handler() {
- private MyBaseAdapter myBaseAdapter;
- public void handleMessage(android.os.Message msg) {
- if (msg.what == SUCEESS) {
- Data1 chatInfo = (Data1) msg.obj;
- // 展示到listView上边 数据成功
- myList.addAll(chatInfo.data);
- if (myBaseAdapter == null) {
- myBaseAdapter = new MyBaseAdapter(MainActivity.this, myList);
- listView.setAdapter(myBaseAdapter);
- } else {
- myBaseAdapter.notifyDataSetChanged();
- }
- }
- };
- };
- private Button bt_search;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- et_search = (EditText) findViewById(R.id.et_name);
- bt_search = (Button) findViewById(R.id.bt_search);
- listView = (ListView) findViewById(R.id.listView);
- // "http://93.gov.cn/93app/get_search.do?key=九三"
- bt_search.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- // TODO Auto-generated method stub
- trim = et_search.getText().toString().trim();
- String path = "http://93.gov.cn/93app/get_search.do?key="
- + trim;
- // 请求数据
- getHttp(path);
- }
- });
- }
- protected void getHttp(final String path) {
- // TODO Auto-generated method stub
- new Thread() {
- public void run() {
- try {
- // http://v.juhe.cn/weixin/query?key=您申请的KEY
- // 0917c812f187b92e025c9b7c2d4e59b5 pno
- URL url = new URL(path);
- HttpURLConnection openConnection = (HttpURLConnection) url
- .openConnection();
- openConnection.setConnectTimeout(5000);
- openConnection.setReadTimeout(5000);
- int responseCode = openConnection.getResponseCode();
- if (responseCode == 200) {
- InputStream inputStream = openConnection
- .getInputStream();
- String parseSteam = StreamUtils.parseSteam(inputStream);
- Gson gson = new Gson();
- Data1 weiChatInfo = gson.fromJson(parseSteam,
- Data1.class);
- // 展示到listView上
- handler.obtainMessage(SUCEESS, weiChatInfo)
- .sendToTarget();
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- };
- }.start();
- }
- }
**其他的代码在一种复制即可,是通用的**
三.XUtils解析数据 (记得降版本,版本高会报错)
1. 功能介绍
xUtils一个公共库框架,主要包括四个部分:View,Db, Http, Bitmap 四个模块。
-
View模块主要的功能是通过注解绑定UI,资源,事件。
-
Db模块是一个orm框架, 简单的语句就能进行数据的操作。
-
Http模块主要访问网络,支持同步,异步方式的请求,支持文件的下载。
-
Bitmap模块是加载图片以及图片的处理, 支持加载本地,网络图片。而且支持图片的内存和本地缓存。
1.主函数 MaActivity.class
[java]
- import java.util.ArrayList;
- import android.app.Activity;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.EditText;
- import android.widget.ListView;
- import com.bwie.test.Data1.MyData;
- import com.google.gson.Gson;
- import com.lidroid.xutils.HttpUtils;
- import com.lidroid.xutils.exception.HttpException;
- import com.lidroid.xutils.http.ResponseInfo;
- import com.lidroid.xutils.http.callback.RequestCallBack;
- import com.lidroid.xutils.http.client.HttpRequest.HttpMethod;
- public class MainActivity extends Activity {
- private EditText et_search;
- private ListView listView;
- private String trim;
- protected static final int SUCEESS = 0;
- private MyBaseAdapter adapter;
- ArrayList<MyData> myList = new ArrayList<MyData>();
- private Button bt_search;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- et_search = (EditText) findViewById(R.id.et_name);
- bt_search = (Button) findViewById(R.id.bt_search);
- listView = (ListView) findViewById(R.id.listView);
- // "http://93.gov.cn/93app/get_search.do?key=九三"
- bt_search.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- // TODO Auto-generated method stub
- trim = et_search.getText().toString().trim();
- String path = "http://93.gov.cn/93app/get_search.do?key="
- + trim;
- // 请求数据
- getHttp(path);
- }
- });
- }
- protected void getHttp(String path) {
- // TODO Auto-generated method stub
- HttpUtils utils = new HttpUtils();
- utils.send(HttpMethod.GET, path, new RequestCallBack<String>() {
- private MyBaseAdapter adapter;
- @Override
- public void onFailure(HttpException arg0, String arg1) {
- // TODO Auto-generated method stub
- }
- @Override
- public void onSuccess(ResponseInfo<String> arg0) {
- String result = arg0.result;
- Gson gson = new Gson();
- Data1 bean = gson.fromJson(result, Data1.class);
- ArrayList<MyData> list = new ArrayList<MyData>();
- list.addAll(bean.data);
- if (adapter == null) {
- adapter = new MyBaseAdapter(MainActivity.this, list);
- } else {
- adapter.notifyDataSetChanged();
- }
- listView.setAdapter(adapter);
- }
- });
- }
- }
最后的配置一定不要忘记啦:
[java]
- android:name="com.bwie.test.MyApplication"
- android:name="android.permission.INTERNET"/>
到这里三个网络请求解析数据的案例就完工啦,下面是XUtils 的详细介绍:
2. 详细设计
2.1 View模块
2.1.1 总体设计
流程和关系较少, 请看下面的详细分析
2.1.2 流程图
2.1.3 核心类功能介绍
请先了解注解 ,动态代理 可以帮助到您, 如果已经了解请忽略。
注解和反射知识是这个模块的主要内容
1.ViewUtils.java
View和各种事件的注入以及资源的注入。
(1)主要函数
[js]- private static void injectObject(Object handler, ViewFinder finder)
第一个参数Object handler代表的是需要注入的对象, 第二个参数是需要注入View(这个View就是handler的成员变量)所在的View或者Activity的包装对象。 该方法完成了View和各种事件的注入以及资源的注入。主要的原理就是通过反射和注解。
-
完成Activity的setContentView。
-
完成View的注入。
-
完成资源的注入。
-
完成各种事件的注入。
2.ViewFinder.java
(1)主要函数
[js]- public View findViewById(int id, int pid)
- public View findViewById(int id)
如果存在父View, 优先从父View寻找,否则从当前的View或者Activity中寻找。
3.ResLoader.java
[js]- public static Object loadRes(ResType type, Context context, int id)
获取资源文件值。支持多种资源的获取。
4.EventListenerManager.java
事件的注入, 其中的设计是通过动态代理。
[js]- private final static DoubleKeyValueMap<ViewInjectInfo, Class<?>, Object> listenerCache =
- new DoubleKeyValueMap<ViewInjectInfo, Class<?>, Object>();
存放监听事件接口map。 因为有些接口有多个函数, 代理会判断事件接口是否存在, 如果存在只增加代理方法就够了, 避免重新设置监听事件接口。
[js]- public static void addEventMethod(
- ViewFinder finder,
- ViewInjectInfo info,
- &n
相关推荐
- Android系统编程入门系列之界面Activity交互响应
- 新型横向移动工具原理分析、代码分析、优缺点以及检测方案
- uni-app滚动视图容器(scroll-view)之监听上拉事件
- uniapp h5,app两端复制文本
- Android系统编程入门系列之界面Activity响应丝滑的传统动画
- 【Azure 应用服务】App Service 配置 Application Settings 访问Storage Account得到 could not be resolved: '*.file.core.windows.net'的报错。没有解析成对应中国区 Storage Account地址 *.file.core.chinacloudapi.cn
- 诺基亚短信生成!太好玩了
- iOS 跳转App Store进行评分
- 开发一个即时通讯App
- 关闭苹果IOS app自动更新
电脑软件
本类排行
- 1关闭苹果IOS app自动更新
- 2iOS 跳转App Store进行评分
- 3诺基亚短信生成!太好玩了
- 4Android系统编程入门系列之界面Activity响应丝滑的传统动画
- 5uniapp h5,app两端复制文本
- 6uni-app滚动视图容器(scroll-view)之监听上拉事件
- 7新型横向移动工具原理分析、代码分析、优缺点以及检测方案
- 8Android系统编程入门系列之界面Activity交互响应
- 9开发一个即时通讯App
- 10【Azure 应用服务】App Service 配置 Application Settings 访问Storage Account得到 could not be resolved: '*.file.core.windows.net'的报错。没有解析成对应中国区 Storage Account地址 *.file.core.chinacloudapi.cn