《Android第一行代码》coolweather项目个人总结

问题1.点击ADM不能查看data文件夹,android device monitor不能查看/data目录。2.不要忘记china后面是有/。String address="http://guolin.tech/api/china/"+provincecode+"/"+citycode;3.ProgressDialog在24以上的
摘要由CSDN通过智能技术生成

14.4 总结

1.点击ADM不能查看data文件夹,android device monitor不能查看/data目录
2.不要忘记china后面是有/。

String address="http://guolin.tech/api/china/"+provincecode+"/"+citycode;

3.ProgressDialog在24以上的是用不了的。
4.setselection(int position)的作用就是把第position位置的数据显示在listview的最上面一项。来自ListView的setSelection用法。下文代码就是把第一项放在最上面一项。假如你设置1,就是把第二位的数据显示在listview的最上面一项,那么第一项呢,向上滑动就可以看到。

 listView.setSelection(0);

5.OkHttp 建立一个新方法,使程序可以多次调用,并带有回调参数callback,同时在client.newCall(request)没有调用excuter()方法,而是调用enqueue()方法,该方法的内部已经开好子线程了,在子线程中去执行HTTP请求,并将最终的请求结果回调OKhttp.Callback当中,在调用它的时候要重写onResponse(),得到服务器返回的具体内容,重写onFailure()方法,在这里对异常情况进行处理。不可以再这里进行UI操作。

public class HttpUtil {
   
    public static void sendOkHttpRequest(String address,okhttp3.Callback callback){
   
        OkHttpClient client=new OkHttpClient();
        Request request=new Request.Builder().url(address).build();
              client.newCall(request).enqueue(callback);
    }

那么我们在调用sendOkHttpRequest()方法的时候就可以这样写

HttpUtil。sendOkHttpRequest("http://www.baidu.com",new okhhtp3.Callback())
{
   
	@Override
	public void onResponse(Call call,Response response)throws IOException{
   
	//得到服务器返回的具体内容
	String responseData =response.body().string();
	}
	@Override
	public void onFailure(Call call,IOException e){
   
	//在这里对异常情况进行处理
	}
}

在coolweather中,重写了onFailure()方法,onResponse()方法。

  • onFailure()方法

    如果加载失败,要返回UI线程,去关闭加载框,并提示加载失败字样。

  • onResponse()方法
    首先去判断要去服务器查询什么type的数据,包含三个种类,去调用相应解析json的方法。之后数据库中已经包含数据了,所以调用对应type的读取数据库数据的方法。

  HttpUtil.sendOkHttpRequest(address, new Callback() {
   
      @Override
            public void onFailure(Call call, IOException e) {
   
                //失败了,返回UI线程处理逻辑
                getActivity().runOnUiThread(new Runnable() {
   
                    @Override
                    public void run() {
   
                        //关闭加载框
                       // closeProgressBar();
                       closeProgressDialog();
                        Toast.makeText(getContext(),"加载失败",Toast.LENGTH_SHORT).show();
                    }
                });
            }
            //得到服务器返回的具体内容
            @Override
            public void onResponse(Call call, Response response) throws IOException {
   
                String responseText=response.body().string();
                boolean result=false;
                if("province".equals(type))
                    result = Utility.handleProvinceResponse(responseText);
                else if("city".equals(type)){
   
                    result=Utility.handleCityResponse(responseText,selectedProvince.getId());
                }
                else if("county".equals(type)){
   
                    result=Utility.handleCountyResponse(responseText,selectedCity.getId());
                }
                //解析完数据牵涉到UI操作,因此必须要在主线程中调用。
                //数据库中有了,可以显示了。
                if(result){
   
                    getActivity().runOnUiThread(new Runnable() {
   
                        @Override
                        public void run() {
   
                            ///关闭进度框
                          //  closeProgressBar();
                           closeProgressDialog();
                            if("province".equals(type))
                                queryProvinces();
                            else if("city".equals(type)){
   
                               queryCities();
                            }
                            else if("county".equals(type)){
   
                               queryCounties();
                            }

                        }
                    });
                }
            }
        });
  1. 和风天气默认让你去使用sdk类型的key,所以要注意我们使用的key要是Web API类型,刚开始我注册后,一直不好使,最后才发现申请的key是sdk类型。和风天气注册地址

14.5总结

1. gson

1.1 gson基本用法

回顾gson的使用,并找一些json格式的数据进行解析。

String response="[{img=0.0,name=非会员,qualify_amount=0.0}," +
                "{img=1.0,name=一级会员,qualify_amount=100.0}," +
                "{img=2.0, name=二级会员,qualify_amount=300.0}]";

由于是数组中有多个对象,所以可以用List的方法进行解析,解析方法如下:

 Gson gson=new Gson();
        //数组的话可以这么做
     List<User>users=gson.fromJson(response,new TypeToken<List<User>>(){
   }.getType());
     for (User user:users){
   
         System.out.println(user.img+" "+user.name+" "+user.qualify_amount);
1.2 属性重命名

这里参考自Gson用法详解。当我们的接口返回的数据与我们期望的数据不同时,我们可以使用属性重命名。或者下述的json数据中有一个tz,我们怕忘记它的意思想给他改成time,就需要使用@SerializedName 来建立与java字段的联系。

 /**
     * admin_area : 北京
     * tz : +8.00
     * location : 北京
     * lon : 116.4052887
     * parent_city : 北京
     * cnty : 中国
     * lat : 39.90498734
     * cid : CN101010100
     */
    private String admin_area;
    @SerializedName("tz")
    private String time;

SerializeName远比你想象的更强大,假如,json数据如下:userName,user_name,Name,都是指向一个值,此时我们可以使用alternate属性。很奇怪的是,我翻看了我的SerializedName类发现竟然没有alternate这个方法,黑人问号脸,为什么问号它围绕着我?

{
   \"userName\":\"leavesC\",\"age\":24,\"sex\":true}
{
   \"user_name\":\"leavesC\",\"age\":24,\"sex\":true}
{
   \"Name\":\"leavesC\",\"age\":24,\"sex\":true}


@SerializedName(value = "userName", alternate = {
   "user_name", "Name"})
    private String name;
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.google.gson.annotations;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target({
   ElementType.FIELD})
public @interface SerializedName {
   
    String value();
}

1.3 JsonDeserializer

参考自Gson 解析复杂数据。首先有一个Json对象,表示一本书的基本信息。

{
   
  'title':    'Java Puzzlers: Traps, Pitfalls, and Corner Cases',
  'isbn-10':  '032133678X',
  'isbn-13':  '978-0321336781',
  'authors':  ['Joshua Bloch', 'Neal Gafter']
}

java的变量名不容许有‘-’符号的,我们可以使用@SerializedName注解来处理,不过对于一些复杂情况是难以处理的,所以我们使用JsonDeserializer。我们需要自定义一个JsonDeserializer,然后注册到GsonBuilder,GsonBuilder在解析时就会自动使用我们自定义的JsonDeserializer。
首先我们需要创建一个BookJsonDeserializer。它负责把Book对应的Json对象,解析为Java对象。

public class BookDeserializer implements JsonDeserializer<Book> {
   

      @Override
      public Book deserialize(final JsonElement jsonElement, final Type typeOfT, final JsonDeserializationContext context)
          throws JsonParseException {
   

        //todo 解析字段

        final Book book = new Book();
        book.setTitle(title);
        book.setIsbn10(isbn10);
        book.setIsbn13(isbn13);
        book.setAuthors(authors);
        return book;
      }
    }

简单介绍下JsonDeserializer,它需要有一个Type,那肯定是我们的Book。我们要重写deserialize()函数,并在其中解析json数据,最后返回一个Book对象。这里比较重要的是,Gson解析Json对象在内部表示为JsonElement,虽然element是元素的意思,但JsonElement可以表示为下列的任何一种:

1. JsonPrimitive :Java 基本类型的包装类,以及 String
2. JsonObject:类比 Js 中 Object的表示,或者 Java 中的 Map<String, JsonElement>,一个键值对结构。
3. JsonArray:JsonElement 组成的数组,注意:这里是 JsonElement,说明这个数组是混合类型的。
4. JsonNull:值为 null

完整代码如下,根据上述所讲,就可以解释,为什么要用getAsString和getAsJsonArray了。使用getAsString时是这个JsonElement表示为JsonPrimitive。使用getAsJsonArray时,虽然读取的是[‘Joshua Bloch’, ‘Neal Gafter’]这个数组,但表示为JsonElement所以,要给他转化一下。

class BookDeserializer implements JsonDeserializer<Book>{
   
    @Override
    public Book deserialize(final JsonElement jsonElement, final Type typeOfT,
                            final JsonDeserializationContext context)throws JsonParseException{
   
        final JsonObject jsonObject=jsonElement.getAsJsonObject();
        JsonElement titleElement=jsonObject.get("title");
        final  String title=titleElement.getAsString();
        JsonElement isbn10Element=jsonObject.get("isbn-10");
        final String isbn10=isbn10Element.getAsString();
        JsonElement isbn13Element=jsonObject.get("isbn-13");
        final String isbn13=isbn13Element.getAsString();
        //虽然是个数组,但Gson解析json对象并在内部表示为JsonElement,
        // 这里的其实是表示为JsonElement的JsonArray,所以要在get之后用getAsJsonArray();
        JsonArray authors=jsonObject.get("authors").getAsJsonArray();
        String[]Authors=new String[authors.size()];
        
  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值