1

I have a method that adds many Markers to a Google Map.

Here is my code:

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

I am getting this error:

Exception of type 'Android.OS.NetworkOnMainThreadException' was thrown.

I have done some research and I think I need to run the action on another thread when getting the Bitmap.

Can I have some help with this code? Does the AsyncTask return a Bitmap, or how do I tie the two together?

Thanks in advance.

EDIT

I am using Xamarin, and have posted the following code into a new class:

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

I am getting many errors. Am I placing this code in the correct area?

3
  • Search for async task in android documentation.. Commented Jan 11, 2014 at 11:55
  • There is no error here. Please show your code in activity. I think the problem in that one. Commented Jan 11, 2014 at 13:52
  • @Override and extends are Java words. In C#,you need to change them, e.g. override in declaration and using :. Or alternatively, you may look at this Async Support Overview in Xamarin Commented Jan 12, 2014 at 5:42

3 Answers 3

4

Get the input Stream in doInBackground of AsyncTask like:

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) {}
}

And

new LoadImage().execute();

You can also set Image URL dynamically as:

 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) {}
}

And

new LoadImage().execute("http://www.canninginc.co.nz/CanFindLocation/yes.png");
Sign up to request clarification or add additional context in comments.

Comments

1

When you create a class derived from AsyncTask you have to specify 3 generic parameters: Params, Progress, Result, and Override the doInBackground function. This function has a signature of protected Result doInBackground(Params...).

Back to your question you can use something like this:

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

After that you can call it this way:

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

1 Comment

Sorry I didn't realise you're using xamarin, this code is java
0

AsyncTask is used to perform task, any task, in the background, not obstructing or holding back the main UI thread. It provides three useful methods, (among others) to tune up the operation.

  1. onPreExecute: to prepare your stuff, before performing the main job, like showing loading icon.
  2. doInBackground: to perform real task, like network based operation or heavy calculation.
  3. onPostExecute: this method is called when the background operation is done and you can now safely update the UI.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.