Android中JSoup的问题

时间:2015-11-21 13:21:32

标签: android android-asynctask jsoup

我在Android应用程序上使用JSoup时遇到问题,因为我有一个NetworkOnMainThreadException。我使用AsyncTask来获取我的网站标签的信息,但我不知道我是否正确操作,所以我需要帮助才能做到这一点。这是代码:

主要活动:

  @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_index);
    tagsSP = (Spinner) findViewById(R.id.spinner);
    String myPage = "http://www.mypage.com";
    TagGetter tG = new TagGetter();
    ArrayList<Tag> a;
    tG.setPage(myPage);
    try {
        a = tG.execute(myPage).get();
        this.fillSpinner(a);
    } catch (InterruptedException e) {
        e.printStackTrace();
    } catch (ExecutionException e) {
        e.printStackTrace();
    }

}

public void fillSpinner(ArrayList<Tag> a) {

    String[] numTags = new String[a.size()];
    for(int i=0;i<a.size();i++){
        numTags[i] = a.get(i).getTitle();
    }
    arrayAdapterTags = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_dropdown_item,numTags);
    tagsSP.setAdapter(arrayAdapterTags);
}

这是AsyncTask代码:

public class TagGetter extends AsyncTask<String, Void, ArrayList<Tag>> {
Document html;
String className, page;
ArrayList<Tag> tags;

/**
 * This method is from the AsyncTask class. It will run with the method "execute"
 *
 * @param params
 * @return
 */
@Override
protected ArrayList<Tag> doInBackground(String... params) {
    this.tags = getTags();
    return this.tags;
}

/**
 * This method allows to you to set a url where you can get the tags.
 *
 * @param url
 */
public void setPage(String url) {
    this.page = url;
}

/**
 * This method gives to you an ArrayList of tags.
 *
 * @return
 */
public ArrayList<Tag> getTags() {
    ArrayList<Tag> tgs = new ArrayList<Tag>();
    try {
        html = getConnect(page);
        className = "tag_col_0";
        Elements items = html.getElementsByClass(className);
        String[] col_0 = getValuesTag(html, "tag_col_0", "b");
        String[] col_1 = getValuesTag(html, "tag_col_1", "b");
        String[] col_2 = getValuesTag(html, "tag_col_2", "b");
        String[] col_3 = getValuesTag(html, "tag_col_3", "b");
        String[] tag_names = new String[col_0.length + col_1.length + col_2.length + col_3.length];
        tag_names = appendArrayString(col_0, col_1, tag_names);
        tag_names = appendArrayString(tag_names, col_2, tag_names);
        tag_names = appendArrayString(tag_names, col_3, tag_names);

        String[] url_0 = getURL(html, "tag_col_0", "href");
        String[] url_1 = getURL(html, "tag_col_1", "href");
        String[] url_2 = getURL(html, "tag_col_2", "href");
        String[] url_3 = getURL(html, "tag_col_3", "href");
        String[] tag_links = new String[col_0.length + col_1.length + col_2.length + col_3.length];
        tag_links = appendArrayString(url_0, url_1, tag_links);
        tag_links = appendArrayString(tag_links, url_2, tag_links);
        tag_links = appendArrayString(tag_links, url_3, tag_links);

        int n = tag_names.length;

        for (int i = 0; i < n; i++) {
            tgs.add(new Tag(tag_names[i], page+"/"+ tag_links[i]));
        }

    } catch (IOException e) {
        e.printStackTrace();
    }

    return tgs;
}

/**
 * This method returns the conection to a web page.
 *
 * @param link
 * @return
 * @throws IOException
 */
public Document getConnect(String link) throws IOException {
    return Jsoup.connect(link).get();
}

/**
 * This method allows to you to append two arrays.
 *
 * @param arrayX
 * @param arrayY
 * @param build
 * @return
 */
public String[] appendArrayString(String[] arrayX, String[] arrayY, String[] build) {
    int x = arrayX.length;
    int y = arrayY.length;
    int n = 0;
    build = new String[x + y];
    for (int i = 0; i < x; i++) {
        build[i] = arrayX[i];
        n = i;
    }
    for (int i = 0; i < y; i++) {
        build[i + n] = arrayY[i];
    }
    return build;
}

/**
 * This method returns the url of a tag.
 *
 * @param item = the connection
 * @param name  = the name of the main class (or tag)
 * @param prin = the name of the attribute you're looking for
 * @return
 */
public String[] getURL(Document item, String name, String prin) {

    Elements e = item.getElementsByClass(name);
    int n = e.size();
    String[] elements = new String[n];
    if (e != null && n > 0) {
        for (int i = 0; i < n; i++) {
            Element element = (Element) e.get(i);
            elements[i] = element.getElementsByAttribute(prin).text();

        }
    }
    return elements;
}

/**
 * This method returns the name of the tag.
 *
 * @param item = the connection
 * @param name  = the name of the main class (or tag)
 * @param prin = the name of the tag you're looking for
 * @return
 */
public String[] getValuesTag(Document item, String name, String prin) {

    Elements e = item.getElementsByClass(name);
    int n = e.size();
    String[] elements = new String[n];
    if (e != null && n > 0) {
        for (int i = 0; i < n; i++) {
            Element element = (Element) e.get(i);
            elements[i] = element.getElementsByTag(prin).text();

        }
    }
    return elements;
}

Tag对象的构造函数只需要标记名称和标记url。

问题出在哪里?

PD:我在清单中有 android.permission.ACCESS_NETWORK_STATE android.permission.INTERNET

1 个答案:

答案 0 :(得分:0)

当应用程序尝试在其主线程上执行网络操作时引发的异常。

仅针对Honeycomb SDK或更高版本的应用程序进行此操作。针对早期SDK版本的应用程序可以在其主要事件循环线程上进行联网,但是非常不鼓励。

因此,尝试使用AsyncTask如下:

   public class ForgotPasswordTask extends AsyncTask<String, String, String> {
    protected void onPreExecute() {}
    @Override
    protected String doInBackground(String... urls) {

        HttpURLConnection urlConnection = null;
        StringBuilder builder = new StringBuilder();

        try {
            /* forming th java.net.URL object */
            URL url = new URL("http://www.mypage.com");
            urlConnection = (HttpURLConnection) url.openConnection();


            urlConnection.setRequestMethod("GET");

            int statusCode = urlConnection.getResponseCode();


            /* 200 represents HTTP OK */
            if (statusCode ==  200) {



                BufferedReader in = new BufferedReader(
                        new InputStreamReader(urlConnection.getInputStream()));
                String inputLine;


                while ((inputLine = in.readLine()) != null) {
                    builder.append(inputLine);
                }
                in.close();

            }

        }
        catch (Exception e) {
            e.printStackTrace();

        }
        return builder.toString();
    }
    protected void onPostExecute(String result) {

//get result/response generated from onPostExecute()

    }
}