runOnUiThread causing app slow-down and eventually force-close-Collection of common programming errors

I have MainActivity (which extends Activity) and GameView (which extends SurfaceView).

MainActivity has TextViews for score and for time left. GameView calculates score and time left, and updates the TextViews in MainActivity.

This works wells, but the problem is when I re-start the game over and over. The more games are re-started, the slower they become and eventually the app force-closes.

Below is what I see in logcat messages.

08-21 10:01:59.826: E/MP-Decision(293): UP Nw:2.700000 Tw:180 rq:2.900000 seq:198.000000
08-21 10:01:59.876: E/ThermalDaemon(294): Maximum CPU[1] frequency 1512000 KHz
08-21 10:01:59.986: I/AlarmManager(246): wakelock acquire, uid:1000 at elapsed real time: 1641603
08-21 10:02:00.016: I/AlarmManager(246): wakelock release, uid:1000 at elapsed real time: 1641632
08-21 10:02:01.096: I/ActivityManager(246): Start proc com.android.defcontainer for service com.android.defcontainer/.DefaultContainerService: pid=3014 uid=10026 gids={1015, 2001}
08-21 10:02:01.156: W/ActivityManager(246): No content provider found for: 
08-21 10:02:01.286: W/ActivityManager(246): No content provider found for: 
08-21 10:02:01.296: D/PackageParser(246): Scanning package: /data/app/vmdl184910092.tmp
08-21 10:02:01.776: I/PackageManager(246): Removing non-system package:com.example.game
08-21 10:02:01.786: I/ActivityManager(246): Force stopping package com.example.game uid=10038
08-21 10:02:02.076: E/MP-Decision(293): DOWN Ns:2.100000 Ts:270 rq:1.931900 seq:279.000000
08-21 10:02:02.476: D/PackageManager(246): Scanning package com.example.game
08-21 10:02:02.476: I/PackageManager(246): Package com.example.game codePath changed from /data/app/com.example.game-2.apk to /data/app/com.example.game-1.apk; Retaining data and using new
08-21 10:02:02.476: I/PackageManager(246): Unpacking native libraries for /data/app/com.example.game-1.apk
08-21 10:02:02.686: E/MP-Decision(293): UP Nw:2.700000 Tw:180 rq:2.926606 seq:205.000000
08-21 10:02:02.806: E/ThermalDaemon(294): Maximum CPU[1] frequency 1512000 KHz
08-21 10:02:03.366: E/MP-Decision(293): DOWN Ns:2.100000 Ts:270 rq:1.336134 seq:347.000000
08-21 10:02:03.556: D/PackageManager(246):   Activities: com.example.game.SplashScreen com.example.game.StartGame com.example.game.MainActivity com.example.game.Help com.example.game.Option com.example.game.Ranking com.example.game.GameOver
08-21 10:02:03.556: W/PackageManager(246): Code path for pkg : com.example.game changing from /data/app/com.example.game-2.apk to /data/app/com.example.game-1.apk
08-21 10:02:03.556: W/PackageManager(246): Resource path for pkg : com.example.game changing from /data/app/com.example.game-2.apk to /data/app/com.example.game-1.apk
08-21 10:02:03.566: I/ActivityManager(246): Force stopping package com.example.game uid=10038
08-21 10:02:03.676: D/PackageManager(246): New package installed in /data/app/com.example.game-1.apk
08-21 10:02:03.786: I/ActivityManager(246): Force stopping package com.example.game uid=10038
08-21 10:02:03.846: I/ActivityManager(246): Start proc com.miui.uac for broadcast com.miui.uac/.UninstallReceiver: pid=3044 uid=10005 gids={1015, 3003}
08-21 10:02:03.886: D/Launcher.Model(438): Got action android.intent.action.PACKAGE_REMOVED
08-21 10:02:03.886: D/LauncherSettings(438): Updating home screen for package com.example.game
08-21 10:02:03.886: D/ScreenUtils(438): Updating home screen for package com.example.game
08-21 10:02:03.896: D/ScreenUtils(438): Found existing items: [35]
08-21 10:02:03.896: D/ScreenUtils(438): Updating home screen item 35
08-21 10:02:03.946: E/jdwp(3044): Failed writing handshake bytes: Broken pipe (-1 of 14)
08-21 10:02:03.986: E/MP-Decision(293): UP Nw:2.700000 Tw:180 rq:5.100000 seq:197.000000
08-21 10:02:04.016: D/InstallReceiver(3044): com.example.game
08-21 10:02:04.016: I/ActivityManager(246): Start proc com.svox.pico for broadcast com.svox.pico/.VoiceDataInstallerReceiver: pid=3057 uid=10009 gids={}
08-21 10:02:04.056: W/RecognitionManagerService(246): no available voice recognition services found
08-21 10:02:04.076: W/Searchables(246): No web search activity found
08-21 10:02:04.096: I/ActivityThread(3057): Pub com.svox.pico.providers.SettingsProvider: com.svox.pico.providers.SettingsProvider
08-21 10:02:04.106: D/GTalkService(464): handlePackageInstalled: re-initialize providers
08-21 10:02:04.106: D/GTalkService(464): [RawStanzaProvidersMgr] ##### searchProvidersFromIntent
08-21 10:02:04.106: I/ActivityManager(246): Start proc com.google.android.partnersetup for broadcast com.google.android.partnersetup/.AppInstalledReceiver: pid=3074 uid=10021 gids={}
08-21 10:02:04.106: D/GTalkService(464): [RawStanzaProvidersMgr] no intent receivers found
08-21 10:02:04.226: E/ThermalDaemon(294): Maximum CPU[1] frequency 1512000 KHz
08-21 10:02:04.496: D/Launcher.Model(438): Got action android.intent.action.PACKAGE_ADDED
08-21 10:02:04.506: D/LauncherSettings(438): Updating home screen for package com.example.game
08-21 10:02:04.506: D/ScreenUtils(438): Updating home screen for package com.example.game
08-21 10:02:04.506: D/ScreenUtils(438): Found existing items: [35]
08-21 10:02:04.506: D/ScreenUtils(438): Updating home screen item 35
08-21 10:02:04.516: D/AllAppsList(438): Loaded application Korean Word Pop at (0, 2) of screen 3 under container -100
08-21 10:02:04.556: D/ApplicationContext(438): Generate customized icon for com.example.game.png
08-21 10:02:04.646: I/ActivityManager(246): Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.example.game/.StartGame } from pid 3103
08-21 10:02:04.986: E/MP-Decision(293): DOWN Ns:2.100000 Ts:270 rq:1.400000 seq:358.000000
08-21 10:02:05.146: W/ActivityManager(246): Activity pause timeout for HistoryRecord{406c8b68 com.android.launcher/com.android.launcher2.Launcher}
08-21 10:02:05.146: I/ActivityManager(246): Start proc com.example.game for activity com.example.game/.StartGame: pid=3112 uid=10038 gids={1015}
08-21 10:02:05.176: D/PhoneWindow(438): couldn't save which view has focus because the focused view com.android.launcher2.CellScreen@40567918 has no id.
08-21 10:02:05.346: E/MP-Decision(293): UP Nw:2.700000 Tw:180 rq:7.100000 seq:197.000000
08-21 10:02:05.436: E/ThermalDaemon(294): Maximum CPU[1] frequency 1512000 KHz
08-21 10:02:05.546: I/ActivityManager(246): Displayed com.example.game/.StartGame: +404ms
08-21 10:02:05.896: E/MP-Decision(293): DOWN Ns:2.100000 Ts:270 rq:1.168067 seq:337.000000
08-21 10:02:09.606: I/ActivityManager(246): Starting: Intent { cmp=com.example.game/.MainActivity } from pid 3112
08-21 10:02:09.606: E/AwesomePlayer(153): AudioPlayer created, Non-LPA mode mime audio/mpeg duration 104437
08-21 10:02:09.666: E/InputDispatcher(246): channel 'StatusBarView (server)' ~ Consumer closed input channel or an error occurred.  events=0x8
08-21 10:02:09.666: E/InputDispatcher(246): channel 'StatusBarView (server)' ~ Channel is unrecoverably broken and will be disposed!
08-21 10:02:09.666: D/AudioHardwareMSM8660(153): write(): dec_id = 1 cur_rx = speaker_stereo_rx
08-21 10:02:09.666: D/AudioHardwareMSM8660(153): value of device and enable is  1
08-21 10:02:10.096: D/ACDB-LOADER(153): ACDB -> send_audio_cal, acdb_id = 15, path =  0
08-21 10:02:10.096: D/ACDB-LOADER(153): ACDB -> send_audtable
08-21 10:02:10.096: D/ACDB-LOADER(153): ACDB -> ACDB_CMD_GET_AUDPROC_COMMON_TABLE
08-21 10:02:10.096: D/ACDB-LOADER(153): ACDB -> AUDIO_SET_AUDPROC_CAL
08-21 10:02:10.096: D/ACDB-LOADER(153): ACDB -> send_audvoltable
08-21 10:02:10.096: D/ACDB-LOADER(153): ACDB -> ACDB_CMD_GET_AUDPROC_GAIN_DEP_VOLTBL_STEP_COPP
08-21 10:02:10.096: D/ACDB-LOADER(153): ACDB -> AUDIO_SET_AUDPROC_VOL_CAL
08-21 10:02:10.126: W/AudioFlinger(153): write blocked for 459 msecs, 13 delayed writes, thread 0x1d858
08-21 10:02:10.216: E/MP-Decision(293): UP Nw:2.700000 Tw:180 rq:3.277228 seq:201.000000
08-21 10:02:10.256: I/ActivityManager(246): Displayed com.example.game/.MainActivity: +605ms
08-21 10:02:10.266: E/ThermalDaemon(294): Maximum CPU[1] frequency 1512000 KHz
08-21 10:02:12.856: W/KeyCharacterMap(3112): No keyboard for id 65539
08-21 10:02:12.856: W/KeyCharacterMap(3112): Using default keymap: /system/usr/keychars/qwerty.kcm.bin
08-21 10:02:13.126: D/AudioHardwareMSM8660(153): AudioStreamOutMSM72xx::standby()
08-21 10:02:13.126: D/AudioHardwareMSM8660(153): Deroute pcm stream
08-21 10:02:13.136: D/AudioHardwareMSM8660(153): value of device and enable is  0
08-21 10:02:13.736: I/ActivityManager(246): Starting: Intent { cmp=com.example.game/.MainActivity } from pid 3112
08-21 10:02:13.756: E/InputDispatcher(246): channel 'StatusBarView (server)' ~ Consumer closed input channel or an error occurred.  events=0x8
08-21 10:02:13.756: E/InputDispatcher(246): channel 'StatusBarView (server)' ~ Channel is unrecoverably broken and will be disposed!
08-21 10:02:14.546: I/ActivityManager(246): Displayed com.example.game/.MainActivity: +793ms
08-21 10:02:16.676: W/KeyCharacterMap(3112): No keyboard for id 65539
08-21 10:02:16.676: W/KeyCharacterMap(3112): Using default keymap: /system/usr/keychars/qwerty.kcm.bin
08-21 10:02:17.586: I/ActivityManager(246): Starting: Intent { cmp=com.example.game/.MainActivity } from pid 3112
08-21 10:02:17.626: E/InputDispatcher(246): channel 'StatusBarView (server)' ~ Consumer closed input channel or an error occurred.  events=0x8
08-21 10:02:17.626: E/InputDispatcher(246): channel 'StatusBarView (server)' ~ Channel is unrecoverably broken and will be disposed!
08-21 10:02:18.256: I/ActivityManager(246): Displayed com.example.game/.MainActivity: +632ms
08-21 10:02:22.656: W/KeyCharacterMap(3112): No keyboard for id 65539
08-21 10:02:22.656: W/KeyCharacterMap(3112): Using default keymap: /system/usr/keychars/qwerty.kcm.bin
08-21 10:02:23.366: I/ActivityManager(246): Starting: Intent { cmp=com.example.game/.MainActivity } from pid 3112
08-21 10:02:23.386: E/InputDispatcher(246): channel 'StatusBarView (server)' ~ Consumer closed input channel or an error occurred.  events=0x8
08-21 10:02:23.386: E/InputDispatcher(246): channel 'StatusBarView (server)' ~ Channel is unrecoverably broken and will be disposed!
08-21 10:02:24.046: I/ActivityManager(246): Displayed com.example.game/.MainActivity: +662ms
08-21 10:02:25.356: W/KeyCharacterMap(3112): No keyboard for id 65539
08-21 10:02:25.356: W/KeyCharacterMap(3112): Using default keymap: /system/usr/keychars/qwerty.kcm.bin
08-21 10:02:26.006: I/ActivityManager(246): Starting: Intent { cmp=com.example.game/.MainActivity } from pid 3112
08-21 10:02:26.016: E/InputDispatcher(246): channel 'StatusBarView (server)' ~ Consumer closed input channel or an error occurred.  events=0x8
08-21 10:02:26.016: E/InputDispatcher(246): channel 'StatusBarView (server)' ~ Channel is unrecoverably broken and will be disposed!
08-21 10:02:26.626: I/ActivityManager(246): Displayed com.example.game/.MainActivity: +609ms
08-21 10:02:28.386: W/KeyCharacterMap(3112): No keyboard for id 65539
08-21 10:02:28.386: W/KeyCharacterMap(3112): Using default keymap: /system/usr/keychars/qwerty.kcm.bin
08-21 10:02:29.136: I/ActivityManager(246): Starting: Intent { cmp=com.example.game/.MainActivity } from pid 3112
08-21 10:02:29.156: E/InputDispatcher(246): channel 'StatusBarView (server)' ~ Consumer closed input channel or an error occurred.  events=0x8
08-21 10:02:29.156: E/InputDispatcher(246): channel 'StatusBarView (server)' ~ Channel is unrecoverably broken and will be disposed!
08-21 10:02:29.706: I/ActivityManager(246): Displayed com.example.game/.MainActivity: +554ms
08-21 10:02:30.906: E/MP-Decision(293): DOWN Ns:2.100000 Ts:270 rq:2.000000 seq:298.000000
08-21 10:02:33.526: E/MP-Decision(293): UP Nw:2.700000 Tw:180 rq:3.184874 seq:228.000000
08-21 10:02:33.586: E/ThermalDaemon(294): Maximum CPU[1] frequency 1512000 KHz
08-21 10:02:34.016: E/MP-Decision(293): DOWN Ns:2.100000 Ts:270 rq:1.600000 seq:317.000000
08-21 10:02:37.336: I/WindowManager(246): Input event dispatching timed out sending to com.example.game/com.example.game.MainActivity
08-21 10:02:37.476: E/MP-Decision(293): UP Nw:2.700000 Tw:180 rq:2.800000 seq:198.000000
08-21 10:02:37.526: E/ThermalDaemon(294): Maximum CPU[1] frequency 1512000 KHz
08-21 10:02:39.136: W/ActivityManager(246): Launch timeout has expired, giving up wake lock!
08-21 10:02:39.166: W/ActivityManager(246): Activity idle timeout for HistoryRecord{406897a0 com.example.game/.MainActivity}
08-21 10:02:39.606: E/AwesomePlayer(153): AudioPlayer created, Non-LPA mode mime audio/raw duration 3657324
08-21 10:02:39.626: D/AudioHardwareMSM8660(153): write(): dec_id = 1 cur_rx = speaker_stereo_rx
08-21 10:02:39.626: D/AudioHardwareMSM8660(153): value of device and enable is  1
08-21 10:02:39.736: D/ACDB-LOADER(153): ACDB -> send_audio_cal, acdb_id = 15, path =  0
08-21 10:02:39.736: D/ACDB-LOADER(153): ACDB -> send_audtable
08-21 10:02:39.736: D/ACDB-LOADER(153): ACDB -> ACDB_CMD_GET_AUDPROC_COMMON_TABLE
08-21 10:02:39.736: D/ACDB-LOADER(153): ACDB -> AUDIO_SET_AUDPROC_CAL
08-21 10:02:39.736: D/ACDB-LOADER(153): ACDB -> send_audvoltable
08-21 10:02:39.736: D/ACDB-LOADER(153): ACDB -> ACDB_CMD_GET_AUDPROC_GAIN_DEP_VOLTBL_STEP_COPP
08-21 10:02:39.736: D/ACDB-LOADER(153): ACDB -> AUDIO_SET_AUDPROC_VOL_CAL
08-21 10:02:39.756: W/AudioFlinger(153): write blocked for 127 msecs, 14 delayed writes, thread 0x1d858
08-21 10:02:42.336: I/WindowManager(246): Input event dispatching timed out sending to com.example.game/com.example.game.MainActivity
08-21 10:02:43.236: E/ActivityManager(246): ANR in com.example.game (com.example.game/.MainActivity)
08-21 10:02:43.236: E/ActivityManager(246): Reason: keyDispatchingTimedOut
08-21 10:02:43.236: E/ActivityManager(246): Load: 6.36 / 5.3 / 4.17
08-21 10:02:43.236: E/ActivityManager(246): CPU usage from 1683968ms to 1659589ms ago:
08-21 10:02:43.236: E/ActivityManager(246): 68% TOTAL: 22% user + 12% kernel + 33% iowait + 0.1% softirq
08-21 10:02:43.236: E/ActivityManager(246): CPU usage from 312ms to 833ms later:
08-21 10:02:43.236: E/ActivityManager(246):   73% 3112/com.example.game: 67% user + 5.3% kernel / faults: 1 minor
08-21 10:02:43.236: E/ActivityManager(246):     71% 3186/Thread-16: 66% user + 5.3% kernel
08-21 10:02:43.236: E/ActivityManager(246):     1.7% 3118/Binder Thread #: 0% user + 1.7% kernel
08-21 10:02:43.236: E/ActivityManager(246):   36% 246/system_server: 18% user + 18% kernel
08-21 10:02:43.236: E/ActivityManager(246):     25% 254/SurfaceFlinger: 18% user + 7.2% kernel
08-21 10:02:43.236: E/ActivityManager(246):     10% 305/InputDispatcher: 3.6% user + 7.2% kernel
08-21 10:02:43.236: E/ActivityManager(246):     1.8% 256/SurfaceFlinger: 0% user + 1.8% kernel
08-21 10:02:43.236: E/ActivityManager(246):     1.8% 260/GL updater: 1.8% user + 0% kernel
08-21 10:02:43.236: E/ActivityManager(246):     1.8% 451/Binder Thread #: 1.8% user + 0% kernel
08-21 10:02:43.236: E/ActivityManager(246):   2.7% 153/mediaserver: 1.3% user + 1.3% kernel
08-21 10:02:43.236: E/ActivityManager(246):     1.3% 208/Playback Thread: 0% user + 1.3% kernel
08-21 10:02:43.236: E/ActivityManager(246):   1.3% 24/kondemand/0: 0% user + 1.3% kernel
08-21 10:02:43.236: E/ActivityManager(246): 65% TOTAL: 41% user + 12% kernel + 12% iowait
08-21 10:02:43.296: W/KeyCharacterMap(246): No keyboard for id 65539
08-21 10:02:43.296: W/KeyCharacterMap(246): Using default keymap: /system/usr/keychars/qwerty.kcm.bin
08-21 10:02:44.926: W/ActivityManager(246):   Force finishing activity com.example.game/.MainActivity
08-21 10:02:44.926: I/ActivityManager(246): Killing com.example.game (pid=3112): user's request
08-21 10:02:44.936: E/InputDispatcher(246): channel 'StatusBarView (server)' ~ Consumer closed input channel or an error occurred.  events=0x8
08-21 10:02:44.936: E/InputDispatcher(246): channel 'StatusBarView (server)' ~ Channel is unrecoverably broken and will be disposed!
08-21 10:02:44.986: I/ActivityManager(246): Process com.example.game (pid 3112) has died.
08-21 10:02:44.986: I/WindowManager(246): WIN DEATH: Window{40713fd8 SurfaceView paused=false}
08-21 10:02:44.986: E/InputDispatcher(246): channel '408161d0 com.example.game/com.example.game.MainActivity (server)' ~ Consumer closed input channel or an error occurred.  events=0x8
08-21 10:02:44.986: E/InputDispatcher(246): channel '408161d0 com.example.game/com.example.game.MainActivity (server)' ~ Channel is unrecoverably broken and will be disposed!
08-21 10:02:44.996: I/WindowManager(246): WIN DEATH: Window{408a9ec0 SurfaceView paused=false}
08-21 10:02:44.996: I/WindowManager(246): WIN DEATH: Window{408161d0 com.example.game/com.example.game.MainActivity paused=true}
08-21 10:02:44.996: E/InputDispatcher(246): channel '407025d0 com.example.game/com.example.game.MainActivity (server)' ~ Consumer closed input channel or an error occurred.  events=0x8
08-21 10:02:44.996: E/InputDispatcher(246): channel '407025d0 com.example.game/com.example.game.MainActivity (server)' ~ Channel is unrecoverably broken and will be disposed!
08-21 10:02:44.996: I/WindowManager(246): WIN DEATH: Window{407025d0 com.example.game/com.example.game.MainActivity paused=false}
08-21 10:02:45.026: W/InputManagerService(246): Got RemoteException sending setActive(false) notification to pid 3112 uid 10038
08-21 10:02:45.806: E/MP-Decision(293): DOWN Ns:2.100000 Ts:270 rq:1.062893 seq:278.000000
08-21 10:02:47.966: D/AudioHardwareMSM8660(153): AudioStreamOutMSM72xx::standby()
08-21 10:02:47.966: D/AudioHardwareMSM8660(153): Deroute pcm stream
08-21 10:02:47.966: D/AudioHardwareMSM8660(153): value of device and enable is  0
08-21 10:02:49.176: W/ActivityManager(246): Activity destroy timeout for HistoryRecord{405a9638 com.example.game/.MainActivity}

