精华内容
下载资源
问答
  • 首先,了解 api 调用方式。例如:琼台博客 api 说明地址如下:http://www.qttc.net/openapi.html。...当任何不是普通本地文件读取时,例如在读取远程文件或 popen() 以及 fsockopen() 返回流时,读取会在...

    首先,了解 api 调用的方式。例如:琼台博客的 api 说明地址如下:http://www.qttc.net/openapi.html

    然后,获取 api 结构数据。(参考http://sg2.php.net/manual/zh/function.fread.php)

    当从任何不是普通本地文件读取时,例如在读取从远程文件popen() 以及 fsockopen() 返回的流时,读取会在一个包可用之后停止。这意味着应该如下例所示将数据收集起来合并成大块。

     <?php
    // 对 PHP 5 及更高版本
    $handle = fopen("http://www.example.com/", "rb");
    $contents = stream_get_contents($handle);
    fclose($handle);
    ?> 
     
    或者
     
     <?php
    $handle = fopen("http://www.example.com/", "rb");
    $contents = '';
    while (!feof($handle)) {
      $contents .= fread($handle, 8192);
    }
    fclose($handle);
    ?> 

     

    最后,解析并输出内容。首先对 contents 变量中的 JSON  数据处理,然后变成 PHP 可以调用的数据,再使用 foreach 遍历输出即可。

     

    $contents = json_decode($contents);
    foreach ($contents as $key) {
    do sth;
    }

     

    转载于:https://www.cnblogs.com/eterwei/p/3591950.html

    展开全文
  • 前面一篇我们学习了如何拿到testlink...我们需要拿到接口的一些请求方式和请求地址,或者post方法一般都有json的传参,以及请求完之后,我们需要拿到期待结果响应状态码,进行测试断言,这个是一个接口测试基本...

            前面一篇我们学习了如何拿到testlink中测试用例的步骤,这篇我们介绍如何拿到测试用例步骤对应的期待结果。从步骤或者期待结果去解析数据,这个是我们的重点。不管步骤还是期待结果,都是我们设定好的Json格式字符串。我们需要拿到接口的一些请求方式和请求地址,或者post方法一般都有json的传参,以及请求完之后,我们需要拿到期待结果的响应状态码,进行测试断言,这个是一个接口测试的基本过程。

           不知道你们注意到没有,前面我把project 名称“API_Automation”一直是使用硬编码的方式,这个是不灵活的方式,我这里暂时不去提取到配置文件,等我们写用例运行入口的代码再去优化这个问题。我们的思想就是,我连接你的testlink环境,你只需要提供project名称,我就默认去遍历这个项目下的测试套件,然后嵌套遍历测试用例,再次嵌套遍历测试步骤,一次性运行完全部的接口测试用例。

    1.获取步骤对应的期待结果

         按照前面一篇获取步骤的思路,我们去获取用例下步骤的期待结果。在com.testlink.tests包下,新建一个GetExpectedResult.java文件。注意下面我的获取用例的方式,然后这里也需要进行数据清洗操作。

    package com.testlink.tests;
    
    import java.util.List;
    
    import org.apache.commons.lang3.StringEscapeUtils;
    import org.testng.annotations.Test;
    
    import com.qa.util.TestlinkUtil;
    
    import br.eti.kinoshita.testlinkjavaapi.TestLinkAPI;
    import br.eti.kinoshita.testlinkjavaapi.model.TestCase;
    import br.eti.kinoshita.testlinkjavaapi.model.TestCaseStep;
    
    public class GetExpectedResult {
    	
    	TestLinkAPI api = TestlinkUtil.connect();
    	
    	@Test
    	public void getExpectedResult() {
    		//我这里直接根据external id去拿到单个测试用例,方便测试,就不像前面那样全部获取所有用例
    		TestCase tc = api.getTestCaseByExternalId("at-1", null);
    		//得到单个用例的测试步骤集合
    		List<TestCaseStep> steps = tc.getSteps();
    		//遍历步骤,但是实际上我们在testlink只写了一个测试步骤,集合只有一个元素
    		for (TestCaseStep testCaseStep : steps) {
    			String expectResult = testCaseStep.getExpectedResults();
    			System.out.println(expectResult);
    			
    			//数据清洗
    			//去除最外层的<p> </p>		
    			String s1 = expectResult.split("<p>")[1].split("</p>")[0];
    			//把全部br换行符替换成空字符
    			String s2 = s1.replaceAll("<br />", "");
    			//为了双引号在控制台正常显示
    			String result = StringEscapeUtils.unescapeHtml4(s2);
    			System.out.println(result);
    		}
    	}
    }
    

    先来解释下什么是ExternalId,请看下图

    上面是根据这个红圈id来得到这个用例,从而得到这个用例下所有信息。

    运行测试结果:

    [RemoteTestNG] detected TestNG version 6.14.3
    2018-06-03 11:11:52 848 INFO  TestBase:28 - 正在读取配置文件...
    Hello!
    <p>{"code":"200"}</p>
    
    {"code":"200"}
    PASSED: getExpectedResult
    

          再看代码,只要你给我提供一个TestCase对象,我就给你返回期待结果字符串,至于你如何找到TestCase不是这个方法关系的问题,我们抽象方法如下,为了节约代码篇幅,我没有贴TestlinkUtil.java全部代码,下面这段代码放最后就行。

    public static String getResult(TestLinkAPI api,TestCase tCase) {
    		
    		TestCase tc = api.getTestCaseByExternalId(tCase.getFullExternalId(), null);
    		List<TestCaseStep> tcs = tc.getSteps();
    		
    		String result = null;
    		//遍历steps集合
    		for (TestCaseStep testCaseStep : tcs) {
    			
    			String expectResult = testCaseStep.getExpectedResults();
    			//System.out.println(expectResult);
    			
    			//数据清洗
    			//去除最外层的<p> </p>		
    			String s1 = expectResult.split("<p>")[1].split("</p>")[0];
    			//把全部br换行符替换成空字符
    			String s2 = s1.replaceAll("<br />", "");
    			//为了双引号在控制台正常显示
    			result = StringEscapeUtils.unescapeHtml4(s2);
    		}
    		
    		return result;
    		
    	}

         下面写一个测试类,来测试我们抽取到TestlinkUtil.java中的getResult方法好不好用。

    package com.testlink.tests;
    
    import org.testng.annotations.Test;
    
    import com.qa.util.TestlinkUtil;
    
    import br.eti.kinoshita.testlinkjavaapi.TestLinkAPI;
    import br.eti.kinoshita.testlinkjavaapi.model.TestCase;
    
    public class GetResultTest {
    	
    	TestLinkAPI api = TestlinkUtil.connect();
    	
    	@Test
    	public void getResult() {
    		
    		String ExternalID = "au-1";
    		TestCase tc = api.getTestCaseByExternalId("at-1", null);
    		
    		String result = TestlinkUtil.getResult(api, tc);
    		System.out.println(result);
    	}
    }
    

    运行结果:

    [RemoteTestNG] detected TestNG version 6.14.3
    2018-06-03 11:56:09 555 INFO  TestBase:28 - 正在读取配置文件...
    Hello!
    {"code":"200"}
    PASSED: getResult

    2.获取请求方式

          目前,我们拿到了测试用例的步骤和期待结果。接下来就是对JSON字符串进行解析操作,得到对应json对象的值。这里,我们先介绍得到请求方式。因为这个最重要,一旦拿到请求方式,就可以决定调用get还是post(其他方法暂不考虑)方法去进行接口测试。

    在com.testlink.tests包新建一个GetRequestType.java文件

    package com.testlink.tests;
    
    import org.testng.annotations.Test;
    
    import com.alibaba.fastjson.JSON;
    import com.alibaba.fastjson.JSONObject;
    import com.qa.util.TestUtil;
    import com.qa.util.TestlinkUtil;
    
    import br.eti.kinoshita.testlinkjavaapi.TestLinkAPI;
    import br.eti.kinoshita.testlinkjavaapi.model.TestCase;
    
    public class GetRequestType {
    	
    	TestLinkAPI api = TestlinkUtil.connect();
    	
    	@Test
    	public void getRequestMethod_get() {
    		
    		String ExternalID = "at-1";
    		TestCase tc = api.getTestCaseByExternalId(ExternalID, null);
    		
    		String action = TestlinkUtil.getTestCaseAction(api, tc);
    		
    		//把字符串转换成json对象
    		JSONObject actionJson = JSON.parseObject(action);
    		//下面开始解析得到名称为method的json对象的值
    		String method = TestUtil.getValueByJPath(actionJson, "method");
    		System.out.println(method);
    	}
    	
    	@Test
    	public void getRequestMethod_post() {
    		
    		String ExternalID = "at-2";
    		TestCase tc = api.getTestCaseByExternalId(ExternalID, null);
    		
    		String action = TestlinkUtil.getTestCaseAction(api, tc);
    		
    		//把字符串转换成json对象
    		JSONObject actionJson = JSON.parseObject(action);
    		//下面开始解析得到名称为method的json对象的值
    		String method = TestUtil.getValueByJPath(actionJson, "method");
    		System.out.println(method);
    	}
    
    }
    

    运行测试结果:

    [RemoteTestNG] detected TestNG version 6.14.3
    2018-06-03 12:49:15 098 INFO  TestBase:28 - 正在读取配置文件...
    Hello!
    get
    post
    PASSED: getRequestMethod_get
    PASSED: getRequestMethod_post

          下面来对获取请求方法进行封装,同样只贴出这个方法,不贴出全部TestlinkUtil.java代码。

    public static String getRequestType(String stepAction) {
    		
    		//先把string转换成json对象
    		JSONObject actionJson = JSON.parseObject(stepAction);
    		//注意这里method是硬编码,和你testlink步骤中要求一致
    		String requestType = TestUtil.getValueByJPath(actionJson, "method");
    		return requestType;
    	}

    再次写一个单元测试来测试封装的方法。

    package com.testlink.tests;
    
    import org.testng.annotations.Test;
    
    import com.alibaba.fastjson.JSON;
    import com.alibaba.fastjson.JSONObject;
    import com.qa.util.TestUtil;
    import com.qa.util.TestlinkUtil;
    
    import br.eti.kinoshita.testlinkjavaapi.TestLinkAPI;
    import br.eti.kinoshita.testlinkjavaapi.model.TestCase;
    
    public class GetRequestTypeTest {
    TestLinkAPI api = TestlinkUtil.connect();
    	
    	@Test
    	public void getRequestMethod_get() {
    		
    		String ExternalID = "at-1";
    		TestCase tc = api.getTestCaseByExternalId(ExternalID, null);
    		
    		String action = TestlinkUtil.getTestCaseAction(api, tc);
    		
    		String request = TestlinkUtil.getRequestType(action);
    		System.out.println(request);
    	}
    	
    	@Test
    	public void getRequestMethod_post() {
    		
    		String ExternalID = "at-2";
    		TestCase tc = api.getTestCaseByExternalId(ExternalID, null);
    		
    		String action = TestlinkUtil.getTestCaseAction(api, tc);
    		
    		String request = TestlinkUtil.getRequestType(action);
    		System.out.println(request);
    	}
    
    }
    

    运行结果:

    [RemoteTestNG] detected TestNG version 6.14.3
    2018-06-03 13:08:47 121 INFO  TestBase:28 - 正在读取配置文件...
    Hello!
    get
    post
    PASSED: getRequestMethod_get
    PASSED: getRequestMethod_post
          本篇学完之后,可以得到用例步骤中的具体测试步骤描述文字和json中的请求类型。这个请求类型,将来在我们测试执行入门模块会进行调用去判断,从而决定去调用RestClient.java中的哪个一个封装好的接口请求方法。下一篇继续介绍json解析,拿到接口url和json参数以及期待结果中的状态码。





    展开全文
  • jquerypost请求从接口json){ "m":"dh", "oper":"fdghgh", "sqlid":"2455", "params":{ "PHONE":"手机号码" } },获取到结果后,然后将结果解析并编译成表格形式.这个怎么弄,请教各位大神 我已经弄...
  • Geocoding API 是一类简单HTTP接口,用于提供从地址到经纬度坐标或者经纬度坐标到地址的转换服务,用户可以使用C# 、C++、Java等开发语言发送HTTP请求且接收JSON、XML返回数据。Geocoding API包括地址解析和逆...

    什么是Geocoding?

    Geocoding API 是一类简单的HTTP接口,用于提供从地址到经纬度坐标或者从经纬度坐标到地址的转换服务,用户可以使用C# 、C++、Java等开发语言发送HTTP请求且接收JSON、XML的返回数据。

    043ffe189d5fe2d3006419913472c62d.png

    Geocoding API包括地址解析和逆地址解析功能:

    地理编码:即地址解析,由详细到街道的结构化地址得到百度经纬度信息,例如:“北京市海淀区中关村南大街27号”地址解析的结果是“lng:116.31985,lat:39.959836”。同时,地理编码也支持名胜古迹、标志性建筑名称直接解析返回百度经纬度,例如:“百度大厦”地址解析的结果是“lng:116.30815,lat:40.056885” ,通用的POI检索需求,建议使用Place API。

    逆地理编码:即逆地址解析,由百度经纬度信息得到结构化地址信息,例如:“lat:31.325152,lng:120.558957”逆地址解析的结果是“江苏省苏州市虎丘区塔园路318号”。

    使用说明

    使用限制:

    百度地图Geocoding API是一套免费对外开放的API,默认配额6000次/天,若需更高配额,请申请开发者认证以获取更高配额和更及时技术支持。

    使用方法:

    第一步:申请ak(即获取密钥),若无百度账号则首先需要注册百度账号。

    第二步,拼写发送http请求的url,注意需使用第一步申请的ak。

    第三步,接收http请求返回的数据(支持json和xml格式)。

    Hello, World示例:

    发送一个地址是“百度大厦”的请求,返回该地址对应的地理坐标。示例URL如下:

    服务地址

    服务地址:

    http://api.map.baidu.com/geocoder/v2/

    组成说明:

    域名:api.map.baidu.com

    服务名:geocoder

    服务版本号:较之前版本,v2版本新增参数。

    通用接口参数

    参数是否必须默认值格式举例含义

    output

    xml

    json或xml

    输出格式为json或者xml

    ak

    E4805d16520de693a3fe707cdc962045

    用户申请注册的key,自v2开始参数修改为“ak”,之前版本参数为“key”

    sn

    若用户所用ak的校验方式为sn校验时该参数必须。 (sn生成算法)

    callback

    callback=showLocation(JavaScript函数名)

    将json格式的返回值通过callback函数返回以实现jsonp功能

    地理编码服务

    地理编码专属请求参数:

    参数是否必须默认值格式举例含义 参数

    address

    北京市海淀区上地十街10号

    根据指定地址进行坐标的反定向解析,最多支持100个字节输入。

    可以输入三种样式的值,分别是:

    1、标准的地址信息,如北京市海淀区上地十街十号

    2、名胜古迹、标志性建筑物,如天安门,百度大厦

    3、支持“*路与*路交叉口”描述方式,如北一环路和阜阳路的交叉路口

    注意:后两种方式并不总是有返回结果,只有当地址库中存在该地址描述时才有返回。

    city

    “北京市”

    “广州市”

    地址所在的城市名。用于指定上述地址所在的城市,当多个城市都有上述地址时,该参数起到过滤作用。

    对于address字段可能会出现中文或其它一些特殊字符(如:空格),对于类似的字符要进行编码处理,编码成 UTF-8 字符的二字符十六进制值,凡是不在下表中的字符都要进行编码。

    字符集合字符

    URL非保留字

    a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 - _ . ~

    URL保留字

    ! * ' ( ) ; : @ & = + $ , / ? % # [ ]

    附注:

    1、javascript中一般采用encodeURIComponent函数对特殊字符进行编码;

    2、Java中可以使用函数URLEncoder.encode对特殊字符进行编码;

    3、C#中可以使用函数HttpUtility.UrlEncode对特殊字符进行编码;

    4、php中可以使用函数urlencode对特殊字符进行编码。

    地理编码示例:

    地理编码返回结果字段:

    名称

    类型

    说明

    status

    Int

    返回结果状态值, 成功返回0,其他值请查看下方返回码状态表。

    location

    object

    经纬度坐标

    lat

    float

    纬度值

    lng

    float

    经度值

    precise

    Int

    位置的附加信息,是否精确查找。1为精确查找,即准确打点;0为不精确,即模糊打点。

    confidence

    Int

    可信度,描述打点准确度

    level

    string

    地址类型

    json格式的返回值:

    //带回调函数的返回格式

    showLocation&&showLocation(

    {

    status: 0,

    result: {

    location: {

    lng: 116.30814954222,

    lat: 40.056885091681

    },

    precise: 1,

    confidence: 80,

    level: "商务大厦"

    }

    }

    )

    //不带回调函数的返回值

    {

    status: 0,

    result: {

    location: {

    lng: 116.30814954222,

    lat: 40.056885091681

    },

    precise: 1,

    confidence: 80,

    level: "商务大厦"

    }

    }

    xml格式的返回值:

    0

    40.056885091681

    116.30814954222

    1

    80

    商务大厦

    特别说明: 若解析status字段为OK,但结果内容为空,原因分析及可尝试方法: 1、地址库里无此数据,本次结果为空; 2、加入city字段重新解析; 3、将过于详细或简单的地址更改至省市区县街道重新解析。

    逆地理编码服务

    逆地理编码专属请求参数:

    参数是否必须默认值格式举例含义

    coordtype

    bd09ll

    bd09ll 百度经纬度坐标

    坐标的类型,目前支持的坐标类型包括:bd09ll(百度经纬度坐标)、bd09mc(百度米制坐标)、gcj02ll(国测局经纬度坐标)、wgs84ll( GPS经纬度)

    location

    38.76623,116.43213 lat,lng

    根据经纬度坐标获取地址

    pois

    0

    0

    是否显示指定位置周边的poi,0为不显示,1为显示。当值为1时,显示周边100米内的poi。

    状态字段:

    名称类型说明

    status

    constant

    返回结果状态值, 成功返回0,其他值请查看附录。

    location

    lat

    纬度坐标

    lng

    经度坐标

    formatted_address

    结构化地址信息

    business

    所在商圈信息,如 "人民大学,中关村,苏州街"

    addressComponent

    country

    国家

    province

    省名

    city

    城市名

    district

    区县名

    street

    街道名

    street_number

    街道门牌号

    adcode

    行政区划代码

    country_code

    国家代码

    direction

    和当前坐标点的方向,当有门牌号的时候返回数据

    distance

    和当前坐标点的距离,当有门牌号的时候返回数据

    pois(周边poi数组)

    addr

    地址信息

    cp

    数据来源

    direction

    和当前坐标点的方向

    distance

    离坐标点距离

    name

    poi名称

    poiType

    poi类型,如’ 办公大厦,商务大厦’

    point

    poi坐标{x,y}

    tel

    电话

    uid

    poi唯一标识

    zip

    邮编

    sematic_description

    constant

    当前位置结合POI的语义化结果描述。

    json示例:

    xml示例:

    特别说明:

    1、因为Geocoding和反Geocoding使用的门址数据以及算法都不是一样的,所以会出现不能一一对应的现象。

    2、逆地址解析location参数传入的参数格式是(纬度lat,经度lng)。

    返回码状态表

    返回码定义

    0

    正常

    1

    服务器内部错误

    2

    请求参数非法

    3

    权限校验失败

    4

    配额校验失败

    5

    ak不存在或者非法

    101

    服务禁用

    102

    不通过白名单或者安全码不对

    2xx

    无权限

    3xx

    配额错误

    升级说明

    v2版本较之v1版本,功能更新详见更新日志。若需查看v1文档,请点击目录 “Geocoding APIv1.0”。

    若v1版本升级至v2版本,地理/逆地理编码的请求url,参数:新增版本号“v2”,修改“key”为“ak”。v2不兼容v1版本的key,若需升级,请重新获取密钥。

    展开全文
  • 主要是慕课网提供提供的接口(www.imooc.com/api/teacher?type=4&num=30)获取数据进行Json解析,将解析得到数据放到ListView,观察Json数据,我们主要用到是name 作为标题,description作为内容,picSmall...

    本文是学习笔记,原视频地址:异步加载。主要是从慕课网提供提供的接口(www.imooc.com/api/teacher?type=4&num=30)获取数据进行Json解析,将解析得到的数据放到ListView中,观察Json数据,我们主要用到的是name 作为标题,description作为内容,picSmall作为ImageView获取图片的网址。其中用到的网络请求,AsyncTask,Json解析,将在本文的末尾贴出详细地址(如果还没贴就是我还没更完)

    一、AsyncTask请求网络获取Jason数据解析后获取数据源,建立适配器显示在ListView中

    (注:由于返回Json数据中picSmall为图片地址,所以第一步骤,先将ImageView中的图片设置为ic_launcher,在第二步骤中将听过两种方式来处理)

    先新建布局文件item.xml作为ListView的Item

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent" android:layout_height="wrap_content"
        android:padding="4dp"
        android:orientation="horizontal">
        <ImageView
            android:id="@+id/item_pic"
            android:layout_width="64dp"
            android:layout_height="64dp"
            android:src="@mipmap/ic_launcher"/>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:paddingLeft="4dp"
            android:layout_gravity="center">
           <TextView
               android:id="@+id/item_title"
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:textSize="20sp"
               android:text="This is a Title"
               android:gravity="center"
               android:ellipsize="end"
               android:maxLines="1"/>
            <TextView
                android:id="@+id/item_content"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:maxLines="3"
                android:textSize="15sp"
                android:text="This is Content"
                />
    
        </LinearLayout>
        
    
    </LinearLayout>

    也就是左边一个显示图片的ImageView,右边有两行,放两个TextView分别显示标题和内容


    在MainActivity中:

     1.先在MainActivity的布局文件中加一个ListView,比较简单,略去不写

    2.在MainActivity中,我们需要考虑到由于是网络请求属于费时操作,此处需要使用多线程和Handelr或者使用AsyncTask来处理,此处我们使用AsyncTask来处理

    。开始之前,我们先搞清楚需要传进去的参数,以及最终向要的结果是什么?本程序中,我们传进去一个url,想最终返回的是包含图片地址的url(还要对图片地址做进一步处理才会达到最终想要的图片)、题目、内容的多个对象,所以我们需要新建一个类来封装这些属性

    2.1新建NewsBean:

    package com.example.administrator.asyncapplication;
    
    public class NewsBean {
        public  String newsPicUrl;
        public String newsTitle;
        public String newsContent;
    
    
    
    }

    2.2使用AsyncTask:

    class NewsAsyncTask extends AsyncTask<String,Void,List<NewsBean>>{
            @Override
            protected List<NewsBean> doInBackground(String... params) {
                return getJsonData (params[0]);
            }
    
            @Override
            protected void onPostExecute(List<NewsBean> newsBeans) {
                super.onPostExecute(newsBeans);
                
            }
    
        }
    此时,我们需要一个getJsonData来返回我们所需要的List<NewsBean> 对象

    2.2 获取从网络上返回的数据之后进行Json解析:

     private List<NewsBean> getJasonData(String url){
             List<NewsBean> news = new ArrayList<NewsBean>();
    
    
            try {
              String data = getDataFromInputStream(new URL(url).openStream());
               // Log.i("xyz", data);
                //Json解析
                NewsBean bean;
                JSONObject jsonObject;
                try {
                    jsonObject = new JSONObject(data);
                    JSONArray jsonArray = jsonObject.getJSONArray("data");
                    for(int i=0;i<jsonArray.length();i++){
                        jsonObject = jsonArray.getJSONObject(i);
                        bean = new NewsBean();
                        bean.newsPicUrl=jsonObject.getString("picSmall");
                        bean.newsTitle=jsonObject.getString("name");
                        bean.newsContent=jsonObject.getString("description");
                        news.add(bean);
                    }
    
    
                } catch (JSONException e) {
                    e.printStackTrace();
                }
                ;
            } catch (IOException e) {
                e.printStackTrace();
            }
            //System.out.println(news.size());
            return news;
    
        }

    2.3读取服务器返回的InputStream数据 getDataFromInputStream

        //读取输入流,返回字符
        private String getDataFromInputStream(InputStream is){
            InputStreamReader isr;
            String result = "";//获取读取每一行之后的所有数据
    
            try {
                isr = new InputStreamReader(is, "utf-8");
                BufferedReader bufferedReader = new BufferedReader(isr);
                String line = "";
                while ((line = bufferedReader.readLine()) != null) {
                    result += line;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
    
    
            return result;
        }

    以上几个步骤,我们得到数据源List<NewsBean>,之后

    3.1建立适配器NewAdapter(用BaseAdapter):

    public class NewAdapter extends BaseAdapter {
        List<NewsBean> list;
        LayoutInflater inflater;
     
        public NewAdapter(Context context,List<NewsBean> list){
            this.list=list;
            inflater = LayoutInflater.from(context);
         
        }
        @Override
        public int getCount() {
            return list.size();
        }
    
        @Override
        public Object getItem(int position) {
            return list.get(position);
        }
    
        @Override
        public long getItemId(int position) {
    
            return position;
        }
    
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder viewHolder=null;
            NewsBean bean = list.get(position);
            if(convertView==null){
                viewHolder = new ViewHolder();
                convertView=inflater.inflate(R.layout.item,null);
                viewHolder.pic = (ImageView)convertView.findViewById(R.id.item_pic);
                viewHolder.title =(TextView)convertView.findViewById(R.id.item_title);
                viewHolder.content=(TextView)convertView.findViewById(R.id.item_content);
                convertView.setTag(viewHolder);
            }
            else{
                viewHolder =(ViewHolder)convertView.getTag();
            }
            //先将ImageView的图片设为固定的,后面会更改
            viewHolder.pic.setImageResource(R.mipmap.ic_launcher);
            viewHolder.title.setText(bean.newsTitle);
            viewHolder.content.setText(bean.newsContent);
    
            return convertView;
        }
        class ViewHolder{
            public TextView title,content;
            public ImageView pic;
        }
    }

    3.2需要在MainActivity中创建异步任务的onPostExecute方法中设置适配器:

      protected void onPostExecute(List<NewsBean> newsBeans) {
                super.onPostExecute(newsBeans);
                listView.setAdapter(new NewAdapter(MainActivity.this,newsBeans));
            }

    3.3在MainActivity中的onCreate()方法中执行异步任务:

    public class MainActivity extends ActionBarActivity {
    
        ListView listView;
        private static String URL ="http://www.imooc.com/api/teacher?type=4&num=30" ;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            listView = (ListView)findViewById(R.id.lv_main);
    
            //请求网络,异步加载
            new NewsAsyncTask().execute(URL);
    
        }



    之后运行程序。

    二、将得到的图片url解析成图片并设置给ImageView,并且做规避ListView的View复用的处理以及用Lrucache对图片进行缓存

    然后,我们来处理图片,由于Jason数据中解析出来的是图片地址,所以们需要连接网络,获取所需要的图片。可以用多线程和异步加载:

    1.采用多线程的方式给ImageView设置图片:

    1.1新建类ImageLoader,之后新建两个成员变量。ImageView mImageView; String mUrl;之后:

      //从内部类中访问url需要被声明为最终类型
        public void showImageByThread(ImageView imageView,final String url){
            mUrl = url;
            mImageView = imageView;
            new Thread(){
                @Override
                public void run() {
                    super.run();
                    Bitmap bitmap = getbitMapFromUrl(url);
                    Message message = Message.obtain();
                    message.obj=bitmap;
                    //用Handler机制,将获得的图片通过消息发送出去
                    mHandler.sendMessage(message);
                }
            }.start();
        }

    1.2 getbitMapFromUrl :

    //通过一个网络url地址返回一个图片
        //得到拂去其返回的输入流
        //通过BitmapFactory的decodeStream()方法来获取图片
        public Bitmap getbitMapFromUrl(String url){
            InputStream in=null;
            Bitmap bitMap;
            URL url1 = null;
    
            try {
                url1 = new URL(url);
                HttpURLConnection connection= (HttpURLConnection) url1.openConnection();
                in = new BufferedInputStream(connection.getInputStream());//对InputStream进行封装
                bitMap = BitmapFactory.decodeStream(in);//根据InputStream得到BitMap
                connection.disconnect();
                return bitMap;
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
    
    
    
            return null;

    1.3 在Handler中进行消息处理 handleMessage
     private Handler mHandler = new Handler(){
            //收到并处理消息
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
               
                    mImageView.setImageBitmap((Bitmap) msg.obj);
                
    
            }
        };
    1.4在NewAdapter中在设置完默认图片之后,加上一行

    new ImageLoader(viewHolder.pic,uri);

    (String url = list.get(position).newsPicUrl; url即为newsBean的属性之一)

    1.5之后运行程序,可以看到现在已经完全能接收到图片了,是不是已经完美了呢?远远不是!在快速滑动的过程中,可以看到图片出现闪动的状态,原因是刷新了多次,第一次是

    ListView中的缓存,先从缓存池中拿出图片,然后再从网络上下载,等于显示了两次,有时候会造成图片错位等。如何解决,将ViewHolder.pic和url联系起来,只有是当前的url时,才设置图片。在NewAdapter中 viewHolder.pic.setTag(url);在ImageLoader中的Handler处理中加上;if(mImageView.getTag().equals(mUrl)){mImageView.setBitmap((Bitmap)mas.obj)},之后再快速滑动,可以看到不会出现刚才的情况。

    2.用AsyncTask的方式加载图片,不再详解

    2.1

    //异步任务
        class NewsAsyncTask extends AsyncTask<String,Void,Bitmap>{
            //前期在设置ImageView和后期在避免ListView的缓存机制设置Tag时,需要用到url
            private ImageView mImageView;
            private String mUrl;
            public NewsAsyncTask(ImageView imageView,String url){
                mImageView = imageView;
                mUrl = url;
            }
    
            
            @Override
            protected Bitmap doInBackground(String... params) {
               
                return  <span style="font-family: Arial, Helvetica, sans-serif;">getbitMapFromUrl(url);</span>
            }
    
            @Override
            protected void onPostExecute(Bitmap bitmap) {
                super.onPostExecute(bitmap);
                if (mImageView.getTag().equals(mUrl)) {
                    mImageView.setImageBitmap(bitmap);
                }
            }
    2.2
     //通过异步任务将图片设置给ImageView
        public void showImageByAsyncTask(ImageView imageView,String url){
           
                new NewsAsyncTask(imageView, url).execute(url);
            
    
        }
    之后再NewAdapter做相应的更改即可。现在程序上下滑动可以看到先出现默认图标,然后才显示了图片,还不够完美,因为图片没有缓存,导致每次都得重新加载下面通过AsyncTask来介绍使用LruCache缓存

    三、使用LruCache缓存

    注意lruche对象的底层是用map来是实现的,所以很多map的方法,我们在这里也可以使用,存储也是通过键值对的方式,key在此处是图像的url,value是Bitmap

    1.创建cache对象

    我们在ImageLoader的构造函数中来初始化LruCache

    这样当ImageLoader对象被创建时,也就初始化了cache

    public class ImageLoader {
         
        private LruCache<String,Bitmap> caches;
        public ImageLoader(){
            //获得最大内存,从而设置缓存的空间大小,当款村的图骗超过设置的空间大小时
            //lru最近未被使用的图片就会被抛出缓存
            int maxMermory = (int)Runtime.getRuntime().maxMemory();
            int cacheSize = maxMermory/8;
            //匿名内部类 获得cache实例
            caches = new LruCache<String,Bitmap>(cacheSize){
                @Override
                protected int sizeOf(String key, Bitmap value) {
                    return value.getByteCount();
                }
            };
    
        }
    2.两个方法,一个时从缓存中获取图片,另一个是添加图片到缓存中:

     //先看缓存中是否有图片,没有的话就加到缓存中去
        public void addBitmapToCache(String url,Bitmap bitmap){
            if(getBitmapFromCache(url)==null){
                caches.put(url,bitmap);
            }
    
        }
        //根据url(key)从缓存中取出Bitmao(value)
        public Bitmap getBitmapFromCache(String url){
            return caches.get(url);
        }
    3.之后,还需要对showImageByAsyncTask进行修改,给ImageView设置图片之前,先看缓存中是否有对应图片,没有的话,从网络上进行加载,有的话,直接设置

    ,但是,还有一点,从网络上加载完了,应该添加到缓存中,以便下次备用

     //通过异步任务将图片设置给ImageView
        public void showImageByAsyncTask(ImageView imageView,String url){
            Bitmap bitMap = getBitmapFromCache(url);
            //如果缓存中没有图片,就从网络上下载
            //如果缓存中有图片了,直接设置
            if(bitMap==null) {
                new NewsAsyncTask(imageView, url).execute(url);
            }else{
                imageView.setImageBitmap(bitMap);
            }
    
        }

     //异步任务
        class NewsAsyncTask extends AsyncTask<String,Void,Bitmap>{
            //前期在设置ImageView和后期在避免ListView的缓存机制设置Tag时,需要用到url
            private ImageView mImageView;
            private String mUrl;
            public NewsAsyncTask(ImageView imageView,String url){
                mImageView = imageView;
                mUrl = url;
            }
    
            //先从网络上下载图片,下载下来之后,不需要重复下载,需要加入缓存
            @Override
            protected Bitmap doInBackground(String... params) {
                String url = params[0];
                Bitmap bitmap = getbitMapFromUrl(url);
                if(bitmap!=null){
                    addBitmapToCache(url,bitmap);
                }
                return  bitmap;
            }
    
            @Override
            protected void onPostExecute(Bitmap bitmap) {
                super.onPostExecute(bitmap);
                if (mImageView.getTag().equals(mUrl)) {
                    mImageView.setImageBitmap(bitmap);
                }
            }
        }


    经过这几个步骤,缓存已经差不多了,为什么说差不多呢?因为我们在NewAdapter中还没有修改的,回想一下我们如何调用的

    new ImageLoader().showImageByAsyncTask(viewHolder.pic,url);
    这样,每次调用都重新生成了ImageLoader对象,哪里有缓存了?解决办法,将生成的ImageLoader对象保存起来
    在NewAdapter中
    private ImageLoader mImageLoader;
    之后再NewAdapter的构造函数中,
    mImageLoader = new ImageLoader();
    之后在getView方法中更改:
    mImageLoader.showImageByAsyncTask(viewHolder.pic,url);
    至此,缓存也已经完成,运行程序,可以看到当加载完图片之后,再往上滑动,将会使用缓存,不会重复加载,这就省了流量
    (待续。。。。)
    
    





    展开全文
  • 百度地图地址解析

    千次阅读 2017-06-08 12:56:11
    Geocoding API 是一类接口,用于提供从地址到经纬度坐标或者经纬度坐标到地址的转换服务,用户可以使用C# 、C++、Java等开发语言发送请求且接收JSON、XML返回数据。 Geocoding API 已全面支持HTTP/HTTPS两种...
  • jquerypost请求从接口json){ "m":"dh", "oper":"fdghgh", "sqlid":"2455", "params":{ "PHONE":"手机号码" } },获取到结果后,然后将结果解析并编译成表格形式.这个怎么弄,请教各位大神 我...
  • 看到一个题目: ip.taobao.com获取公网ip信息分析:1、生成公网IP地址;2、根据ip.taobao.com返回代码,用json解析 下面是淘宝的接口说明'''接口说明1. 请求接口(GET): ...
  • String appSecret,应用证书中的App Secret,前边已经设置,固定用"@{pPage:app_secret}"即可 String file,调用上传文件接口上传文件(如图片)到京东JOS平台时的文件全名(含相对路径,如:images/logo.png),...
  • Go入门学习笔记,零开始学Go,做一个Go工程师。 持续更新... 项目结构 ├─ Go │ ├─ 00-基础语法 │ ├── 01-环境安装 │ ├── 02-变量声明 │ ├── 03-数组 │ ├── 04-Slice 切片 │ ├── 05-...
  • 11.4 CIDR地址中生成IP地址的范围 456 11.5 创建基于REST风格简单接口 458 11.6 利用XML-RPC实现简单远端过程调用 463 11.7 在不同解释器间进行通信 466 11.8 实现远端过程调用 468 11.9 以简单方式验证...
  • * 解析从服务器传来的json字符传对象 * @param jsonString json字符串 */ private void parseJsonString(String jsonString){ Log.v("test","pareseJsonString"); try { JSONArray jsonArray=new ...
  • Vue axios 跨域 post参数...那么这个是什么意思呢,这个是只能请求的地址中取出参数,也就是只能 username=admin&password=admin这种字符串中解析出参数。 查看Content-Type: application/json;charse...
  • 1、本项目是作为一个服务接口,使用Python开发,对方采用JavaMySQL数据库读取批量文本信息,然后调用本接口服务,解析出相关字段信息。跨语言平台间数据交互采用HTTP方式。 服务端采用Flask框架,对方先将...
  • GitHub地址:...下面这段python首先解析港交所页面,页面获取港交所Token值,而后请求返回数据,数据格式类似于Json,但是需要稍微处理一下,就可...
  • 关于python爬虫分析

    2020-12-10 22:08:59
    #通过json库解析json,获得返回数据 DataNode = json.loads(response.text).get('returndata').get('data')[0]</code></pre> ,"SF UI Text",Arial,"PingFang SC",&#...
  • MobilePreFixProperties:配置文件读取配置国家和手机号前缀对应关系 application:增加国家和手机前缀对应关系 启动项目并验证 启动zh-boot 访问 http://127.0.0.1:8080/bad/check/mobile 和 ...
  • PDFMiner:一个用于 PDF 文档抽取信息工具。 PyPDF2:一个可以分割,合并和转换 PDF 页面库。 ReportLab:快速创建富文本 PDF 文档。 Markdown Mistune:快速并且功能齐全纯 Python 实现 Markdown...
  • Android 上百实例源码分析以及开源分析 集合打包4

    千次下载 热门讨论 2012-07-10 21:54:03
    10.设置音量键在飞行切换中的作用 本项目共25个目标文件。 13、Jchat Android jChat 是一个 Android 手机上基于位置的聊天软件,采用P2P通讯机制。 JChat 的编译: 1、 配置环境,需要的软件有Android 模拟器,...
  • 类别侧边栏的实现后,需要为每一个类别的元素都添加一个id,通过id来获取数据库中的数据,用Ajax获取数据并且刷新页面的信息。采用分页技术,防止数据过多的时候,显示在同一个页面,给用户带来不好的体验,分页支持...
  • java开源包1

    千次下载 热门讨论 2013-06-28 09:14:34
    利用JoSQL可以像操作数据库中的数据一样对任何Java对象集进行查询,排序,分组。 搜索自动提示 Autotips AutoTips是为解决应用系统对于【自动提示】的需要(如:Google搜索), 而开发的架构无关的公共控件, 以满足该类...
  • java开源包12

    热门讨论 2013-06-28 10:14:45
    利用JoSQL可以像操作数据库中的数据一样对任何Java对象集进行查询,排序,分组。 搜索自动提示 Autotips AutoTips是为解决应用系统对于【自动提示】的需要(如:Google搜索), 而开发的架构无关的公共控件, 以满足该类...
  • python cookbook(第3版)

    2016-01-06 22:24:38
    1.6 字典中的键映射多个值 1.7 字典排序 1.8 字典的运算 1.9 查找两字典的相同点 1.10 删除序列相同元素并保持顺序 1.11 命名切片 1.12 序列中出现次数最多的元素 1.13 通过某个关键字排序一个字典列表 ...
  • Java资源包01

    2016-08-31 09:16:25
    利用JoSQL可以像操作数据库中的数据一样对任何Java对象集进行查询,排序,分组。 搜索自动提示 Autotips AutoTips是为解决应用系统对于【自动提示】的需要(如:Google搜索), 而开发的架构无关的公共控件, 以满足该类...
  • java开源包101

    2016-07-13 10:11:08
    利用JoSQL可以像操作数据库中的数据一样对任何Java对象集进行查询,排序,分组。 搜索自动提示 Autotips AutoTips是为解决应用系统对于【自动提示】的需要(如:Google搜索), 而开发的架构无关的公共控件, 以满足该类...
  • java开源包11

    热门讨论 2013-06-28 10:10:38
    利用JoSQL可以像操作数据库中的数据一样对任何Java对象集进行查询,排序,分组。 搜索自动提示 Autotips AutoTips是为解决应用系统对于【自动提示】的需要(如:Google搜索), 而开发的架构无关的公共控件, 以满足该类...
  • java开源包6

    热门讨论 2013-06-28 09:48:32
    利用JoSQL可以像操作数据库中的数据一样对任何Java对象集进行查询,排序,分组。 搜索自动提示 Autotips AutoTips是为解决应用系统对于【自动提示】的需要(如:Google搜索), 而开发的架构无关的公共控件, 以满足该类...
  • java开源包10

    热门讨论 2013-06-28 10:06:40
    利用JoSQL可以像操作数据库中的数据一样对任何Java对象集进行查询,排序,分组。 搜索自动提示 Autotips AutoTips是为解决应用系统对于【自动提示】的需要(如:Google搜索), 而开发的架构无关的公共控件, 以满足该类...
  • java开源包8

    热门讨论 2013-06-28 09:55:26
    利用JoSQL可以像操作数据库中的数据一样对任何Java对象集进行查询,排序,分组。 搜索自动提示 Autotips AutoTips是为解决应用系统对于【自动提示】的需要(如:Google搜索), 而开发的架构无关的公共控件, 以满足该类...

空空如也

空空如也

1 2 3 4
收藏数 66
精华内容 26
关键字:

从接口中解析json中的地址