如何使用runOnUiThread更新适配器

时间:2014-06-22 07:02:33

标签: android

以下代码,我尝试更新适配器。代码正确完成。但是移动到Hong模式。循环结束后。显示数据。

(MainActivity.this).runOnUiThread(new Runnable() {

                @Override
                public void run() {
                     for(News news : SharedVar.getCurrentNews()){
                            _adapter.notifyDataSetChanged();
                            int currentIndex=news.getIndex();
                            Log.d("SRC_IMAGE_ADDRESS", news.getImageNewsAddress());
                            News replaceNews=new News();
                            News oldNews =_adapter.getItem(currentIndex);
                            replaceNews.setTitle(oldNews.getTitle()+" ( "+String.valueOf(currentIndex)+" )");
                            replaceNews.setImageNews(Helpers.GetImageFromUrl(news.getImageNewsAddress()));
                            SharedVar.getCurrentNews().set(currentIndex, replaceNews);
                            _adapter.notifyDataSetChanged();
                        }

                }
            });

更新:

我改变了我的代码,如下面的代码。 Hong模式仍未解决。我该如何解决?

(MainActivity.this).runOnUiThread(new Runnable() {

                @Override
                public void run() {
                     for(News news : SharedVar.getCurrentNews()){

                            int currentIndex=news.getIndex();
                            Log.d("SRC_IMAGE_ADDRESS", news.getImageNewsAddress());
                            News replaceNews=new News();
                            News oldNews =_adapter.getItem(currentIndex);
                            replaceNews.setTitle(oldNews.getTitle()+" ( "+String.valueOf(currentIndex)+" )");
                            replaceNews.setImageNews(Helpers.GetImageFromUrl(news.getImageNewsAddress()));
                            SharedVar.getCurrentNews().set(currentIndex, replaceNews);

                        }
                            _adapter.notifyDataSetChanged();

                }
            });

更新2:

public static Bitmap GetImageFromUrl(String url) {
    URL urlForImage;
    Bitmap imageNews=null;
    try {
        urlForImage = new URL(url);
        URLConnection conn = urlForImage.openConnection();
        imageNews= BitmapFactory.decodeStream(conn.getInputStream());

    } catch (MalformedURLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return imageNews;
}

更新3:

再次:我改变了我的代码,如下面的代码。洪模式仍未解决。

public class AsyncTaskReadImageNews extends AsyncTask<Void, Void, Void>{
        @Override
        protected Void doInBackground(Void... arg0) {
            (MainActivity.this).runOnUiThread(new Runnable() {
                @Override
                public void run() {
                       for(News news : SharedVar.getCurrentNews()){
                            int currentIndex=news.getIndex();
                            Log.d("INDEX_ITEM", String.valueOf(currentIndex));
                            News replaceNews=new News();
                            News oldNews =_adapter.getItem(currentIndex);
                            replaceNews.setTitle(oldNews.getTitle()+" ( "+String.valueOf(currentIndex)+"  )");
                            replaceNews.setImageNews(Helpers.GetImageFromUrl(news.getImageNewsAddress()));
                            SharedVar.getCurrentNews().set(currentIndex, replaceNews);
                        }
                }
            });
            return null;
        }
        @Override
        protected void onPostExecute(Void result) {
            _adapter.notifyDataSetChanged();
        }
    }
    }

