上一篇实现了选项卡,接下来就是进入每个模块的编写了。因为一个模块可能牵扯的技术点太多,如果完成一个模块再写一次博客的话,这样篇幅可能过大,且技术点也不容易整理,所以我把一个模块分为几篇来讲解,由于这次只是从网络获取数据,所以开头就不放效果图了,我们只需要将获取的数据log.d出来在logcat中查看就行了
作为一个安卓前端,与后台进行交互的app接触的肯定也比较多,这次我们的数据来源于聚合数据这个网站,其中“笑话大全”这个接口是免费的,大家注册了就可以使用,但是只能免费会员只能申请使用一个免费接口。我们看看这个api给我们提供的接口是什么样的
这张图把这个api的请求参数和返回参数说的很明确,我们使用get去访问,然后网站会给我们返回一个json数据,我们只需要在程序里解析这个json,然后把需要的数据通过baseadpter与预先写好的布局相匹配就行了,不过今天我们只讲如何去获得这个json数据
实现思路:
1、因为是网络请求,所以肯定是不能在主线程中请求数据,这样很容易引起ANR(程序未响应),所以我们需要使用异步操作来请求数据,但是使用普通message的机制会让程序看起来没有秩序,日后也不容易理解和维护,所以我们还是将访问网络的操作封装在asynctask中
2、Everyday这个app有三个模块都需要用到网络,如果每个模块都创建一个asynctask,会使我们的工作量增大,而且更重要的是维护的时候如果要修改一个,其他的也要进行修改,所以,为了提高效率(偷懒?),我们就写一个asynctask模板,把我们需要传入的数据通过构造函数封装起来,这样我们在创建asynctask实例的时候就可以根据不同的需求来提交不同的数据了,是不是很高兴
3、既然获得了数据,那么肯定是要使用的,为了在创建asynctask实例的地方能够获取到数据,我们创建一个接口,如果创建asynctask实例的activity需要获得数据的话,那它只要实现这个接口就行了
asynctask代码:
package com.everyday.wei.everyday; import android.os.AsyncTask; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; /** * Created by wei on 2017/10/19. */ //使用AsyncTask来对网络请求进行封装 public class GetHttpData extends AsyncTask<String,Void,String> { private String URL; private TransmitHttpData transmitHttpData; GetHttpData(String URL,TransmitHttpData transmitHttpData) { //其他活动在调用此类时需要传递访问的网址 this.URL=URL; this.transmitHttpData=transmitHttpData; } @Override protected String doInBackground(String... params) { try { //传递网址 URL url=new URL(URL); try { //打开网络链接 HttpURLConnection httpURLConnection= (HttpURLConnection) url.openConnection(); //以GET的方式访问网络 httpURLConnection.setRequestMethod("GET"); //设置最长等待时间为5秒 httpURLConnection.setConnectTimeout(5000); //获得网络返回的代码 int code=httpURLConnection.getResponseCode(); //code == 200表示网络请求成功 if (code==200) { InputStream json = httpURLConnection.getInputStream(); //将网页返回的数据解析成字符串数据 BufferedReader reader=new BufferedReader(new InputStreamReader(json,"UTF-8")); StringBuilder response=new StringBuilder(); String line; while ((line=reader.readLine())!=null) { response.append(line); } return response.toString(); } } catch (IOException e) { e.printStackTrace(); } } catch (MalformedURLException e) { e.printStackTrace(); } return null; } @Override protected void onPostExecute(String s) { //将网络获得的数据通过接口传递给活动 transmitHttpData.GetData(s); } }可以看到我们把接口作为GetHttpData的内部成员,并且在onPostExecute中把网络返回的数据传递给它
TransmitHttpData代码:
package com.everyday.wei.everyday; /** * Created by wei on 2017/10/19. */ public interface TransmitHttpData { public void GetData(String data); }这个接口只有一个函数,就是得到请求返回的数据
接下来就是在我们需要的地方获取数据,在这里我们就在Mainacticity中获取,只是证明我们是不是真的能获取到数据,让Mainactivity实现这个接口
获取数据代码:
getHttpData= (GetHttpData) new GetHttpData("http://japi.juhe.cn/joke/content/text.from?key=60fbc4de5e9c94872a10268487583390&page=1&pagesize=5",this).execute(); } @Override public void GetData(String data) { Log.d("mainActivity","我获取到的数据是"+data); }效果图:
这个是我从log cat中copy到笔记本的,因为太长了,所以为了便于观看放在笔记本中截图,可以看到,我们确实在MainActivity中获取到了数据,而且返回的格式也的确是json格式
反思与总结:
1、我们创建asynctask时,其实可以其中一些数据设置为常量,也可以将这些在构造函数中让调用其的地方进行初始化,在这里为了简洁,我就只封装了地址和接口
2、今天的内容略少,就讲讲下一篇博客的预告:下一篇是对json数据进行解析,创建baseadapter来把我们需要的信息以列表的方式显示在joke这个fragment中去