Here’s my XML.





    

    

    

    

    


Here’s my MainActivity.

public class MainActivity extends Activity {

    /* Variables are declared here */       

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);      

        /* Variables are initialized here */

        mGameView = (GameView) findViewById(R.id.mGameView);

        findViewById(R.id.submitButton).setOnClickListener(buttonListener);
        findViewById(R.id.resetButton).setOnClickListener(buttonListener);

        // TextViews for displaying Score and Timer
        tvScore = (TextView) findViewById(R.id.totalScore);
        tvTimer = (TextView) findViewById(R.id.timer);          
    }   

    @Override
    protected void onDestroy() {
        super.onDestroy();
        /* Garbage collection by unbindDrawables() here */
        System.gc();
    }

    //---------------------------
    // Option menu
    //---------------------------
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        menu.add(1, 1, 0, "New Game");
        menu.add(1, 2, 0, "Quit Game");
        return true;
    }

    //---------------------------
    // onOptions ItemSelected
    //---------------------------
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case 1:
            Intent intentNewGame = new Intent(MainActivity.this,
                                   MainActivity.class);
            MainActivity.this.startActivity(intentNewGame);
            finish();
            break;
        case 2:
            /* Quits game here */
            break;
        }
        return true;
    }

    //---------------------------------------------
    // buttonListener()
    //---------------------------------------------
    private OnClickListener buttonListener = new OnClickListener() {
        @Override
        public void onClick(View v) {
            int id = v.getId();
            if (id == R.id.submitButton) {
                mGameView.submit = true;
            } else if (id == R.id.resetButton) {
                mGameView.reset = true;
            }   
        }
    };

    //---------------------------------------------
    // SetTotalScore()
    //---------------------------------------------
    public void SetTotalScore(final int totalScore) {
        final String score = "" + totalScore + " points";
        MainActivity.this.runOnUiThread(new Runnable() {
            public void run() {
                tvScore.setText(score); 
            }
        });
    }

    //---------------------------------------------
    // SetTimer()
    //---------------------------------------------
    public void SetTimer(final String timer, final int time) {
        MainActivity.this.runOnUiThread(new Runnable() {
            public void run() {             
                if (time