Как использовать AsyncTask для Jsoup Parser? - PullRequest
0 голосов
/ 16 августа 2011

Я пытаюсь использовать AsyncTask, потому что сила активации закрывается, потому что это занимает много времени в главном потоке.

Вот что я хочу использовать в DoInBackGround ..

}
class fetcher extends AsyncTask<Void,Void, Void>{

    @Override
    protected Void doInBackground(Void... arg0) { 
        Document doc = null;
        try {
            doc = Jsoup.connect(url).get();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        TextView article = (TextView)findViewById(R.id.releaseInfo);
        final TextView featuresText = (TextView)findViewById(R.id.features);

        // Get the overview div
        Element overview = doc.select("div#object-overview").last();
        Element featureList = doc.select("div.callout-box").last();

        Elements features = featureList.select("li");
        ListIterator<Element> featList = features.listIterator();
        while (featList.hasNext()) {
            featuresText.setText("Features: " + featList.next().text() + "\n");

        }


        // Get the paragraph element
        Element paragraph = overview.select("p").last();
        System.out.println(paragraph.text());

        article.setText(paragraph.text());


        return null;
    }

}

}

это всегда принудительно закрывает, я не знаю почему?

РЕДАКТИРОВАТЬ: Это ошибка отладки я получаю

08-16 18:52:59.547: WARN/System.err(27209): java.net.SocketTimeoutException
08-16 18:52:59.547: WARN/System.err(27209):     at org.apache.harmony.luni.net.PlainSocketImpl.read(PlainSocketImpl.java:564)
08-16 18:52:59.547: WARN/System.err(27209):     at org.apache.harmony.luni.net.SocketInputStream.read(SocketInputStream.java:61)
08-16 18:52:59.547: WARN/System.err(27209):     at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.readln(HttpURLConnectionImpl.java:1279)
08-16 18:52:59.547: WARN/System.err(27209):     at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.readServerResponse(HttpURLConnectionImpl.java:1351)
08-16 18:52:59.547: WARN/System.err(27209):     at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.sendRequest(HttpURLConnectionImpl.java:1339)
08-16 18:52:59.547: WARN/System.err(27209):     at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.doRequestInternal(HttpURLConnectionImpl.java:1656)
08-16 18:52:59.547: WARN/System.err(27209):     at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.doRequest(HttpURLConnectionImpl.java:1649)
08-16 18:52:59.557: WARN/System.err(27209):     at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:1374)

Подробнее ...

08-16 18:52:59.577: ERROR/AndroidRuntime(27209): FATAL EXCEPTION: AsyncTask #2
 08-16 18:52:59.577: ERROR/AndroidRuntime(27209): java.lang.RuntimeException: An error occured while executing doInBackground()
08-16 18:52:59.577: ERROR/AndroidRuntime(27209):     at android.os.AsyncTask$3.done(AsyncTask.java:200)
08-16 18:52:59.577: ERROR/AndroidRuntime(27209):     at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
08-16 18:52:59.577: ERROR/AndroidRuntime(27209):     at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
08-16 18:52:59.577: ERROR/AndroidRuntime(27209):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
08-16 18:52:59.577: ERROR/AndroidRuntime(27209):     at java.util.concurrent.FutureTask.run(FutureTask.java:137)
08-16 18:52:59.577: ERROR/AndroidRuntime(27209):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
08-16 18:52:59.577: ERROR/AndroidRuntime(27209):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
08-16 18:52:59.577: ERROR/AndroidRuntime(27209):     at java.lang.Thread.run(Thread.java:1096)
08-16 18:52:59.577: ERROR/AndroidRuntime(27209): Caused by: java.lang.NullPointerException
08-16 18:52:59.577: ERROR/AndroidRuntime(27209):     at com.fttech.htmlParser.HtmlparserExampleActivity$getGames.doInBackground(HtmlparserExampleActivity.java:156)
08-16 18:52:59.577: ERROR/AndroidRuntime(27209):     at com.fttech.htmlParser.HtmlparserExampleActivity$getGames.doInBackground(HtmlparserExampleActivity.java:1)

NullPointerException указывает на этот метод в doInBackground ()

                Elements games = doc.select("tr>  td.indexList1, tr > td.indexList2");

РЕДАКТИРОВАТЬ: я получаю эту ошибку при запуске его на Android Honeycomb

08-16 19:04:01.600: ERROR/AndroidRuntime(7302): Caused by: android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

Ответы [ 2 ]

3 голосов
/ 17 августа 2011

Другая проблема с вашим примером кода: doInBackground() запускается в отдельном потоке. Вы пытаетесь манипулировать двумя TextViews из фонового потока, что недопустимо в Android.

Из документов Android SDK :

Кроме того, инструментарий Andoid UI не является поточно-ориентированным. Итак, вы должны не манипулировать своим пользовательским интерфейсом из рабочего потока - вы должны сделать все манипуляции с вашим пользовательским интерфейсом из потока пользовательского интерфейса. Таким образом, там это просто два правила для однопоточной модели Android:

Не блокировать поток пользовательского интерфейса

Не получать доступ к инструментарию пользовательского интерфейса Android из потока пользовательского интерфейса

Вам придется перевести вызовы на TextView обратно в ваш главный поток. AsyncTask дает вам два встроенных способа сделать это: onProgressUpdate() и onPostExecute(). Код, который вы поместили в любой из этих методов, будет запущен в основном потоке пользовательского интерфейса.

1 голос
/ 17 августа 2011

http://download.oracle.com/javase/1.5.0/docs/api/java/net/SocketTimeoutException.html

Время вашего подключения истекло.Вот почему NPE выбрасывается, так как вы пытаетесь .select("something") из нулевого объекта.Объект doc Document имеет значение null, поскольку данные не возвращаются из URL.И вот экземпляр AsyncTask выбрасывает RuntimeException.

Проверьте, находитесь ли вы за прокси.Проверьте, можете ли вы получить доступ к URL в вашем браузере.Проверьте DNS эмулятора.Также проверьте наличие разрешения ИНТЕРНЕТ в вашем манифесте.

Plus: Обновление пользовательского интерфейса должно выполняться в потоке пользовательского интерфейса.то есть вам нужно сделать это в onPostExecute()

Еdit:

class fetcher extends AsyncTask<Void,Void, Void>{
   //HERE DECLARE THE VARIABLES YOU USE FOR PARSING
   private Element overview=null;
   private  Element featureList=null;
   private Elements features=null;
   private Element paragraph =null;
    @Override
    protected Void doInBackground(Void... arg0) { 
        Document doc = null;
        try {
            doc = Jsoup.connect(url).get();
      overview = doc.select("div#object-overview").last();
       featureList = doc.select("div.callout-box").last();

       features = featureList.select("li");
       paragraph = overview.select("p").last();
        System.out.println(paragraph.text());
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        // Get the paragraph element
       // article.setText(paragraph.text()); I comment this out because you cannot update ui from non-ui thread, since doInBackground is running on background thread.


        return null;
    }
     @Override
     protected Void onPostExecute(Void result)
     {

    TextView article = (TextView)findViewById(R.id.releaseInfo);
        final TextView featuresText = (TextView)findViewById(R.id.features);
      for(Element e: features)
      {
        //setText()
      } 

} 

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...