我有一个方法可以在谷歌地图上添加许多标记。
这是我的代码:
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 线程。它提供了三种有用的方法(除其他外)来调整操作。
- onPreExecute:在执行主要工作之前准备你的东西,比如显示加载图标。
- doInBackground:执行实际任务,如基于网络的操作或繁重的计算。
- onPostExecute:在后台操作完成时调用此方法,您现在可以安全地更新 UI。