对位图使用异步任务

时间:2014-01-11 11:44:23

标签: android url bitmap android-asynctask xamarin

我有一种方法可以在Google地图上添加许多标记。

这是我的代码:

item = new MapLocation();
URL myurl = new URL("http://www.canninginc.co.nz/CanFindLocation/yes.png"); 
Bitmap bmp = BitmapFactory.DecodeStream(myurl.OpenConnection().InputStream);
item.icon = BitmapDescriptorFactory.FromBitmap(bmp);
item.Location = new LatLng (-41.227834, 174.812857);
item.Snippet = "Snippet2";
item.Title = "Title2";
item.ShowInfoWindowOnStartup = true;
_mapLocationList.Add(item);

我收到此错误:

  

抛出了'Android.OS.NetworkOnMainThreadException'类型的异常。

我做了一些研究,我认为我需要在获取Bitmap时在另一个线程上运行该操作。

我可以帮助您使用此代码吗? AsyncTask是否返回一个Bitmap,或者我如何将两者绑在一起?

提前致谢。

修改

我正在使用Xamarin,并将以下代码发布到新类中:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.Graphics;

namespace SimpleMapDemo
{
    class MyAsyncTask extends AsyncTask<String, Void, Bitmap>
    {
        @Override
        protected Bitmap doInBackground(String... urls) {
            if (urls.length > 0) {
                URL myurl = new URL("http://www.canninginc.co.nz/CanFindLocation/yes.png"); 
                return BitmapFactory.DecodeStream(myurl.OpenConnection().InputStream);
            }

            return null;
        }
        @Override
        protected void onPostExecute(Bitmap bmp) {
            super.onPostExecute(bmp);

            if (bmp != null) {
                item = new MapLocation();
                item.icon = BitmapDescriptorFactory.FromBitmap(bmp);
                item.Location = new LatLng (-41.227834, 174.812857);
                item.Snippet = "Snippet2";
                item.Title = "Title2";
                item.ShowInfoWindowOnStartup = true;
                _mapLocationList.Add(item);
            }
        }
    }
}

我收到很多错误。我将此代码放在正确的区域吗?

3 个答案:

答案 0 :(得分:4)

在AsyncTask的doInBackground中获取输入Stream,如:

private class LoadImage extends AsyncTask<String, Void, Bitmap> {

    @Override
    protected String doInBackground(String... params) {
       URL myurl = new URL("http://www.canninginc.co.nz/CanFindLocation/yes.png"); 
       Bitmap bmp = BitmapFactory.DecodeStream(myurl.OpenConnection().InputStream);
       return bmp;
    }

    @Override
    protected void onPostExecute(String result) {
        item.icon = BitmapDescriptorFactory.FromBitmap(bmp);
        item.Location = new LatLng (-41.227834, 174.812857);
        item.Snippet = "Snippet2";
        item.Title = "Title2";
        item.ShowInfoWindowOnStartup = true;
        _mapLocationList.Add(item);
    }

    @Override
    protected void onPreExecute() {}

    @Override
    protected void onProgressUpdate(Void... values) {}
}

并且

new LoadImage().execute();

您还可以动态设置图片网址:

 private class LoadImage extends AsyncTask<String, Void, Bitmap> {

    @Override
    protected String doInBackground(String... params) {
       URL myurl = new URL(params[0]); 
       Bitmap bmp = BitmapFactory.DecodeStream(myurl.OpenConnection().InputStream);
       return bmp;
    }

    @Override
    protected void onPostExecute(String result) {
        item.icon = BitmapDescriptorFactory.FromBitmap(bmp);
        item.Location = new LatLng (-41.227834, 174.812857);
        item.Snippet = "Snippet2";
        item.Title = "Title2";
        item.ShowInfoWindowOnStartup = true;
        _mapLocationList.Add(item);
    }

    @Override
    protected void onPreExecute() {}

    @Override
    protected void onProgressUpdate(Void... values) {}
}

并且

new LoadImage().execute("http://www.canninginc.co.nz/CanFindLocation/yes.png");

答案 1 :(得分:1)

当您创建从AsyncTask派生的类时,您必须指定3个通用参数:参数,进度,结果和Override doInBackground函数。此函数的签名为protected Result doInBackground(Params...)

回到你的问题,你可以使用这样的东西:

class MyAsyncTask extends AsyncTask<String, Void, Bitmap>
    @Override
    protected Bitmap doInBackground(String... urls) {
        if (urls.length > 0) {
            URL myurl = new URL("http://www.canninginc.co.nz/CanFindLocation/yes.png"); 
            return BitmapFactory.DecodeStream(myurl.OpenConnection().InputStream);
        }

        return null;
    }

    @Override
    protected void onPostExecute(Bitmap bmp) {
        super.onPostExecute(bmp);

        if (bmp != null) {
            item = new MapLocation();
            item.icon = BitmapDescriptorFactory.FromBitmap(bmp);
            item.Location = new LatLng (-41.227834, 174.812857);
            item.Snippet = "Snippet2";
            item.Title = "Title2";
            item.ShowInfoWindowOnStartup = true;
            _mapLocationList.Add(item);
        }
    }
}

之后你可以这样称呼它:

new MyAsyncTask().execute("http://www.canninginc.co.nz/CanFindLocation/yes.png");

答案 2 :(得分:0)

AsyncTask用于在后台执行任务,任何任务,不阻碍或阻止主UI线程。它提供了三种有用的方法(等等)来调整操作。

  1. onPreExecute:在执行主要工作之前准备你的东西,比如显示加载图标。
  2. doInBackground:执行真正的任务,如基于网络的操作或繁重的计算。
  3. onPostExecute:在后台操作完成后调用此方法,您现在可以安全地更新UI。