【问题标题】:Use JSoup with Android Java在 Android Java 中使用 JSoup
【发布时间】:2012-09-10 13:44:33
【问题描述】:
package com.example.application;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;

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

import com.example.androidtablayout.R;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;


public class PhotosActivity extends Activity  {

    public void onCreate(Bundle savedInstanceState) {


        String htmlCode = "";

            Document doc;
              try {
                  //Problem start
            doc = Jsoup.connect("http://www.example.com/").get();
            Element content = doc.select("a").first();
                    String variable = content.text();
                  // Problem end
                    TextView t = new TextView(this);
                    t=(TextView)findViewById(R.id.textView3); 
                    t.setText(variable);
               } catch (IOException e) {
               // TODO Auto-generated catch block
               e.printStackTrace();
            }

            super.onCreate(savedInstanceState);
            setContentView(R.layout.photos_layout);

    }
}

我的问题是 JSoup 框架。在“问题”行之间。我采取“意外停止错误”。

当我像这样放置“htmlCode”变量时

t.SetText(htmlCode); 

这是工作,但我得到了所有的 html 源代码。

主要问题是什么,我不明白。

【问题讨论】:

    标签: java android jsoup


    【解决方案1】:

    你的代码有很多问题:

    • super.onCreate() 应该始终是您自己的onCreate() 中的第一个呼叫

    • 您在最后调用setContentView(),但在catch 子句中尝试在此之前调用findViewById()。此时,您的Activity 还没有内容视图,因此findViewById() 将返回null——由此产生的NullPointerException 很可能是您的代码崩溃的原因。

    • 您在 UI 线程上执行 IO。不要那样做,Android 会强制退出你的应用,因为 IO 是不可预测的,你的应用会无响应,网络 IO 更糟糕。查看AsyncTask,了解如何从 UI 线程执行 IO,然后异步更新您的 TextView

    另外,请查看logcat。对于大多数崩溃,它将包含一个堆栈跟踪,可以查明哪里出了问题。


    这是您的代码的重新修改版本,它遵循了我给出的一些建议。

    请注意,我没有有时间修复最重要的问题:这段代码仍然在 UI 线程上执行 IO。它应该改用AsyncTask

    public class PhotosActivity extends Activity {
    
      // Use a string constant to "tag" log statements that belong to the same
      // feature/module of your app. This activity does something with "photos" so
      // use that as a tag. It's the first parameter to Android's Log methods.
      private static final String TAG = "photos";
    
      @Override
      public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState); // Always call super.onCreate() first.
        setContentView(R.layout.photos_layout); // Then load the layout.
    
        // Find textView3 in layout and set it's text to HTML code.
        // There's no need to create a new TextView() here.
        TextView textView = (TextView) findViewById(R.id.textView3);
        textView.setText(getHtmlCode());
      }
    
      // Structure your code. If it's a larger block that does one thing,
      // extract it into a method.
      private String getHtmlCode() {
        try {
          Document doc = Jsoup.connect("http://www.example.com/").get();
          Element content = doc.select("a").first();
          return content.text();
        } catch (IOException e) {
          // Never e.printStackTrace(), it cuts off after some lines and you'll
          // lose information that's very useful for debugging. Always use proper
          // logging, like Android's Log class, check out
          // http://developer.android.com/tools/debugging/debugging-log.html
          Log.e(TAG, "Failed to load HTML code", e);
          // Also tell the user that something went wrong (keep it simple,
          // no stacktraces):
          Toast.makeText(this, "Failed to load HTML code",
              Toast.LENGTH_SHORT).show();
        }
      }
    }
    

    【讨论】:

    • 嘿,菲利普。感谢您的回答。我不明白的一点是,当我在 //problem start 和 //problem end 之间删除并将字符串变量放在“setText()”处时,我将变量放在我的布局中。我应该解决 onCreate 事件吗?你的意思是?
    • 对不起,我完全不明白你的评论。我已经快速修改了您的代码并将其添加到我的问题中——我希望这会有所帮助。请注意,代码仍然没有使用AsyncTask,但应该使用!
    • 谢谢菲利普!我为这段代码工作了 2 天。我理解我所有的错误。再次感谢:)
    • @ShabbirDhangot,请发布一个新问题,包括您的代码和堆栈跟踪。
    【解决方案2】:

    您应该将调用 super.onCreate(...)setContentView(...) 移动到 onCreate 方法的前两行。

    public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.photos_layout);
      .....
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-27
      • 2013-03-26
      • 1970-01-01
      • 1970-01-01
      • 2018-07-05
      • 2023-02-07
      相关资源
      最近更新 更多