我最近在做外汇项目,用的是ListView视图来显示外汇数据,我的数据是从服务器中通过socket得到数据,但是我没有思路在ListView中实时更新外汇数据,服务器发送数据过来,通过过滤自己想要的货币对数据实时更新数据,有的货币对数据是不会变化的,只是哪几对有变化就更新。望大侠提出一些详细的解决思路。我下面的代码可以从服务器中得到显示出来,现在是在 ListView实时更新数据不能得到解决。
代码如下:package com.jhconn.KVB_android.main;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;import android.app.Activity;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ListView;
import android.widget.SimpleAdapter;import com.jhconn.KVB_android.util.CCDB_Helper;public class ShowCurrencyPair extends Activity {        private final static String[] currencyPair = new String[] { "USDCHF",
                        "GBPUSD", "USDJPY", "EURUSD", "USDCAD", "EURGBP", "EURJPY",
                        "GBPJPY", "GBPCHF", "NZDUSD", "NZDJPY", "NZDAUD", "AUDUSD",
                        "AUDJPY", "AUDNZD", "EURAUD", "NZDCHF", "AUDCHF", "USDCNY" };        private final String DEBUG_TAG = "showcurrencyPair";
        private String msg = null;
        private PrintWriter out = null;
        private BufferedReader br = null;
        private String[] s = new String[100];        private int[] to = null;
        private String[] from = null;        private Socket socket = null;
        private int j = 0;
        private Boolean iscurrencypair = false;
        private static final int SERVERPORT = 15000;
        private static final String SERVERIP = "192.168.9.10";
        private ListView lv = null;
        private List<HashMap<String, String>> fillMaps = null;        private Cursor cursor = null;
        private static final String TABLE_RATE = "rates";
        private DataBaseLayer dataBaseLayer;        @Override
        public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.currencypair);
                setTheme(R.style.Transparent);
                lv = (ListView) findViewById(R.id.listview);                from = new String[] { "rowid", "forex", "bid", "ask" };
                to = new int[] { R.id.item1, R.id.item2, R.id.item3, R.id.item4 };
                fillMaps = new ArrayList<HashMap<String, String>>();                Handler handler = new Handler();
                handler.post(new Runnable() {
                        @Override
                        public void run() {
                                String message = "request" + "\r\n";
                                try {
                                        // 创建Socket
                                        socket = new Socket(SERVERIP, SERVERPORT);
                                        // 向服务器发送消息
                                        out = new PrintWriter(new BufferedWriter(
                                                        new OutputStreamWriter(socket.getOutputStream())),
                                                        true);
                                        out.println(message);
                                        out.println(message);                                        // 接收来自服务器的消息
                                        br = new BufferedReader(new InputStreamReader(socket
                                                        .getInputStream()));
                                        msg = br.readLine();
                                        while ((msg = br.readLine()) != null) {
                                                HashMap<String, String> map = new HashMap<String, String>();
                                                s = msg.split(" ");
                                                if (isCurrencyPair(s[0])) {
                                                        map.put("forex", s[0]);
                                                        map.put("bid", s[1]);
                                                        map.put("ask", s[2]);
                                                        fillMaps.add(map);
                                                        iscurrencypair = false;
                                                }
                                        }
                                        // // 关闭流
                                        // out.close();
                                        // br.close();
                                        // // 关闭Socket
                                        // socket.close();
                                } catch (Exception e) {
                                        Log.e(DEBUG_TAG, e.toString());
                                }
                        }
                });                SimpleAdapter adapter = new SimpleAdapter(this, fillMaps,
                                R.layout.listview_chart, from, to);
                lv.setAdapter(adapter);
                lv.setOnItemSelectedListener(l);
                lv.setOnItemClickListener(new OnItemClickListener() {
                        public void onItemClick(AdapterView<?> parent, View view,
                                        int position, long id) {
                        }
                });
                lv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
                        public boolean onItemLongClick(AdapterView<?> parent, View view,
                                        int position, long id) {
                                return false;
                        }
                });                lv.setScrollContainer(true);
        }        OnItemSelectedListener l = new OnItemSelectedListener() {
                public void onItemSelected(AdapterView<?> parent, View view,
                                int position, long id) {
                }                public void onNothingSelected(AdapterView<?> parent) {
                }
        };        @Override
        public boolean dispatchKeyEvent(KeyEvent event) {
                return super.dispatchKeyEvent(event);
        }        public Boolean isCurrencyPair(String msg) {
                for (int i = 0; i < currencyPair.length; i++) {
                        if (currencyPair[i].equals(msg)) {
                                iscurrencypair = true;
                                break;
                        }
                }
                return iscurrencypair;
        }        // {zhangzhiyuan
        // 将数据库中数据全部取出并放到记录集合中
        public Cursor getAllDate() {
                CCDB_Helper dbHelper = new CCDB_Helper(null, dataBaseLayer, "rates_db");
                SQLiteDatabase db = dbHelper.getReadableDatabase();
                String str_sql = "SELECT * FROM " + TABLE_RATE;
                cursor = db.rawQuery(str_sql, null);
                return cursor;
        }
        // }
}

