3

I have a problem with google maps implementation in Android. I want to get some data from the internet (some let's say units on the visible part of the map). The problem begins, when I want to clear all the previous markers from the map in the onPostExecute. Here is the code:

private class GetNewPins extends AsyncTask<Void, String, Unit[]>
{

    @Override
    protected Unit[] doInBackground(Void... f_url)
    {
        try
        {
            LatLng campos = map.getCameraPosition().target;
            VisibleRegion vr = map.getProjection().getVisibleRegion();
            double left = vr.latLngBounds.southwest.longitude;
            double top = vr.latLngBounds.northeast.latitude;
            double right = vr.latLngBounds.northeast.longitude;
            double bottom = vr.latLngBounds.southwest.latitude;
            Location middleLeftCornerLocation = new Location("right");
            Location center = new Location("center");
            middleLeftCornerLocation.setLatitude(right);
            middleLeftCornerLocation.setLongitude(vr.latLngBounds
                    .getCenter().longitude);
            center.setLatitude(vr.latLngBounds.getCenter().latitude);
            center.setLongitude(vr.latLngBounds.getCenter().longitude);
            float dis = center.distanceTo(middleLeftCornerLocation);
            System.out.println("Gettin' data from " + campos.latitude + " "
                    + campos.longitude + " " + dis);
            Unit[] units = new FreechargingAPI().GetUnitsOnMap(
                    campos.latitude, campos.longitude, dis);
            if (units != null)
            {
                return units;
            }

        } catch (Exception e)
        {
            System.out.println(e);
        }
        return null;
    }

    @Override
    protected void onPostExecute(final Unit[] units)
    {
        if (units == null)
        {
            return;
        }

        MapView.this.runOnUiThread(new Runnable()
        {
            @Override
            public void run()
            {
                map.clear();
                for (Unit u : units)
                {
                    // Creating an instance of MarkerOptions to set position
                    MarkerOptions markerOptions = new MarkerOptions();

                    // Setting position on the MarkerOptions
                    markerOptions.position(new LatLng(Double.parseDouble(u
                            .getUnitgpslatitude()), Double.parseDouble(u
                            .getUnitgpslongitude())));

                    // Adding marker on the GoogleMap
                    Marker marker = map.addMarker(markerOptions.title(
                            u.getUnitname()).snippet(
                            DistanceConverter.convert(u.getDistance())));

                    // Showing InfoWindow on the GoogleMap
                    marker.showInfoWindow();

                }
            }// public void run() {
        });


    }
}

as you might see, I've already tried to do some research about the issue map.clear() "not running the main thread" but without success, as the asynctask doesn't run at all and all I get is just this illegalstateexception: not on the main thread.

EDIT1: No, it does not even work in plain onpostexecute and I still getting not on the main thread stuff

EDIT2: as I totally forgot about stack trace, I've realised that I've had a try catch block in background process, sorry, I wrote that code at 4 in the morning. So the stack trace is:

 11-05 10:48:56.504: W/System.err(5498): java.lang.IllegalStateException: Not on the main thread
 11-05 10:48:56.504: W/System.err(5498):    at com.google.j.a.cl.b(Unknown Source)
 11-05 10:48:56.504: W/System.err(5498):    at com.google.maps.api.android.lib6.c.br.b(Unknown Source)
 11-05 10:48:56.504: W/System.err(5498):    at com.google.maps.api.android.lib6.c.dw.a(Unknown Source)
 11-05 10:48:56.504: W/System.err(5498):    at com.google.android.gms.maps.internal.l.onTransact(SourceFile:51)
 11-05 10:48:56.505: W/System.err(5498):    at android.os.Binder.transact(Binder.java:380)
 11-05 10:48:56.505: W/System.err(5498):    at com.google.android.gms.maps.internal.IGoogleMapDelegate$a$a.getCameraPosition(Unknown Source)
 11-05 10:48:56.505: W/System.err(5498):    at com.google.android.gms.maps.GoogleMap.getCameraPosition(Unknown Source)
 11-05 10:48:56.505: W/System.err(5498):    at com.reddatura.freecharging_beta.MapView$GetNewPins.doInBackground(MapView.java:241)
 11-05 10:48:56.505: W/System.err(5498):    at com.reddatura.freecharging_beta.MapView$GetNewPins.doInBackground(MapView.java:1)
 11-05 10:48:56.505: W/System.err(5498):    at android.os.AsyncTask$2.call(AsyncTask.java:288)
 11-05 10:48:56.505: W/System.err(5498):    at java.util.concurrent.FutureTask.run(FutureTask.java:237)
 11-05 10:48:56.505: W/System.err(5498):    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
 11-05 10:48:56.505: W/System.err(5498):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
 11-05 10:48:56.505: W/System.err(5498):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
 11-05 10:48:56.505: W/System.err(5498):    at java.lang.Thread.run(Thread.java:818)

thanks Peter for that. SO the problem doesn't seem to be at onPostExecute as I initially thought, but it is the doinbackground, where I want to get the campos variable

EDIT3: as Adogeon advised I've put the whole thing in the main loop, but there is this exception, which I was aware, just for the sake why I used asynctask for this...but I am prone to other suggestions

11-05 11:28:06.926: W/System.err(6417): android.os.NetworkOnMainThreadException
11-05 11:28:06.927: W/System.err(6417):     at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1147)
11-05 11:28:06.927: W/System.err(6417):     at libcore.io.BlockGuardOs.recvfrom(BlockGuardOs.java:249)
11-05 11:28:06.927: W/System.err(6417):     at libcore.io.IoBridge.recvfrom(IoBridge.java:553)
11-05 11:28:06.927: W/System.err(6417):     at java.net.PlainSocketImpl.read(PlainSocketImpl.java:485)
11-05 11:28:06.927: W/System.err(6417):     at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:37)
11-05 11:28:06.927: W/System.err(6417):     at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:237)
11-05 11:28:06.927: W/System.err(6417):     at com.android.okio.Okio$2.read(Okio.java:113)
11-05 11:28:06.927: W/System.err(6417):     at com.android.okio.RealBufferedSource.indexOf(RealBufferedSource.java:147)
11-05 11:28:06.927: W/System.err(6417):     at com.android.okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:94)
11-05 11:28:06.928: W/System.err(6417):     at com.android.okhttp.internal.http.HttpConnection.readResponse(HttpConnection.java:175)
11-05 11:28:06.928: W/System.err(6417):     at com.android.okhttp.internal.http.HttpTransport.readResponseHeaders(HttpTransport.java:101)
11-05 11:28:06.928: W/System.err(6417):     at com.android.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:616)
11-05 11:28:06.928: W/System.err(6417):     at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:379)
11-05 11:28:06.928: W/System.err(6417):     at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:323)
11-05 11:28:06.928: W/System.err(6417):     at com.android.okhttp.internal.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:190)
11-05 11:28:06.928: W/System.err(6417):     at com.reddatura.serverside.FreechargingAPI.ExecuteGET(FreechargingAPI.java:42)
11-05 11:28:06.928: W/System.err(6417):     at com.reddatura.serverside.FreechargingAPI.GetUnitsOnMap(FreechargingAPI.java:100)
11-05 11:28:06.928: W/System.err(6417):     at com.reddatura.freecharging_beta.MapView$1.onMapSettled(MapView.java:101)
11-05 11:28:06.928: W/System.err(6417):     at com.reddatura.listeners.MapStateListener.settleMap(MapStateListener.java:119)
11-05 11:28:06.928: W/System.err(6417):     at com.reddatura.listeners.MapStateListener$4$1.run(MapStateListener.java:78)
11-05 11:28:06.928: W/System.err(6417):     at android.os.Handler.handleCallback(Handler.java:739)
11-05 11:28:06.928: W/System.err(6417):     at android.os.Handler.dispatchMessage(Handler.java:95)
11-05 11:28:06.928: W/System.err(6417):     at android.os.Looper.loop(Looper.java:135)
11-05 11:28:06.928: W/System.err(6417):     at android.app.ActivityThread.main(ActivityThread.java:5221)
11-05 11:28:06.928: W/System.err(6417):     at java.lang.reflect.Method.invoke(Native Method)
11-05 11:28:06.929: W/System.err(6417):     at java.lang.reflect.Method.invoke(Method.java:372)
11-05 11:28:06.929: W/System.err(6417):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
11-05 11:28:06.929: W/System.err(6417):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

