-1

Please bear with me, I'm a beginner to Android development. I'm trying to put URLs in an ArrayList and return the ArrayList to MainActivity.

I can update it in the Connection class but when I try to check if it's working in the getValidURL() method, it doesn't display anything.

In MainActivity, I also use Log.d to log whether the ArrayList returned is empty or not, and it is.

What am I doing wrong? I feel like I'm making a very silly mistake and I have no idea what it is.

MainActivity.urlEnteredButton():

public void urlEnteredButton(View view) throws IOException {

    Button ok = (Button) findViewById(R.id.urlButtonOK);

    Intent displayArticleScreen = new Intent(this, SecondActivity.class);

    GetURLS work = new GetURLS();

    ArrayList<String> URLS = work.getValidURL();

    if(URLS.isEmpty()){
        Log.d("URL IN MAIN IS: " , "EMPTY!!!!!");
    }
        for(String s : URLS){
            Log.d("URL Main: " , s);
        }

    if(!URLS.isEmpty()) {
        String[] workingURLS = URLS.toArray(new String[URLS.size()]);
        final int result = 1;

        displayArticleScreen.putExtra("url", workingURLS);

        startActivity(displayArticleScreen);
    }
}

GetURLS.java

import android.os.AsyncTask;
import android.util.Log;
import android.widget.TextView;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.IOException;
import java.util.ArrayList;

public class GetURLS {

    ArrayList<String> workingURLS = new ArrayList<String>();
    Connection myConnection = new Connection();

    public GetURLS() throws IOException {

        myConnection.execute();

    }

    public void update(ArrayList<String> temp){

        for(String s : temp){
            workingURLS.add(s);
        }

        for(String s : workingURLS){
            Log.d("URL in workingURLS", s);
        }

    }

    public ArrayList<String> getValidURL(){
        for(String s : workingURLS){
            Log.d("URL in getValidURL()", s);
        }
        return workingURLS;

    }

    private boolean isValidURL(String temp){
        if(temp.contains("thestar.com") && temp.length() > 75 && (temp.contains("/news/") || temp.contains("/business/") || temp.contains("/sports/") || temp.contains("/entertainment/") || temp.contains("/life/"))){
            return true;
        }
        return false;
    }

    private class Connection extends AsyncTask<Void , Void, ArrayList<String>> {

        ArrayList<String> tempAL = new ArrayList<String>();

        @Override
        protected ArrayList<String> doInBackground(Void... params){
            Document doc = null;
            Elements links = null;


            try {
                doc = Jsoup.connect("http://www.thestar.com/").get();
                links = doc.select("a");
            } catch (IOException e) {
                e.printStackTrace();
            }

            if (links != null) {
                for(Element link : links){
                    String temp = link.attr("href");
                    if(isValidURL(temp)){
                        tempAL.add(temp);
                    }
                }
            }

            return tempAL;

        }

        @Override
        protected void onPostExecute(ArrayList<String> tempAL){

            update(tempAL);

        }

    }

}

In logcat, I get the following messages:

07-10 16:41:58.824  21413-21413/com.bloopbloop.ishyfishyy.thestargrabber D/URL IN MAIN IS:﹕ EMPTY!!!!!

07-10 16:41:59.894  21413-21413/com.bloopbloop.ishyfishyy.thestargrabber D/URL in workingURLS﹕ http://www.thestar.com/news/crime/2015/07/10/lecent-rosss-mother-too-grief-stricken-to-speak.html
//followed by all the other URLS I requested
  • In MainActivity, why is if(URLS.isEmpty()) executed BEFORE ArrayList<String> URLS = work.getValidURL(); according to the timestamp?

  • Why won't the ArrayList in the GetURLS class get updated?

Thanks in advance

Ishaan
  • 707
  • 1
  • 7
  • 16

1 Answers1

0

Since myConnectiont.execute() is starting an AsyncTask, it's happening concurrently in the background. So execution continues past that in the MainActivity even though all you're networking calls haven't completed. That's why your logs are showing your ArrayList as empty: at the time the execution gets to it, it is empty. It's only after that the thread with the networking completes that they are populated, and your update() method gets called.

ozymandias
  • 59
  • 2
  • 5
  • Would I have to make the main thread in app pause after starting Asynctask and let that finish, and THEN move on? – Ishaan Jul 10 '15 at 21:36
  • You could, though you run the risk of ANR if the networking call fails and frustrating users when the app doesn't do anything. Ideally you would set up some kind of progress indicator to the user (even if its just a spinner Dialog). You may want to consider implementing a callback system between the MainActivity and the AsyncTask so that MainActivity is aware of the completion. You can see that [here](http://stackoverflow.com/questions/9963691/android-asynctask-sending-callbacks-to-ui) – ozymandias Jul 10 '15 at 21:51