解决方案 »

  1.   

    数据变了就调用一下adapter的notifyDataChange()呗.  你是怕性能有问题么? 可LIstView维护的只是屏幕显示的那10多条记录吧. ? 
      

  2.   

    我调用adapter的notifyDataChange()不管用,因为我的服务器是不停地发有变化的货币对数据,而android客户端就必须实时接收更新数据,而上面的代码我是不断做循环判断将所有的数据最后一次性显示在ListView视图中,这样首先在启动应用程序运行到这个显示的时候,要等待很长时间才从服务器中得到数据显示出来,服务器端是没有问题的,它是不断地发变化的货币对数据。这样给用户很不爽的感觉,现在我的想法是首先在运行程序时,从数据库中得到数据,这样显示快,然后从服务器中得到更新的货币对数据,ListView视图中的数据跟服务器中的数据做比较,哪条或多条数据有变化,就即时更新ListView数据,即这种显示是动态数据显示。但是我现在遇到的问题是不知道怎么实时更新ListView哪条或多条数据有变化的每一行。就是跟火车站那样显示火车票信息一样的效果。望各位集思广益,给一些意见,谢谢大家!
      

  3.   

    非常烂的写法.不是我说你,Handler.post不是新建一个线程.
    所以你取数据和其它是在一个UI线程里, 不卡才怪.
    New thread().start()用来取Socket数据,取完后得到一个List或者其它的形式,然后再组装成Adapter里需要的数据,比如你这里是List<map>,然后才Handler.post(new Runnable(){NotifyXX})可以用后台服务,也可以设置定时器处理Socket数据的.最好是将它放在后台,运行.Android.Process
    有一个设置线程为Background,具体我忘了.
      

  4.   

    嗯刷新的话,要添加新的线程,定时使用handle传送数据。大体思路就这样,
      

  5.   

    谢谢您的很重要回复,嗯,你的方法不错,我现在用你的方法改进一下,有什么问题互相讨论一下,很高兴能认识大家。有android问题可以加QQ:395738072,互相学习讨论,感谢大家的支持!
      

  6.   

    ListView怎么可以向上述所说的那样,可以更新一条或多条实时数据,不是更新全部,而是有变化的数据就更新,谢谢大家提意见!
      

  7.   

    只能全部刷新,不过Android只会刷新屏幕可见的部分,
    当滚动到下面时才调用 Getview,
      

  8.   

    不了解android机制导致的,实质上oncreate执行一次就不执行了
    那么你要开辟新的线程来监视你的数据是否更新了,如果数据更新了,但是画面没有更新

    从new Thread(){   public void run(){
           try{
             你自己的监听代码,通过white(true){  Thread.sleep(time...)}
             Message msg =new Message();
             msg.obj = 你的数据; //注意obj是  Object类型了
              msg.what = 1 ; 
             mHandler.sendMessage()
            }catch(Exception e){
            
            }
      }
    }Handler mHandler = new Handler(){
       handleMessage(msg){
          switch(msg.what){
             case 1:
                   int/String/...  data = (强制转换)msg.obj;
                   然后你拿到你的新数据了再放到新的Adapter
                   再listview.setAdapter(mAdapter);
                   break;
             default : break
          }
       }
    }主要是他的机制,你必须通过Thread 非UI线程发送一个Handler消息去刺激  主UI线程该刷新页面了
    否则Thread里是不能直接对界面操作的!必须在Handle里或者系统的callback方法,即onCreate,onstart
    ,onresume再不行你再告诉我吧
      

  9.   

    你好:Arashmen,谢谢你的回复,期待与你共同探讨android开发问题,我会尝试你上述提出的解决方案,我的QQ:395738072,望加我,这样更加方便交流。谢谢!呵呵