【问题标题】:Crash report on AsyncTaskAsyncTask 的崩溃报告
【发布时间】:2013-08-18 04:25:13
【问题描述】:

我收到有关 Google Play 中某个应用的崩溃报告。我使用异步任务来获取图像,它适用于我测试的每台设备,但有些用户遇到了问题。这真的很少见,但我需要调试和修复它。这是 doInBackground 方法:

public class MetaTask extends AsyncTask<Void, Void, Void> {
    URL imageurl;

    @Override
    protected Void doInBackground(Void... params) {
        try {
            doc = Jsoup.connect(data).get();
            Elements meta = doc.select("meta[property=og:image]");
            for (Element element : meta) {
                extracted = element.attr("content");
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block

            e.printStackTrace();
        }

        try {
            imageurl = new URL(extracted);
        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        try {
            bitmap = BitmapFactory.decodeStream(imageurl.openConnection()
                    .getInputStream());
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return null;
    }

空指针似乎在这一行(271):

bitmap = BitmapFactory.decodeStream(imageurl.openConnection()
                .getInputStream()); 

由于某种原因,我正在考虑变量 imageurl 不是实际的 url,我唯一能想到的就是检查提取的包含“http”和“jpg”的字符串变量,如果这些变量不存在,则存储这个使用 Flurry 获取信息。

在执行异步任务之前,会检查互联网连接的可用性,因此不会导致这种情况。

谁能想到导致这种情况的其他原因?这是我对崩溃报告的完整堆栈跟踪记录:

java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:278)
at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:208)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at java.lang.Thread.run(Thread.java:856) 
Caused by: java.lang.NullPointerException
at        com.ddroid.photosaveinstagram.MainActivity$MetaTask.doInBackground(MainActivity.java:271)
at com.ddroid.photosaveinstagram.MainActivity$MetaTask.doInBackground(MainActivity.java:1)
at android.os.AsyncTask$2.call(AsyncTask.java:264)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
... 5 more

【问题讨论】:

  • 如果你在 try 块中记录 imageURl,它是空的吗?
  • 是的,我可以尝试使用 Flurry。问题是,我在 9 台设备上进行了测试。它总是有效,但这些来自用户。
  • 您的错误来自于滥用 try/catch 来抑制/忽略异常。异常不应被忽略,而应被处理。当某一点发生异常(imageUrl在您的情况下)并且需要此值时,整个块的执行将停止。您不应执行依赖于 try/catch 中的变量/对象的代码,这些变量/对象被您抑制但未正确处理。

标签: android android-asynctask bitmapfactory


【解决方案1】:

如果遇到异常怎么办:

try {
            imageurl = new URL(extracted);
        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

那么您的 imageurl 将为空。所以,这里:

try {
            bitmap = BitmapFactory.decodeStream(imageurl.openConnection()
                    .getInputStream());
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

你会得到 NullPointerException 因为imageurl 只是声明了但没有初始化。所以在顶部改变这个:

URL imageurl=null

希望这可行。祝你好运。

【讨论】:

  • 谢谢,我试试这个。我仍然需要跟踪这是如何实现的,但这至少可以防止我的应用崩溃。
【解决方案2】:

为了完整起见:

在您的代码中,如果您需要使用在 try/catch 块中获得的值,则您不应该这样做!相反,编写更好的代码会更好,并且可以避免这种情况。

public class MetaTask extends AsyncTask<Void, Void, Void> {
    URL imageurl;

    @Override
    protected Void doInBackground(Void... params) {
        try {
            doc = Jsoup.connect(data).get();
            Elements meta = doc.select("meta[property=og:image]");
            for (Element element : meta) {
                extracted = element.attr("content");
            }

            imageurl = new URL(extracted);
            bitmap = BitmapFactory.decodeStream(imageurl.openConnection()
                    .getInputStream());
        } catch (IOException e) {
            // TODO Auto-generated catch block

            e.printStackTrace();

            // Notify user that an IO error occured 
        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();

            // Notify user that the URL is invalid
        } catch (Exception e) {
            // Ignore all other errors... probably not a good idea unless you know what you do 
        }

        return null;
    }
}

此代码将在Exception 出现后立即退出,并且在try/catch 块内假定一切正常。

您应该学习如何正确处理异常,而不是忽略它们,因为 Eclipse 拒绝编译您的代码,并且您通过 IDE 辅助方法添加了一个自动尝试/捕获块。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多