【问题标题】:How to handle exceptions in Android by using throw如何使用 throw 处理 Android 中的异常
【发布时间】:2020-03-04 20:07:45
【问题描述】:

我正在尝试从网站获取信息并将其显示在 Android 应用中。问题“What is the fastest way to scrape HTML webpage in Android?”的第二个答案建议使用 BufferedReader。在答案中,此人使用 URL 类。我试图实现这样的答案:

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.widget.TextView;

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

import java.net.URL;

public class MainActivity extends AppCompatActivity {
    TextView display = (TextView) findViewById(R.id.textDisplay);

    @Override
    protected void onCreate(Bundle savedInstanceState) throws Exception {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        URL url = new URL("http://stackoverflow.com/questions/2971155");
        BufferedReader reader = null;
        StringBuilder builder = new StringBuilder();
        try {
            reader = new BufferedReader(new InputStreamReader(url.openStream(), "UTF-8"));
            for (String line; (line = reader.readLine()) != null; ) {
                builder.append(line.trim());
            }
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException logOrIgnore) {
                    logOrIgnore.printStackTrace();
                }
            }
        }
        String start = "<div class=\"post-text\"><p>";
        String end = "</p>";
        String part = builder.substring(builder.indexOf(start) + start.length());
        String question = part.substring(0, part.indexOf(end));
        TextView display = (TextView) findViewById(R.id.textDisplay);
        display.setText(question);

    }


}

我收到了这个错误:

'onCreate(Bundle)' in 'com.example.myproject.MainActivity' clashes with 
'onCreate(Bundle)' in 'android.appcompat.app.AppCompatActivity';
 overridden method does not throw 'java.lang.Exception'

您建议如何处理这个问题,这是从网站获取数据的明智方式吗? 非常感谢任何帮助

【问题讨论】:

  • 欢迎来到 StackOverflow!删除throws Exception,添加catch 到try 块,覆盖时不能修改方法声明。此外,你会得到异常,因为你试图在主线程上执行网络调用。使用 OkHttp 库。是的,不要尝试手动解析 html(SO 有 json API,afaik)

标签: android exception throws


【解决方案1】:

像这样修改代码

    public class MainActivity extends AppCompatActivity {
        TextView display = (TextView) findViewById(R.id.textDisplay);

        @Override
        protected void onCreate(Bundle savedInstanceState) throws Exception {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);

try{
            URL url = new URL("http://stackoverflow.com/questions/2971155");
            BufferedReader reader = null;
            StringBuilder builder = new StringBuilder();
            try {
                reader = new BufferedReader(new InputStreamReader(url.openStream(), "UTF-8"));
                for (String line; (line = reader.readLine()) != null; ) {
                    builder.append(line.trim());
                }
            } finally {
                if (reader != null) {
                    try {
                        reader.close();
                    } catch (IOException logOrIgnore) {
                        logOrIgnore.printStackTrace();
                    }
                }
            }
            String start = "<div class=\"post-text\"><p>";
            String end = "</p>";
            String part = builder.substring(builder.indexOf(start) + start.length());
            String question = part.substring(0, part.indexOf(end));
            TextView display = (TextView) findViewById(R.id.textDisplay);
            display.setText(question);
}catch(Exception ex){
Log.e("EEXCCEption","ex.localizedMessage.toString()")

}

        }


    }

在 Logger 文件中你可以得到异常的实际原因。

【讨论】:

    【解决方案2】:

    首先 - onCreate() 应该是 public,而不是 protected。 其次,onCreate()的签名不会抛出异常,所以覆盖的时候不能加。如果你真的想扔,那么你能做的最好的就是从方法签名中删除throwscatch,将它包装在RuntimeException中并重新扔:

    try {
      // .. your code
    } catch(Exception e){
        throw new RuntimeException(e);
    }finally {
                if (reader != null) {
                    try {
                        reader.close();
                    } catch (IOException logOrIgnore) {
                        logOrIgnore.printStackTrace();
                    }
                }
            }
    

    【讨论】:

      【解决方案3】:

      onCreate() 方法是Activity 生命周期的一部分,您只是覆盖它(注意@Override),而不是编写自己的,因此您无法更改属性、返回类型或添加/删除throws 声明

      protected void onCreate(Bundle savedInstanceState) throws Exception { 中删除throws Exception - 这会导致您的异常

      并使用try{}catch{},例如

      try {
          reader = new BufferedReader(new InputStreamReader(url.openStream(), "UTF-8"));
          for (String line; (line = reader.readLine()) != null; ) {
              builder.append(line.trim());
          }
      } catch(Exception e){
          e.printStackTrace();
          //TODO handle exception by own, don't throw outside onCreate, it will break lifecycle
      } finally {
          ...
      

      @Neeraj 这不是真的,事实上这是你可以改变的唯一一件事 - 类可访问性(publicprotected 等) - 但仅适用于“更易访问”版本,所以 protectedpublic,但不是例如publicprivate。顺便提一句。其实super这个方法的版本是protected,@MamoRatzo没改,没关系

      【讨论】:

        猜你喜欢
        • 2011-04-25
        • 1970-01-01
        • 1970-01-01
        • 2016-01-13
        • 1970-01-01
        • 2014-03-12
        • 1970-01-01
        • 2014-07-10
        相关资源
        最近更新 更多