我的程序单独开启了个线程从网络接收数据,当服务器端大量推送数据给我的时候,就会造成我滑动ListView卡
个人推测是由于网络数据接收线程占用了CPU,导致主线程ListView滑动时卡。哪位大神有没有好的解决方法呀?先谢过了O(∩_∩)O

解决方案 »

  1.   

    是不是要用到Handler去更新界面。
      

  2.   


    楼主的处理应该是接受推送的数据时占用了主线程,所以导致ListView滑动卡Android在处理耗时操作、后台操作时,提供了异步任务机制AsyncTask,楼主查查这个的用法
    Class OverviewAsyncTask enables proper and easy use of the UI thread. This class allows to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.An asynchronous task is defined by a computation that runs on a background thread and whose result is published on the UI thread. An asynchronous task is defined by 3 generic types, called Params, Progress and Result, and 4 steps, called onPreExecute, doInBackground, onProgressUpdate and onPostExecute.Developer Guides
    For more information about using tasks and threads, read the Processes and Threads developer guide.
    UsageAsyncTask must be subclassed to be used. The subclass will override at least one method (doInBackground(Params...)), and most often will override a second one (onPostExecute(Result).)Here is an example of subclassing: private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
         protected Long doInBackground(URL... urls) {
             int count = urls.length;
             long totalSize = 0;
             for (int i = 0; i < count; i++) {
                 totalSize += Downloader.downloadFile(urls[i]);
                 publishProgress((int) ((i / (float) count) * 100));
             }
             return totalSize;
         }     protected void onProgressUpdate(Integer... progress) {
             setProgressPercent(progress[0]);
         }     protected void onPostExecute(Long result) {
             showDialog("Downloaded " + result + " bytes");
         }
     }
     
    Once created, a task is executed very simply: new DownloadFilesTask().execute(url1, url2, url3);
     
      

  3.   

    我以前也遇到过,但AsyncTask的本质也是开启一个线程异步加载,与lz的做法大致相同,可能AsyncTask内部实现要比lz的优化一些,但可能也解决不了根本问题。
    以下是我以前想的几个解决思路:
    1、图片等资源用异步加载(每一张图片用一个线程,所有线程用线程池管理,限制线程个数)
    2、数据分页(分批)加载
    3、只加载当页数据,滑动到哪加载到哪,道理同2
    4、listView滑动时暂停加载(也就是滑动时暂停所有线程,这是解决卡顿的重点之一)
      

  4.   


    我懂3楼的意思,可是我们的产品设计不允许分页加载,服务器会分包把所有的数据都推下来,然后拿到数据去更新UI?
    1.我现在觉得这个问题是不是无解啊,UI线程竞争不过网络线程会导致卡。
    2.如果我把网络线程的优先级设置低了,会导致数据收发不及时,但是产品对及时更新又有很高的要求。唉,~~~~(>_<)~~~~ 
      

  5.   

    你应该是在ListView需要承载的数据加载完以后才为listView设置数据的啊,也就是说是在数据加载完以后才会有ListView展示,有ListView展示你才有东西滑动啊……如果说是ListView滑动时候卡的话,应该是你adapter的getView方法的问题,在这里有处理诸如网络请求之类耗时比较长的操作,但是又没做异步处理。
      

  6.   

    在getView里打印下,看是不是重复执行
      

  7.   


    1.因为服务器给的数据是分包推送的,一个包处理完了让listView去更新数据,此时网络线程同时在获取下一个包进行解析等数据处理操作。
    2.getView方法已经复用View了,而且我尝试着在getView方法里只获取一个TextView,同样卡顿。所以应该是网络线程大量占用了CPU时间片。我把网络线程的优先级设置为Process.THREAD_PRIORITY_BACKGROUND UI线程就不卡顿了,但是导致网络收发包有延迟,我的程序对网络交互的实时性很强。真是顾此失彼啊
      

  8.   


    这个真没有重复执行,原因已经找到。
    网络线程大量占用了CPU时间片。我把网络线程的优先级设置为Process.THREAD_PRIORITY_BACKGROUND UI线程就不卡顿了,但是导致网络收发包有延迟,我的程序对网络交互的实时性很强。真是顾此失彼啊
      

  9.   

      美女android 工程师,求关注..
      

  10.   

    可以把每一个listview的item存起来,getview先读存的,如果不存在再获取数据
      

  11.   

        首先确定一点,客户端接收推送数据的线程是否可以暂停?良好的设计,这个线程一定能够暂停的,当用户在滑动listview时,让该线程暂停,停止滑动,再唤醒该线程,数据接收完成后,再通过回调,通知listview更新,也就是说,滑动和数据更新完全分开,滑动过程中,未加载完成的数据,可以用默认数据代替,如图片使用默认图片,文字使用“加载中……”等,这样就不会存在抢占资源的问题了,当然,为了保证listview数据不发生错乱,getview中使用view缓存时,必须对重复使用的view中的数据进行初始化。
        归根结底,还是再说滑动时保证只有主线程在活动。
        如果客户端接收推送数据的线程无法暂停……这个就真没办法处理了,呃,至少我还没想到什么好方法