对位图使用异步任务



我有一个方法可以在谷歌地图上添加许多标记。

这是我的代码:

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"的异常。

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

我可以对此代码提供一些帮助吗?AsyncTask 是否返回位图,或者如何将两者绑定在一起?

提前谢谢。

编辑

我正在使用 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);
            }
        }
    }
}

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

在 AsyncTask 的 doInBackground 中获取输入流,如下所示:

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");

创建派生自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");

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

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

最新更新