Football-Is-My-Life
Football-Is-My-Life

Reputation: 1437

how to use runOnUiThread for Update Adapter

following code, I try update Adapter. Code is properly done .But Mobile to goes Hong mode.After the loop ends. Data is displayed.

(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();
                        }

                }
            });

Update :

I changed my code like the following code. Hong mode is still not resolved.How do I fix it?

(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();

                }
            });

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

Update 3 :

again : I changed my code like the following code. Hong mode is still not resolved.

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();
        }
    }
    }

This is all my code :

  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();
        }
    }
    }
}

Upvotes: 0

Views: 3690

Answers (3)

Shivam Verma
Shivam Verma

Reputation: 8023

Your app hangs because you're doing the image downloading on the UI Thread. You'll need to do the image downloading off the UI thread.

What I'd suggest is to create an AsyncTask, add all the processing inside doInBackground() method and the _adapter.notifyDataSetChanged() inside onPostExecute() since this is the only thing that you need to call on the UI Thread.

Upvotes: 1

CodeWarrior
CodeWarrior

Reputation: 5176

Your are calling notifyDataSetChanged() in your for loop which is a bad practice and that to you are calling it twice. So remove notifyDataSetChanged() from your for loop. A better approach would be to move your code to an AsyncTask inside doInBackground() and then call notifyDataSetChanged() in your onPostexecute().

Upvotes: 0

Lena Bru
Lena Bru

Reputation: 13947

change this:

(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();
                        }

                }
            });

to this:

   (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();
                    }
                });

explanation : calling notifyDataSetChanged many times in a row, is a bad idea. make your updates to the data, and then call it once!

your code was calling it twice for every news item.

Upvotes: 0

Related Questions