码迷,mamicode.com
首页 > 其他好文 > 详细

自己实现简单的天气预报应用(5)

时间:2015-03-05 09:12:36      阅读:144      评论:0      收藏:0      [点我收藏+]

标签:

5.解决延迟加载的问题

 

因为使用volley库大应该是会单开线程得服务器数据(网络处理一般也是单开线程),因此,特别是在第一次启动程序的时候由于没有配置文件也没有数据文件,因此设置ListView的Adapter的时候会由于无法直接在OnCreate中得到模型层数据而导致无法显示出结果,为此我使用的方法是在处理数据文件的时候,如果没有文件,就返回空的items的ArrayList,同时在Volley的响应位置添加更新Adapter的方法。MainActivity中的代码如下:

  1 import android.os.Bundle;
  2 import android.support.v7.app.ActionBarActivity;
  3 import android.view.Menu;
  4 import android.view.MenuItem;
  5 import android.view.View;
  6 import android.view.ViewGroup;
  7 import android.widget.BaseAdapter;
  8 import android.widget.ListView;
  9 import android.widget.TextView;
 10 import android.widget.Toast;
 11 
 12 import com.android.volley.Request;
 13 import com.android.volley.RequestQueue;
 14 import com.android.volley.Response;
 15 import com.android.volley.VolleyError;
 16 import com.android.volley.toolbox.JsonObjectRequest;
 17 import com.android.volley.toolbox.Volley;
 18 
 19 import org.json.JSONException;
 20 import org.json.JSONObject;
 21 
 22 import java.io.File;
 23 import java.io.IOException;
 24 import java.util.ArrayList;
 25 
 26 
 27 public class MainActivity extends ActionBarActivity {
 28 
 29     private static final String url="http://api.k780.com:88/?app=weather.future&weaid=101270101&appkey=137&sign=efb0ccae3443e2238e5bb2f83bba&format=json";
 30 
 31     //标记是否有最新的数据可用
 32     private static boolean hasNew;
 33     private static File configure;
 34     private ArrayList<WeatherItem> mWeatherItems=new ArrayList<>();
 35     private ItemAdapter mAdapter;
 36     private ListView listView;
 37 
 38     @Override
 39     protected void onCreate(Bundle savedInstanceState) {
 40         super.onCreate(savedInstanceState);
 41         setContentView(R.layout.activity_main);
 42 
 43         configure=new File(getApplicationContext().getFilesDir().toString()+"/"+FileTools.conf);
 44         update();//这里不同步,就是说这语句可能执行完毕但是后台进程却尚未完成
 45 
 46         listView=(ListView)findViewById(R.id.listView);
 47         listView.setAdapter(mAdapter);
 48     }
 49 
 50     @Override
 51     public boolean onCreateOptionsMenu(Menu menu) {
 52         getMenuInflater().inflate(R.menu.menu_main,menu);
 53         return true;
 54     }
 55 
 56     @Override
 57     public boolean onOptionsItemSelected(MenuItem item) {
 58         switch (item.getItemId()){
 59             case R.id.fetch:
 60                 update();
 61                 return true;
 62             default:
 63                 return super.onOptionsItemSelected(item);
 64         }
 65     }
 66 
 67     private void update(){
 68         if(mAdapter == null){
 69             try {
 70                 mAdapter = new ItemAdapter(FileTools.loadData(getApplicationContext()));
 71             }catch (IOException | JSONException e){
 72                 e.printStackTrace();
 73             }
 74         }
 75 
 76         if(!configure.exists()){    //配置文件不存在的时候需要直接加载数据,一般是第一次启动程序的时候才没有此文件
 77             Toast.makeText(getApplicationContext(),"更新ing...",Toast.LENGTH_SHORT).show();
 78             fetchData();
 79         }else {
 80             try{
 81                 hasNew = ! DateTools.getDate().equals(FileTools.loadConf(getApplicationContext()));//判断从配置文件中读取的数据是否与当前时间相同
 82             }catch (IOException e){
 83                 e.printStackTrace();
 84             }
 85             if(hasNew){
 86                 Toast.makeText(getApplicationContext(),"更新ing...",Toast.LENGTH_SHORT).show();
 87                 fetchData();
 88             }
 89         }
 90     }
 91 
 92     private void fetchData(){
 93         RequestQueue mQueue= Volley.newRequestQueue(getApplicationContext());
 94         mQueue.add(new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
 95             @Override
 96             public void onResponse(JSONObject jsonObject) {
 97                 //服务器有响应的时候才会调用此方法
 98                 try {
 99                     mWeatherItems = ParseTools.getInstance(jsonObject.toString(),ParseTools.REQUEST_RAW);
100                     //保存数据到文件
101                     FileTools.saveData(getApplicationContext(), mWeatherItems);
102                     Toast.makeText(getApplicationContext(),"更新完毕",Toast.LENGTH_SHORT).show();
103 
104                     //更新完毕之后立即链接Adapter,这是为了解决上面第一次启动程序之后Adapter为空的问题,同时也更新了ListView的Adapter
105                     mAdapter=new ItemAdapter(mWeatherItems);
106                     listView.setAdapter(mAdapter);
107                 } catch (JSONException | IOException e) {
108                     e.printStackTrace();
109                 }
110             }
111         }, new Response.ErrorListener() {
112             @Override
113             public void onErrorResponse(VolleyError volleyError) {
114                 Toast.makeText(getApplicationContext(), "获取失败", Toast.LENGTH_SHORT).show();
115             }
116         }));
117         mQueue.start();
118     }
119 
120 
121     private class ItemAdapter extends BaseAdapter{
122 
123         ArrayList<WeatherItem> mItems=new ArrayList<>();
124         private ItemAdapter(ArrayList<WeatherItem> items) {
125             mItems=items;
126         }
127 
128         @Override
129         public View getView(int position, View convertView, ViewGroup parent) {
130             ViewHolder holder;
131             if(convertView==null){
132                 convertView=getLayoutInflater().inflate(R.layout.list_item,parent,false);
133                 holder=new ViewHolder();
134                 holder.date =(TextView)convertView.findViewById(R.id.date);
135                 holder.weather=(TextView)convertView.findViewById(R.id.weather);
136                 convertView.setTag(holder);
137             }
138             WeatherItem item=getItem(position);
139             holder=(ViewHolder)convertView.getTag();
140             holder.date.setText(item.getDate());
141             holder.weather.setText(item.getWeather());
142             return convertView;
143         }
144 
145         @Override
146         public long getItemId(int position) {
147             return position;
148         }
149 
150         @Override
151         public WeatherItem getItem(int position) {
152             return mItems.get(position);
153         }
154 
155         @Override
156         public int getCount() {
157             return mItems.size();
158         }
159 
160 
161     }
162 
163     static class ViewHolder{
164         TextView date;
165         TextView weather;
166     }
167 }