EDIT X: never mind guys, I've hacked it ugly, but for now it seems it works...moved all the "map based stuff" before the asynctask execution, so I'm passing stuff between threads, which is quite unsafe, but it does work and nothing else matters. May God have mercy on my soul for the sin I will commit to git... Thank you all for the help :)

4
  • OnPostExecute is in the main thread already, you shouldnt need runOnUiThread, just put your code there Commented Nov 5, 2014 at 9:35
  • I've tried it also, but that tells me the same Commented Nov 5, 2014 at 9:39
  • When asking questions about exceptions, please ALWAYS include FULL stack trace. Commented Nov 5, 2014 at 9:42
  • how do you invoke your asynctask? Commented Nov 5, 2014 at 9:49

3 Answers 3

1

You should call the operation on main thread. You cannot manipulate views on other than main thread (e.g. in doInBackground method). Just delete the Async task.

Sign up to request clarification or add additional context in comments.

1 Comment

but the Unit[] units = new FreechargingAPI().GetUnitsOnMap(campos.latitude, campos.longitude, dis); is network operation
0

Adogeon is correct when he says "You should call the operation on main thread. You cannot manipulate views on other than main thread (e.g. in doInBackground method)".

Citrus, more specifically your problem is on below code block:

LatLng campos = map.getCameraPosition().target;
VisibleRegion vr = map.getProjection().getVisibleRegion();

When you call map.someFunction(). You can not call a method of a view there.

Comments

0

I've done it this way:

vr = map.getProjection().getVisibleRegion();
LatLng curPos = map.getCameraPosition().target;
if (prevPos.latitude != curPos.latitude
        || prevPos.longitude != curPos.longitude)
{
    new GetNewPins().execute(curPos);
}

vr is VisibleRegion which is private field in class, which will be used by GetNewPins. Also I've changed the parameter to LatLng of GetNewPins, so now all Google maps related stuff is on the main thread.

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.