记录Android学习过程中遇到的问题

  Android编程中经常会使用到ArrayAdapter、SimpleAdapter、BaseAdapter。其中ArrayAdapter、SimpleAdapter较为简单,定制效果少,而BaseAdapter使用的非常普遍。

 1 asyncHttpClient.get(Constants.HEALTHY_NEWS_LIST,new AsyncHttpResponseHandler() {
 2             @Override
 3             public void onSuccess(int i, Header[] headers, byte[] bytes) {
 4                 try {
 5                     String str = new String(bytes,"gb2312");
 6                     Document document = Jsoup.parse(str);
 7                     Element body = document.body();
 8                     Elements tdWidth = body.select("td[width=500]");
 9                     Elements tdHeight = tdWidth.select("td[height=40]");
10                     Elements links = tdHeight.select("a");
11                     for (Element link : links){
12                         String title = link.text();
13                         String url = link.attr("href");
14                         healthy = new Healthy();
15                         healthy.setTitle(title);
16                         healthy.setUrl(url);
17                         healthyList.add(healthy);
18                     }
19                     HealthyAdapter healthyAdapter = new HealthyAdapter(HealthyActivity.this,healthyList);
20                     pullToRefreshListView.setAdapter(healthyAdapter);
21                     pullToRefreshListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
22                         @Override
23                         public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
24                             String title = healthyList.get((int)id).getTitle();
25                             String url = healthyList.get((int)id).getUrl();
26                             Intent intent = new Intent(HealthyActivity.this,HealthyDetailActivity.class);
27                             intent.putExtra("url",url);
28                             startActivity(intent);
29                         }
30                     });
31                     Elements link_more = body.select("a[href^=http://health.enorth.com.cn/system/more/]");
32                    textView.setText(link_more.attr("href"));
33                 }catch (IOException e){
34                     Log.d("file read exception : ", e.getMessage());
35                 }
36 
37             }
38 
39             @Override
40             public void onFailure(int i, Header[] headers, byte[] bytes, Throwable throwable) {
41                 Toast.makeText(HealthyActivity.this, "请检查网络连接", Toast.LENGTH_SHORT).show();
42                 Log.d("asyncHttpClient fail : ",throwable.getMessage());
43             }
44         });

这段代码使用了AsynHttpClient的get()方法去获得一个页面的字节流。AsyncHttpClient是我之前导入其他开源项目jar包的时候无意中导入android-async-http-x.x.x.jar的,根据它的一个命名我猜想它是用来多线程发起http请求,在网上阅读了相关博客之后,其实就是HttpClient和new Runnable的一个封装,这样使得它可以直接在主线程中进行,不过与AsyncTask相比,缺点就是无法控制网络连接过程中OnPreExecute()的一个处理。对于返回字节流乱码的问题,阅读了网页源码之后发现它的编码方式为gb2312,这是一种在大陆经常使用的汉字编码,据说可以显示98%左右的汉字。设置字符的编码方式为:String str = new String(bytes,"gb2312")。网页代码为html语言(超文本标记语言),在我看来其实跟xml一样是一种标记性语言,其中java 5之后提供了一个工具类htmlParse用来解析html文本,不过之后很少进行更新而且比较复杂所以使用的就很少了。Jsoup则是网上非常流行html解析框架,在网络爬虫方面使用的非常多。大概的使用就是用各种tag去解析文本。底层应该是使用了编译原理的状态机的一些知识,编译原理我学习的不好,这里也说不出什么了。今天早上遇到了一个很大的问题就是往HealthyList中add(healthy),我使用了Log将解析出来的title和url打印出来,在加入之后也将healthy打印出来,在for循环结束之后,我手动将healthy依次Log打印出来,非常奇怪的是居然最后一次打印出来的全是相同的值,这让我迷惑了很久。后来在同学的启发之下,我发现每次循环都要new一个healthy对象既可以解决问题。之前我之所以不在循环中每次都new一个healthy对象是因为我觉得这样会节省内存,结果反而招致这样的问题,其实往深层次分析还是对JAVA中对象的值传递和引用(地址)传递不清晰所导致的。之后我阅读了这篇博客,关于这一点讲的非常详细。http://6924918.blog.51cto.com/6914918/1283761 其中可以总结为两点,基本类型作为参数传递时,是传递值的拷贝,无论你怎么改变这个拷贝,原值是不会发生变化的。Java中对象作为参数传递时,是把对象在内存中的地址拷贝了一份给参数。其中mldnjava视频是有专门对这个的讲解的,不过好像是我遗忘了。所以在我没有在for循环中new一个对象的时候,他每次都将healthy对象的地址的拷贝存放在HealthyList中,每次循环打印出来的都是正确的内容,但是当执行到最后一次循环的时候,地址中存放的对象是最后一次的内容,而这个内容的地址被拷贝了n次,并且都存放在了HealthyList中,所以最后我进行手工打印的时候出现的都是最后一次加入的内容,而且在我打印HelathyList的时候,打印出来的地址都是相同的,但是当时我居然没有想到这个问题,我当时想的居然是每次new一个新对象太占内存,看来JAVA的基础真的很重要。

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。