这是我的全部代码:

  public class MainActivity extends Activity  {
    NewsAdapter _adapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
        StrictMode.setThreadPolicy(policy);
    }

    @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;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        boolean result=true;
        int id = item.getItemId();
        switch (id) {
        case R.id.action_transfer_news:
            SharedVar.setCurrentTask(Taskes.GET_TRANSFER_NEWS);
        new JsoupCommands().ConnectToWebsite(MainActivity.this);
            break;
        case R.id.action_settings:

            break;
        default:
            result=super.onOptionsItemSelected(item);
            break;
        }
        return result;
    }

    public class JsoupCommands {
        private  Dialog _dialog;
        private RatingBar _loadingStar;
        public void ConnectToWebsite(Context context) {
            _dialog = new Dialog(context);
            _dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
            _dialog.setContentView(R.layout.loading_layout);
            _loadingStar=(RatingBar) _dialog.findViewById(R.id.loading_RatingBar);
            Helpers.ConfigRatingLoader(_loadingStar);
            new AsyncTaskJsoup().execute();
        }

    public class AsyncTaskJsoup extends AsyncTask<Void, Void, String>{
            boolean _startThread;
            Element _NewsRegion;
            Elements _links;
            List<News> _LisOfNews;
            int _step=0;
            @Override
            protected String doInBackground(Void... listviews) {
                String result=null;
                Document doc;
                    try {
                        threadLoading.start();
                        SharedVar.clearNews();
                        doc = Jsoup.connect(Helpers.getCurrentTaskLink()).get();
                        _NewsRegion = doc.getElementById("content-post");
                        _links = _NewsRegion.select("article div[class=arch_body]");
                        _LisOfNews = new ArrayList<News>();
                        for (Element element : _links) {
                            Element textNewsElement = element.select("div[class=arch_content] a").first();
                            Element imageNewsElement = element.select("div[class=arch_img] a img").first();
                            String imageSrcNews = imageNewsElement.attr("src").trim().replace("../../../..", Helpers.GetCurrentSite());
                            String titleNews = textNewsElement.text().trim();
                            String linkNews = textNewsElement.attr("href").trim().replace("../../..", Helpers.GetCurrentSite()+"/persian");
                            String dateNews=textNewsElement.nextSibling().toString().trim();
                            News news = new News();
                            news.setIndex(_LisOfNews.size());
                            news.setTitle(titleNews);
                            news.setLink(linkNews);
                            news.setDate(dateNews);
                            news.setImageNewsAddress(imageSrcNews);
                            _LisOfNews.add(news);
                        }
                        SharedVar.setCurrentNews(_LisOfNews);
                        result="Success";
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                return result;
            }
            Thread threadLoading = new Thread()
            {
                @Override
                public void run() {
                    try {
                        while(_startThread) {

                            Helpers.SetRatingLoad(_loadingStar, _step);
                            if(_step++==3){
                                _step=0;
                            }
                            Log.d("DELAY", String.valueOf(_step));
                            sleep(200);
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            };

            @Override
            protected void onPostExecute(String result) {
                _startThread=false;
                _dialog.dismiss();
                FillNewsinListView();
                new AsyncTaskReadImageNews().execute(); 
            }
            private void FillNewsinListView() {
                List<News> news=SharedVar.getCurrentNews();
                if(news!=null&&news.size()>0){
                    Log.d("FILL_NEWS", "YES");
                    _adapter = new NewsAdapter(MainActivity.this, R.layout.rows_news, SharedVar.getCurrentNews());
                    ((ListView)findViewById(R.id.news_listView)).setAdapter(_adapter);
                }else{
                    Log.d("FILL_NEWS", "NO");
                }
            }
            @Override
            protected void onPreExecute() {
                _startThread=true;
                _dialog.show();
            }
        }

    public class AsyncTaskReadImageNews extends AsyncTask<Void, Void, Void>{
        @Override
        protected Void doInBackground(Void... arg0) {
            (MainActivity.this).runOnUiThread(new Runnable() {
                @Override
                public void run() {
                       for(News news : SharedVar.getCurrentNews()){
                            int currentIndex=news.getIndex();
                            Log.d("INDEX_ITEM", String.valueOf(currentIndex));
                            News replaceNews=new News();
                            News oldNews =_adapter.getItem(currentIndex);
                            replaceNews.setTitle(oldNews.getTitle()+" ( "+String.valueOf(currentIndex)+" )");
                            replaceNews.setImageNews(Helpers.GetImageFromUrl(news.getImageNewsAddress()));
                            SharedVar.getCurrentNews().set(currentIndex, replaceNews);
                        }
                }
            });
            return null;
        }
        @Override
        protected void onPostExecute(Void result) {
            _adapter.notifyDataSetChanged();
        }
    }
    }
}

3 个答案:

答案 0 :(得分:1)

您的应用程序挂起,因为您正在UI线程上进行图像下载。您需要从UI线程下载图像。

我建议创建一个AsyncTask,添加doInBackground()方法内的所有处理和_adapter.notifyDataSetChanged()内的onPostExecute(),因为这是你唯一的事情。需要调用UI线程。

答案 1 :(得分:0)

改变这个:

(MainActivity.this).runOnUiThread(new Runnable() {

                @Override
                public void run() {
                     for(News news : SharedVar.getCurrentNews()){
                            _adapter.notifyDataSetChanged();
                            int currentIndex=news.getIndex();
                            Log.d("SRC_IMAGE_ADDRESS", news.getImageNewsAddress());
                            News replaceNews=new News();
                            News oldNews =_adapter.getItem(currentIndex);
                            replaceNews.setTitle(oldNews.getTitle()+" ( "+String.valueOf(currentIndex)+" )");
                            replaceNews.setImageNews(Helpers.GetImageFromUrl(news.getImageNewsAddress()));
                            SharedVar.getCurrentNews().set(currentIndex, replaceNews);
                            _adapter.notifyDataSetChanged();
                        }

                }
            });

到此:

   (MainActivity.this).runOnUiThread(new Runnable() {

                    @Override
                    public void run() {
                         for(News news : SharedVar.getCurrentNews()){
                                int currentIndex=news.getIndex();
                                Log.d("SRC_IMAGE_ADDRESS", news.getImageNewsAddress());
                                News replaceNews=new News();
                                News oldNews =_adapter.getItem(currentIndex);
                                replaceNews.setTitle(oldNews.getTitle()+" ( "+String.valueOf(currentIndex)+" )");
                                replaceNews.setImageNews(Helpers.GetImageFromUrl(news.getImageNewsAddress()));
                                SharedVar.getCurrentNews().set(currentIndex, replaceNews);

                            }
     _adapter.notifyDataSetChanged();
                    }
                });

解释:连续多次调用notifyDataSetChanged,是个坏主意。 对数据进行更新,然后调用一次!

你的代码为每个新闻项目调用了两次。

答案 2 :(得分:0)

您在notifyDataSetChanged()循环中呼叫for这是一种不好的做法,而且您正在调用它两次。因此,请从notifyDataSetChanged()循环中删除for。更好的方法是将代码移至AsyncTask内的doInBackground(),然后在notifyDataSetChanged()中调用onPostexecute()