Как правильно вынести блок кода в поток

255
06 мая 2018, 21:33

В моей программе есть блок кода, отвечающий за открытие новостной статьи и извлечение из неё адреса картинки. Этот блок кода находится в потоке, отвечающем за работу с сетью и получение списка новостей. Когда они работают вместе, та программа сперва загружает всё, и отображает содержимое лишь секунд через 30.

Как правильно реализовать функцию получения адреса картинки используя многопоточность?

Код MainActivity прикреплён ниже:

    public class MainActivity extends AppCompatActivity implements MyRecyclerViewAdapter.ItemClickListener {
    MyRecyclerViewAdapter adapter;
    public Elements content;
    public ArrayList<NewsElement> newsList = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        new NewThread().execute();
        RecyclerView recyclerView = findViewById(R.id.rv_list);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(linearLayoutManager);
        adapter = new MyRecyclerViewAdapter(this, newsList);
        adapter.setClickListener(this);
        recyclerView.setAdapter(adapter);
    }
    @Override
    public void onItemClick(View view, int position) {
        Toast.makeText(this, "You clicked " + adapter.getItem(position) + " on row number " + position, Toast.LENGTH_SHORT).show();
    }
    public class NewThread extends AsyncTask<String, Void, String> {
        String cleaner(String a){
            String source = a;
            String result = "";
            ArrayList<String> arr = new ArrayList<>();
            arr.add(source);
            for(String retrival: source.split(" ")){
                arr.add(retrival);
            }
            arr.remove(0);
            Iterator<String> iterator = arr.iterator();
            while (iterator.hasNext()) {
                String string = iterator.next();
                if (string.equals("Россия") || string.equals("Екатеринбург")) {
                    iterator.remove();
                }else{
                    result += string+" ";
                }
            }
            return result;
        }
        String url_interpretator(String src){
            String result="";
            String interval = "";
            char[] morph = src.toCharArray();
            morph[0]=' ';
            morph[1]=' ';
            for (char a : morph){
                if(a==' '){
                    continue;
                }else{
                    interval=interval+a;
                }
            }
            result="https://"+interval;
            return result;
        }
        @Override
        protected  String doInBackground(String... arg) {
            Document doc;
            String  newsText,  newsDate,  newsTime,  newsPicURL,  newsLink;
            try{
                doc= Jsoup.connect("https://www.znak.com/?&%D0%B5%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B1%D1%83%D1%80%D0%B3%20%D0%BC%D1%83%D0%B7%D0%B5").get();
                content = doc.select(".pub");
                int link_counter = 0;
                newsList.clear();
                for(Element contents: content){



                    String linkID = doc.getElementsByClass("pub").get(link_counter).attr("href");
                      String region = doc.getElementsByClass("region").get(link_counter).text();
                     String time = doc.getElementsByTag("time").get(link_counter).attr("datetime");


//                   Document doc2 = Jsoup.connect("https://www.znak.com"+href).get();
//                   String pic_url=url_interpretator(doc2.getElementsByTag("img").get(1).attr("src"));
                    DateAndTime dat = new DateAndTime(time);
                    newsText=" "+cleaner(contents.text());
                    newsDate=" "+dat.getYear()+" ";
                    newsTime=dat.getTime();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
                    Document doc2 = null;                                                                   //вынести в поток
                    try {
                        doc2 = Jsoup.connect("https://www.znak.com" + linkID).get();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    String pic_url = url_interpretator(doc2.getElementsByTag("img").get(1).attr("src"));
                    String readyURL = pic_url;
                    Log.d("picture", contents.text() + " " + pic_url);
                    newsPicURL=readyURL;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
                    newsLink="https://znak.com"+linkID;
                    NewsElement newsElement = new NewsElement( newsText,  newsDate,  newsTime,  newsPicURL,  newsLink);
                    newsList.add(newsElement);

                    link_counter++;
                }
            }catch (IOException e){
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(String result) {
            adapter.notifyDataSetChanged();
        }
    }
    private class DateAndTime{

        private String date;
        private String year;
        private String time="";
        private char[] timeArr;
        DateAndTime(String date){
            this.date=date;
        }
        String getYear(){

            String[] dateAndTime = date.split("T");
            String[] dateArr = dateAndTime[0].split("-");
            timeArr = dateAndTime[1].toCharArray();
            year = dateArr[2]+"."+dateArr[1]+"."+dateArr[0];
            return year;
        }

        String getTime(){
            for(int i = 0; i<timeArr.length-4; i++){
                time=time+timeArr[i];
            }
            String intTime = String.valueOf(timeArr[0])+String.valueOf(timeArr[1]);
            int timeValue = Integer.valueOf(intTime)+5;
            if(timeValue>23){
                timeValue=timeValue-24;
                String time = "0"+String.valueOf(timeValue)+timeArr[2]+timeArr[3]+timeArr[4];
                return time;
            }else{
                String time = String.valueOf(timeValue)+timeArr[2]+timeArr[3]+timeArr[4];
                return time;
            }
        }
    }
}
Answer 1

Попробуйте уведомлять адаптер не по окончании разбора всех новостей, а после добавления в список каждой:

public class NewThread extends AsyncTask<String, Void, String> {
    // ---------------------
    protected  String doInBackground(String... arg) {
        // ----------------------
        for(Element contents: content){
            // ----------------------
            newsList.add(newsElement);
            publishProgress();
        // ---------------------
    }
    @Override
    protected void onProgressUpdate(Void... values) {
        adapter.notifyDataSetChanged();
    }
READ ALSO
Долгая попытка сделать запрос по сети, без интернета

Долгая попытка сделать запрос по сети, без интернета

Делаю запрос в сетьЗапускаю AsyncTask

249
Где можно использовать методы Predicate?

Где можно использовать методы Predicate?

Интересуют случаи где можно применить negate, and и orНу и к тому же не пойму в общем как они работают

212
Обработка нажатий на Actor в libgdx

Обработка нажатий на Actor в libgdx

Как лучше узнать, было ли нажатие на какого-то актёра в libgdx

242
Исключение InetAdress.getLocalHost() - UnknownHost

Исключение InetAdress.getLocalHost() - UnknownHost

Мне нужно получить адрес устройства, но этот метод отказывается работать, кидая исключенияВсе, что я смог нагуглить, это надо что-то записать...

239