Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8240153
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 7, 20262026-06-07T20:23:26+00:00 2026-06-07T20:23:26+00:00

Here is the basic life cycle of my application. It targets SDK version 8

  • 0

Here is the basic life cycle of my application. It targets SDK version 8 by now, since I am still running Android 2.3.3 on my device.

  • The application starts, onResume() is called
    The method show() is called to display cached data.
  • A background service gets started which downloads and stores data. It uses AsyncTask instances to accomplish its work.
  • One of the tasks stores downloaded data in a SQLite database.
  • A broadcast intent is sent in onPostExecute() when the storing task has finished.
  • The MapActivity receives the intent and handles it.
    The method show() is called to display cached and new data.

Within the method show() the map view gets invalidated after the overlay has been added. This works fine when show() has been called from the MapActivity itself. It raises an exception, however, when the asynchonous task is the source of the method call (indirectly).

As far as I understand, I am at the UI thread when I trigger show() in both cases. Is this true?

    public class CustomMapActivity extends MapChangeActivity {

        private boolean showIsActive = false;

        private BroadcastReceiver mReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                if (intent.getAction().equals(IntentActions.FINISHED_STORING)) {
                    onFinishedStoring(intent);
                }
            }
        };

        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            registerReceiver(mReceiver, new IntentFilter(IntentActions.FINISHED_STORING));
        }

        @Override
        protected void onResume() {
            super.onResume();
            show();
        }

        @Override
        protected void onMapZoomPan() {
            loadData();
            show();
        }

        @Override
        protected void onMapPan() {
            loadData();
            show();
        }

        @Override
        protected void onMapZoom() {
            loadData();
            show();
        }

        private void onFinishedStoring(Intent intent) {
            Bundle extras = intent.getExtras();
            if (extras != null) {
                boolean success = extras.getBoolean(BundleKeys.STORING_STATE);
                if (success) {
                    show();
                }
        }

        private void loadData() {
            // Downloads data in a AsyncTask
            // Stores data in AsyncTask
        }

        private void show() {
            if (showIsActive) {
                return;
            }
            showIsActive = true;
            Uri uri = UriHelper.getUri();
            if (uri == null) {
                showIsActive = false;
                return;
            }
            Cursor cursor = getContentResolver().query(uri, null, null, null, null);
            if (cursor != null && cursor.moveToFirst()) {
                List<Overlay> mapOverlays = mapView.getOverlays();
                CustomItemizedOverlay overlay = ItemizedOverlayFactory.getCustomizedOverlay(this, cursor);
                if (overlay != null) {
                    mapOverlays.clear();
                    mapOverlays.add(overlay);
                }
            }
            cursor.close();
            mapView.invalidate(); // throws CalledFromWrongThreadException
            showIsActive = false;
        }

    }

Here is the stack trace …

android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
    at android.view.ViewRoot.checkThread(ViewRoot.java:3020)
    at android.view.ViewRoot.invalidateChild(ViewRoot.java:647)
    at android.view.ViewRoot.invalidateChildInParent(ViewRoot.java:673)
    at android.view.ViewGroup.invalidateChild(ViewGroup.java:2511)
    at android.view.View.invalidate(View.java:5332)
    at info.metadude.trees.activities.CustomMapActivity.showTrees(CustomMapActivity.java:278)
    at info.metadude.trees.activities.CustomMapActivity.onMapPan(CustomMapActivity.java:126)
    at info.metadude.trees.activities.MapChangeActivity$MapViewChangeListener.onChange(MapChangeActivity.java:50)
    at com.bricolsoftconsulting.mapchange.MyMapView$1.run(MyMapView.java:131)
    at java.util.Timer$TimerImpl.run(Timer.java:284)

Note: I use the MapChange project in order to receive notifications on map events.


EDIT:

From what I now read in the documentation about AsyncTask (scroll down a bit), I am not sure if I use it the correct way. As previously mentioned I start AsyncTask instances from within a Service class. In contrary, the documentation states …

AsyncTask allows you to perform asynchronous work on your user interface. It performs the blocking operations in a worker thread and then publishes the results on the UI thread, without requiring you to handle threads and/or handlers yourself.

… which sounds as if AsyncTask should only be used within an Activity not within a Service?!

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-07T20:23:28+00:00Added an answer on June 7, 2026 at 8:23 pm

    The reason for your crash is because of the way that the MapChange library you are using is implemented. Under the hood, this library uses Timer and TimerTask implementations to delay firing the change event and reduce the number of calls your application gets to onMapChanged(). However, you can see from the docs on Timer that it runs its tasks in created threads:

    Each timer has one thread on which tasks are executed sequentially. When this thread is busy running a task, runnable tasks may be subject to delays.

    Since the MapChange library does nothing to ensure that callbacks are posted to your application on the main thread (a serious bug IMO, especially on Android), you have to protect the code you call as a result of this listener. You can see this in the example MyMapActivity bundled with the library, everything from that callback gets funneled through a Handler which posts the calls back to the main thread for you.

    In your application, the code inside onMapPan() and subsequently showTrees() is being called on a background thread so it is not safe to manipulate the UI there. Using either a Handler or runOnUiThread() from your Activity will guarantee your code is called in the right place.

    With regards to your second questions about AsyncTask, there is nothing stopping you from using it inside of any application component, not just Activity. Even though it’s a “background” component, by default a Service is still running on the main thread as well, so AsyncTask is still necessary to offload long-term processing to another thread temporarily.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Here is the basic I am using FB.ui to post a flash application to
I'm fairly new in Android/Java programming, so some of the basic stuff is still
I am missing something embarrassingly basic here in my Merge Sort implementation: # include
I'm sure I'm doing something really dumb and basic here but I can't seem
Here's the basic UI i intend: There is central circle:CENTER. As the view is
Here's a basic view of what my html looks like: <form> <div id=part1> //
Here's the basic situation: I have an OpenGL VBO that draws a 2D symbol
Here's the basic information: I've been studying Rob Miles' C# Yellow Book 2011 extensively.
Here are my basic assumptions: Wcf executes my service operation methods on IOCP threads
Here one more basic question asked in MS interview recently class A { public

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.