开发实例 PM2.5实时监测
本次开发中所需要的知识点:
1. JSON格式的数据解析。
2. 在Andorid中使用URL和AsyncTask加载网络数据。
JSON格式的数据解析:
JSON格式的数据在前文中已经有所提及,在此就不在过多的提及,JSON格式的数据的操作应该视源数据的格式而定,在此例中的JSON的操作并不涉及全部提供的数据,而仅仅是简单的对第一个数据进行操作为例:
1.数据首先存放在JSONArray的一个数组对象中。
2.然后通过创建一个JSONObject对象来调用array.getJSONObject(0);来获取第一个对象。
3.在获取第一个对象后,他的键值对是一个数组所以再创建一个JSONArray对象来获取其对应的值。
4.最后将各种数据输出。
(详情见代码)
网络数据的加载
1.本次数据的来源:http://aqicn.org/publishingdata/json这个网站可以提供实时的pm2.5实时监测数据,编码方式是utf-8,该网站由URL打开,具体代码为
newURL("http://aqicn.org/publishingdata/json").openStream(),"utf-8")
2.JAVA中URL的简介
JAVA中URL是JAVA网络编程的一部分,其位于java.net.URL。我们可以通过URL来获取资源。类 URL 代表一个统一资源定位符,它是指向互联网“资源”的指针。资源可以是简单的文件或目录,也可以是对更为复杂的对象的引用,例如对数据库或搜索引擎的查询。
简单的可以把URL理解为包含:协议、主机名、端口、路径、查询字符串和参数等对象。每一段可以独立设置。
应用程序也可以指定一个“相对 URL”,它只包含到达相对于另一个 URL 的资源的足够信息。HTML 页面中经常使用相对 URL。
相对 URL 不需要指定 URL 的所有组成部分。如果缺少协议、主机名称或端口号,这些值将从完整指定的 URL 中继承。
由于 URL 不懂 URL 转义,所以它不会识别同一URL 的对等编码和解码形式。
注意,URI 类在某些特定情况下对其组成字段执行转义。建议使用 URI 管理 URL 的编码和解码,并使用 toURI()和 URI.toURL() 实现这两个类之间的转换。
也可以使用 URLEncoder 和 URLDecoder 类,但是只适用于 HTML 形式的编码,它与RFC2396 中定义的编码机制不同。
(以上介绍来自JavaAPI doc)
3.AsyncTask的简介
由于从未接触过AsyncTask,所以只能复制粘贴一下简介,难以进行进一步讲解。AsyncTask便提到这。在本例中AsyncTask也是用于在此创建一个新的线程,在这里附上一个AsyncTask的详细讲解的网址,该段简介也是从中复制而来http://www.cnblogs.com/sjrhero/articles/2574883.html
简介
在开发Android移动客户端的时候往往要使用多线程来进行操作,我们通常会将耗时的操作放在单独的线程执行,避免其占用主线程而给用户带来不好的用户体验。但是在子线程中无法去操作主线程(UI 线程),在子线程中操作UI线程会出现错误。因此android提供了一个类Handler来在子线程中来更新UI线程,用发消息的机制更新UI界面,呈现给用户。这样就解决了子线程更新UI的问题。但是费时的任务操作总会启动一些匿名的子线程,太多的子线程给系统带来巨大的负担,随之带来一些性能问题。因此android提供了一个工具类AsyncTask,顾名思义异步执行任务。这个AsyncTask生来就是处理一些后台的比较耗时的任务,给用户带来良好用户体验的,从编程的语法上显得优雅了许多,不再需要子线程和Handler就可以完成异步操作并且刷新用户界面。
具体的源代码:
packagecom.example.loadpm25data;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
importjava.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.widget.TextView;
public class MainActivity extends Activity{
privateTextView tvPmData;
@Override
protectedvoid onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvPmData=(TextView) findViewById(R.id.pmData);
findViewById(R.id.btnReload).setOnClickListener(newView.OnClickListener() {
@Override
publicvoid onClick(View v) {
//TODO Auto-generated method stub
reloadData();
}
});
reloadData();
}
private void reloadData(){
tvPmData.setText("Loading...");
newAsyncTask(){
@Override
protectedString doInBackground(Void... params) {
try{
BufferedReaderreader=new BufferedReader(new InputStreamReader(newURL("http://aqicn.org/publishingdata/json").openStream(),"utf-8"));
Stringline=null;
StringBuffercontent=new StringBuffer();
while((line=reader.readLine())!=null ){
content.append(line);
}
reader.close();
return content.toString();
}
catch(Exception e) {
e.printStackTrace();
}
returnnull;
}
// protected void OnPostExecute(String s){
protected void onPostExecute(String s){
super.onPostExecute(s);
if(s!=null){
try{
JSONArrayarray=new JSONArray(s);
JSONObjectfirstjo=array.getJSONObject(0);
JSONArraypollutants=firstjo.getJSONArray("pollutants");
JSONObjectfipo=pollutants.getJSONObject(0);
System.out.println("city:"+firstjo.getString("cityName"));
tvPmData.setText(String.format("%s%s:%f",firstjo.get("cityName"),firstjo.getString("localName"),fipo.getDouble("value")));
}catch (JSONException e) {
e.printStackTrace();
}
}
}
}.execute();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}