当返回位图的方法失败时,如何处理?

时间:2012-03-23 02:43:27

标签: java android exception-handling

我正在编写一些代码,这些代码填充了从YouTube中提取的图像。现在它的工作区别于找不到图像的时候,我不知道为什么它找不到图像,因为图像链接在浏览器中工作但这实际上对我有利,因为它清除了已经存在的视频因版权/帐户关闭等原因删除。

我获取图片的代码如下

呼叫

        final Object item = allMatches.get(position);
        if(item != null) {
        Bitmap bitmap = loadBitmap("http://i2.ytimg.com/vi/"+ allMatches.get(position).toString() + "/default.jpg"); 
        imageView.setImageBitmap(bitmap);
        }
        else { imageView.setImageDrawable(getResources().getDrawable(R.drawable.default1)); }

loadBitmap()

    public static Bitmap loadBitmap(String url) 
  {
      Bitmap bitmap = null;
      InputStream in = null;
      BufferedOutputStream out = null;

      try {
          in = new BufferedInputStream(new URL(url).openStream(),  4 * 1024);

          final ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
          out = new BufferedOutputStream(dataStream,  4 * 1024);

          int byte_;
          while ((byte_ = in.read()) != -1)
              out.write(byte_);
          out.flush();

          final byte[] data = dataStream.toByteArray();
          BitmapFactory.Options options = new BitmapFactory.Options();
          //options.inSampleSize = 1;

          bitmap = BitmapFactory.decodeByteArray(data, 0, data.length,options);
      } catch (IOException e) {
          Log.e("","Could not load Bitmap from: " + url);
      } finally {
          try{
              in.close();
              out.close();
          }catch( IOException e )
          {
              System.out.println(e);
          }
      }
      return bitmap;

所以这有时会因以下Stacktrace

而崩溃
03-23 01:47:10.087: E/(9757): Could not load Bitmap from: http://i2.ytimg.com/vi/8s3lnGuyC9M/default.jpg
03-23 01:47:10.247: W/dalvikvm(9757): threadid=1: thread exiting with uncaught exception (group=0x40018560)
03-23 01:47:10.267: E/AndroidRuntime(9757): FATAL EXCEPTION: main
03-23 01:47:10.267: E/AndroidRuntime(9757): java.lang.NullPointerException
03-23 01:47:10.267: E/AndroidRuntime(9757):     at com.myapp.Sample.loadBitmap(Sample.java:159)
03-23 01:47:10.267: E/AndroidRuntime(9757):     at com.myapp..Sample$ImageAdapter.getView(Sample.java:207)
03-23 01:47:10.267: E/AndroidRuntime(9757):     at android.widget.AbsListView.obtainView(AbsListView.java:1467)
03-23 01:47:10.267: E/AndroidRuntime(9757):     at android.widget.GridView.onMeasure(GridView.java:935)
03-23 01:47:10.267: E/AndroidRuntime(9757):     at android.view.View.measure(View.java:8330)
03-23 01:47:10.267: E/AndroidRuntime(9757):     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3138)
03-23 01:47:10.267: E/AndroidRuntime(9757):     at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1017)
03-23 01:47:10.267: E/AndroidRuntime(9757):     at android.widget.LinearLayout.measureVertical(LinearLayout.java:386)
03-23 01:47:10.267: E/AndroidRuntime(9757):     at android.widget.LinearLayout.onMeasure(LinearLayout.java:309)
03-23 01:47:10.267: E/AndroidRuntime(9757):     at android.view.View.measure(View.java:8330)
03-23 01:47:10.267: E/AndroidRuntime(9757):     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3138)
03-23 01:47:10.267: E/AndroidRuntime(9757):     at android.widget.FrameLayout.onMeasure(FrameLayout.java:250)
03-23 01:47:10.267: E/AndroidRuntime(9757):     at android.view.View.measure(View.java:8330)
03-23 01:47:10.267: E/AndroidRuntime(9757):     at android.widget.LinearLayout.measureVertical(LinearLayout.java:531)
03-23 01:47:10.267: E/AndroidRuntime(9757):     at android.widget.LinearLayout.onMeasure(LinearLayout.java:309)
03-23 01:47:10.267: E/AndroidRuntime(9757):     at android.view.View.measure(View.java:8330)
03-23 01:47:10.267: E/AndroidRuntime(9757):     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3138)
03-23 01:47:10.267: E/AndroidRuntime(9757):     at android.widget.FrameLayout.onMeasure(FrameLayout.java:250)
03-23 01:47:10.267: E/AndroidRuntime(9757):     at android.view.View.measure(View.java:8330)
03-23 01:47:10.267: E/AndroidRuntime(9757):     at android.view.ViewRoot.performTraversals(ViewRoot.java:843)
03-23 01:47:10.267: E/AndroidRuntime(9757):     at android.view.ViewRoot.handleMessage(ViewRoot.java:1865)
03-23 01:47:10.267: E/AndroidRuntime(9757):     at android.os.Handler.dispatchMessage(Handler.java:99)
03-23 01:47:10.267: E/AndroidRuntime(9757):     at android.os.Looper.loop(Looper.java:130)
03-23 01:47:10.267: E/AndroidRuntime(9757):     at android.app.ActivityThread.main(ActivityThread.java:3835)
03-23 01:47:10.267: E/AndroidRuntime(9757):     at java.lang.reflect.Method.invokeNative(Native Method)
03-23 01:47:10.267: E/AndroidRuntime(9757):     at java.lang.reflect.Method.invoke(Method.java:507)
03-23 01:47:10.267: E/AndroidRuntime(9757):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:847)
03-23 01:47:10.267: E/AndroidRuntime(9757):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:605)
03-23 01:47:10.267: E/AndroidRuntime(9757):     at dalvik.system.NativeStart.main(Native Method)

