本菜鸟因为之前一直使用的是公司前辈封装好的类(网络接口调用超级方便有木有)完全没有想过有一天我会自己写,然后今天接触的时候一脸懵逼,然后今天花了一天时间终于研究好了;哈哈哈哈哈
二话不说先上代码:
package com.example.administrator.caipiaoproject; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.os.Parcelable; import android.support.annotation.Nullable; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.util.Log; import android.view.View; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserFactory; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.StringReader; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.ProtocolException; import java.net.URL; import java.util.ArrayList; import java.util.List; /** * Created by Administrator on 2018/3/5. */ public class HomeActivity extends BaseActivity { private RecyclerView recyclerView; private CaiPiaoAdapter caiPiaoAdapter; private TextView number, time; private List<CaiPiaoData> list = new ArrayList<>(); private String key = "123"; private CaiPiaoViewHolder caiPiaoViewHolder; private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.arg1) { case 1: getXml(msg.obj.toString()); break; } } }; private String open_time; private String how_time; private String code; protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); list = getIntent().getParcelableArrayListExtra(key); setContentView(R.layout.activity_start); if (list == null) { setListData(); } recyclerView = findViewById(R.id.recycler); caiPiaoAdapter = new CaiPiaoAdapter(this, list); recyclerView.setAdapter(caiPiaoAdapter); LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this); recyclerView.setLayoutManager(linearLayoutManager); number = findViewById(R.id.number); time = findViewById(R.id.time_today); getnumber(); } @Override public void initTitle() { setMiddleTitele("双色球助手"); setRemoveleft(); } private void setListData() { list = new ArrayList<>(); CaiPiaoData ssq = new CaiPiaoData(R.drawable.ssq, "双色球", 1); list.add(ssq); CaiPiaoData qxc = new CaiPiaoData(R.drawable.qxc2, "七星彩", 2); list.add(qxc); CaiPiaoData dlt = new CaiPiaoData(R.drawable.dlt, "大乐透", 3); list.add(dlt); CaiPiaoData fc3D = new CaiPiaoData(R.drawable.fc3d, "福彩3D", 4); list.add(fc3D); CaiPiaoData gdfc = new CaiPiaoData(R.drawable.gdfc, "广东福彩36选7", 5); list.add(gdfc); CaiPiaoData gdfc2 = new CaiPiaoData(R.drawable.gdfc2, "广东福彩26选5", 6); list.add(gdfc2); CaiPiaoData klsf = new CaiPiaoData(R.drawable.kuaileshifen, "快乐十分", 7); list.add(klsf); CaiPiaoData ssc = new CaiPiaoData(R.drawable.ssc, "时时彩", 8); list.add(ssc); } @Override public void onClickRight() { Intent intent = new Intent(this, ShouCangActivity.class); intent.putParcelableArrayListExtra(key, (ArrayList<? extends Parcelable>) list); startActivity(intent); } private void getnumber() { new Thread(new Runnable() { @Override public void run() { String jos = ""; String url = "..."; try { URL url_caipiao = new URL(url); HttpURLConnection connection = (HttpURLConnection) url_caipiao.openConnection(); connection.setRequestMethod("GET"); int responseCode = connection.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_OK) { InputStream inputStream = connection.getInputStream(); InputStreamReader inputStreamReader = new InputStreamReader(inputStream); BufferedReader reader = new BufferedReader(inputStreamReader); String result; while ((result = reader.readLine()) != null) jos += result; } Message message = handler.obtainMessage(); message.obj = jos; message.arg1 = 1; handler.sendMessage(message); } catch (MalformedURLException e) { e.printStackTrace(); } catch (ProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }).start(); } //json解析 /* private void getJson(String s) { try { JSONObject jsonObject = new JSONObject(s); JSONArray jsonArray = jsonObject.optJSONArray("data"); if (jsonArray != null) { for (int i = 0; i < jsonArray.length(); i++) { JSONObject jsonObject1 = jsonArray.optJSONObject(i); //开奖时间 open_time = jsonObject1.optString("opentime"); //开奖期数 how_time = jsonObject1.optString("expect"); code = jsonObject1.optString("opencode"); } number.setText(code); time.setText(open_time); } } catch (JSONException e) { e.printStackTrace(); } }*/ private void getXml(String s) { try { XmlPullParserFactory xmlPullParserFactory = XmlPullParserFactory.newInstance();//获取xml抓取解析器工厂实例 XmlPullParser xmlPullParser = xmlPullParserFactory.newPullParser();//获取xml抓取解析器实例 xmlPullParser.setInput(new StringReader(s)); int type = xmlPullParser.getEventType();//获取当前解析事件 while (type != XmlPullParser.END_DOCUMENT) {//0是开始解析节点,1是完成解析节点,2是解析子节点,3是完成子节点解析,4暂且不祥 String nodename = xmlPullParser.getName();//获取节点名字 switch (type) { case XmlPullParser.START_TAG: { if ("row".equals(nodename)) {//判断是否等于子节点名称 open_time = xmlPullParser.getAttributeValue(null, "opentime");//获取标签里的多个值 how_time = xmlPullParser.getAttributeValue(null, "expect"); code = xmlPullParser.getAttributeValue(null, "opencode"); } } break; default: break; } type = xmlPullParser.next();//每次循环完成必须调用此方法,换成下一个值 } number.setText(code); time.setText(open_time); } catch (XmlPullParserException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
这里大家可以看到我用了json和pull两种方式进行解析,但是解析之前,我们肯定要写一个接口啊,对吧,然后在网上找了好多接口的写法,我承认真的是层出不穷,但是原谅我一个从来没有写过接口的人,我真的看不懂,于是开始了自己摸索,终于让我成功悟出其中的奥妙
首先,调用接口的方法有很多种,其中比较常用的就是我上面所用的
HttpURLConnection 方法
还有一种呢就是OKHttp了,但是这个方法并不在google官方api中,所以使用的时候需要添加依赖,这里就主要介绍HttpURLConnection方法了
这个方法使用前我们需要一个接口,于是可以看到我定义了
String url = "...";
(为了保险起见我隐藏掉了自己的接口)
然后我们定义一个URL,传入我们的接口
然后我们初始化HttpURLConnection方法,这里调用的是url.getconnection();并且将其强制转换成HttpURLConnection类型
然后重点来了,如果我要要从服务器拿数据
我们在下面一行就写“GET”,如果是我们要发送数据,就写“POST”;
connection.setRequestMethod("GET");然后我们会看到
getResponseCode
这个方法,这个方法是返回一个服务器返回的数据,如果是200,就代表一切正常,如果是401,那就代表数据异常,还有一种情况就是-1(小编在这里就遇到了,初步原因是因为我没有设置网络权限)
然后我们用输入流读取拿到的数据,警告:重要的事情说三遍
网络请求要使用子线程!!!!网络请求要使用子线程!!!!网络请求要使用子线程!!!!
好了,然后这里我们需要一个handle发送通知,将子线程中的数据取出来,拿到主线程(别问为什么,不然你的接口返回的永远都是没数据),下面就开始了我们今天的重点:
1,如果你拿到的是xml格式的数据,那你有两种解析方法,第一个是pull第二个是sax(pull简单多了,所以这里主要讲pull)
2,如果你拿到的是json类型的数据,你也有两种方式,第一个是json,第二个是gson,至于为何只讲json不讲gson,我想各位百度一下就知道其中利弊
pull解析:
pull解析xml格式数据:
private void getXml(String s) { try { XmlPullParserFactory xmlPullParserFactory = XmlPullParserFactory.newInstance();//获取xml抓取解析器工厂实例 XmlPullParser xmlPullParser = xmlPullParserFactory.newPullParser();//获取xml抓取解析器实例 xmlPullParser.setInput(new StringReader(s)); int type = xmlPullParser.getEventType();//获取当前解析事件 while (type != XmlPullParser.END_DOCUMENT) {//0是开始解析节点,1是完成解析节点,2是解析子节点,3是完成子节点解析,4暂且不祥 String nodename = xmlPullParser.getName();//获取节点名字 switch (type) { case XmlPullParser.START_TAG: { if ("row".equals(nodename)) {//判断是否等于子节点名称 open_time = xmlPullParser.getAttributeValue(null, "opentime");//获取标签里的多个值 how_time = xmlPullParser.getAttributeValue(null, "expect"); code = xmlPullParser.getAttributeValue(null, "opencode"); } } break; default: break; } type = xmlPullParser.next();//每次循环完成必须调用此方法,换成下一个值 }
这里我们先初始化pull解析器工厂,然后将HttpURLConnection中接口拿到的数据使用setInput()进行转换,然后getEventype()获取当前的解析事件,进入循环,这里要介绍五个参数以及它们所对应的值:
1,START_DOCUMENT==0,开始解析文件
2,START_TAG==2,开始解读节点
3,END_TAG==3,解析节点结束
4,END_DOCYMENT==1,解析文件结束
5,TEXT==4,读取字符信息,这里其实和getText()是一样的(不是nextText()!!!不是nextText()!!!!不是nextText()!!!!);
这里首先判断当它没有结束解析文件,然后进行循环,使用getName拿到节点名字,将节点名字进行对比,如果节点名字相同,就是用nextText()获取其中的值,嗯。。。网上大多数文章就介绍道这里了!但是!!我遇到了不一样的事情!!因为你们的xml文件是这样的:
<a>
<b>
“hahahahaha”
</b>
</a>
可是我遇到的是这样的呀:
<a>
<b name="11" password="22"/>
</a>
于是天真的我以为读了节点b就可以拿到里面的数据了,于是这里就要使用到这个方法
xmlPullParser.getAttributeValue
这个方法是拿到子节点中的数据的,比如说上面的例子,当我们判断b是等于子节点名称时,就是用此方法,传入null和“name”就可以拿到数据11了。
json解析:
json解析用的就特别多了,首先我们将HttpURLConnection拿到的json格式数据的字符串拿出来,再使用
JSONObject jsonObject = new JSONObject(s);
就可以将字符串转换成json格式,然后这时候对于新手来说,首先要看的不是忙着解析,而是要看好jsonobject的格式啊!因为一般的json不可能只包含了外面一层,也可能使多层的json,所以我们使用json解析的第一件事情就是先看好json到底是怎样的格式,
比如说:
{“name”:“111”,“password”:“123”}
这就是一个很简单的json格式
解析它,我们只需要使用jsonObject的potString方法,传入字段“name”就可以拿到name的值了
但是还有一种格式
{"name":""json","data":"[{"a":"1","b","2"}]"}
这是包含了jsonArray的jsonobject,所以首先我们得拿到jsonarray,使用jsonobject.optjsonarray("data")就可以拿到上面这个jsonArray的数据了,然后我们将jsonArray进行循环,拿出里面的每一个jsonObject,再使用与上面相同的jsonobject解析方式,就可以拿到全部的数据了!是不是很简单。