(上述代码隐藏了了URL,所以还请自己申请自己的账号去获取)

 

然后再文件解析工具类中使用的是:

 1 public static ArrayList<WeatherItem> loadData(Context context) throws IOException,JSONException{
 2         ArrayList<WeatherItem> items=new ArrayList<>();
 3 
 4         BufferedReader reader=null;
 5         try{
 6             if(!(new File(context.getFilesDir()+"/"+jsonFile).exists())){
 7                 return items;
 8             }
 9             InputStream is=context.openFileInput(jsonFile);
10             reader=new BufferedReader(new InputStreamReader(is));
11             StringBuilder builder=new StringBuilder();
12             String line;
13             while((line=reader.readLine())!=null){
14                 builder.append(line);
15             }
16 
17             items = ParseTools.getInstance(builder.toString(),ParseTools.REQUEST_ITEMS);
18         }catch (IOException | JSONException e){
19             e.printStackTrace();
20         }finally {
21             if(reader!=null){
22                 reader.close();
23             }
24         }
25 
26         return items;
27     }

 

当然为了解析天气对应的Icon,这里添加了如何获取图标ID(因为要在网上找图标,怕出现版权问题,这里就不挂Icon资源了)

1 private static int tokener(String url){
2         String[] raw=url.split("/");
3         String[] code=raw[raw.length-1].split("\\.");
4         return Integer.parseInt(code[0]);
5     }

模型层更新,加入了一个int的icon成员,同时解析raw数据的时候加入了这一句:

witem.setIcon(tokener(item.getString("weather_icon")));

 

大概就是这样了,完成之后的界面是这样的:(由于是改成了自动更新,因此去掉了手动更新的菜单项)

技术分享

 

 

实际上有做个这个的想法是因为想联系Widget的配置和使用,因此,下一阶段就是建立主屏幕上的Widget小部件。

 

自己实现简单的天气预报应用(5)

标签:

原文地址:http://www.cnblogs.com/lhyz/p/4314819.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!