我需要做的是能够处理它无法检索图像。我的Java技能有限,但我想要类似下面的东西(但实际工作)

Bitmap bitmap = loadBitmap("http://i2.ytimg.com/vi/"+ allMatches.get(position).toString() + "/default.jpg"); //  

if (bitmap == null) {
   imageView.setImageBitmap(defaultBitmap); 
} else {
imageView.setImageBitmap(bitmap); }

//Doesn't work anyway due to 'Exception IOException is not compatible with throws clause in Adapter.getView'
try { 
Bitmap bitmap = loadBitmap("http://i2.ytimg.com/vi/"+ allMatches.get(position).toString() + "/default.jpg"); 
imageView.setImageBitmap(bitmap);
}catch( IOException ) {
imageView.setImageBitmap(defaultBitmap);
}

我对try catch块的理解是,如果你“发现错误”,代码应该继续。在这种情况下,不应该只是将错误打印到日志并继续?

如果'loadBitmap'在检索图像时失败,我怎么能这样做?

编辑:我根据一些用户评论更新了代码 - 它仍然提供完全相同的错误,它只是消除了一些关于失败点的疑问。另外,澄清

Line 159: in.close();
Line 207: Bitmap bitmap = loadBitmap("http://i2.ytimg.com/vi/"+ allMatches.get(position).toString() + "/default.jpg"); 

3 个答案:

答案 0 :(得分:0)

这是错误:

catch (IOException e) 
{
    Log.e("","Could not load Bitmap from: " + url);
    // If IOExceotion occurs, the `bitmap` variable is null, right?
    bitmap = bitmap.loadBitmap("http://i2.ytimg.com/vi/k4v9JWUhveY/default.jpg");
    //       ^^^^^^ NullPointerException will be thrown and IOException will be lost (overwritten by NullPointerException).
} 

答案 1 :(得分:0)

我打算像第三次一样说。您应尽可能避免使用Exception。你说它不起作用,你能不能告诉我们你Sample.java类的哪一行159和207哪个,发生了NullPointerException?理解这个问题会有很大的帮助。

这条线指向哪里?你似乎没有在你的问题中引用它:

03-23 01:47:10.267: E/AndroidRuntime(9757):     at com.myapp..Sample$ImageAdapter.getView(Sample.java:207)

为什么不将默认图像设置为局部可绘制而不是从网站中提取?

答案 2 :(得分:0)

首先:

try
{
    Bitmap bitmap = loadBitmap("http://i2.ytimg.com/vi/"+ allMatches.get(position).toString() + "/default.jpg"); 
    imageView.setImageBitmap(bitmap);
}
catch(IOException e)
{
    System.err.println("Couldn't load image: "+e.getMessage());
    imageView.setImageDrawable(getResources().getDrawable(R.drawable.default1)); 
}

第二

public static Bitmap loadBitmap(String url) throws IOException
{
    final InputStream in = new BufferedInputStream(new URL(url).openStream(),  4 * 1024);

    try 
    {
        final ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
        final BufferedOutputStream out = new BufferedOutputStream(dataStream,  4 * 1024);

        try
        {
            int byte_;
            while ((byte_ = in.read()) != -1)
                out.write(byte_);
            out.flush();

            final byte[] data = dataStream.toByteArray();
            BitmapFactory.Options options = new BitmapFactory.Options();
            //options.inSampleSize = 1;

            return BitmapFactory.decodeByteArray(data, 0, data.length,options);
        }
        finally
        {
            out.close();
        }
    } 
    finally 
    {
        in.close();
    }
}