Question

in my apps, i'm using tabview. inside one of the tab i implement a refresh function such as:

private final Runnable r = new Runnable() {
    public void run() {
        mVar = true;
        while (mVar == true){
            calculateResult();
            //refresh();

            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }
    }
};
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    handler.removeCallbacks(r);
    setContentView(R.layout.result_view);
    refresh();
    setBackGround();
}
public void refresh() {
    new Thread(r).start();
    //handler.postDelayed(r, 1000);
}

i already try using handler.removeCallbacks(r); in order to stop the handler to repeat it self or so what i believe. but the system just crash when i start it.

here is my error log:

04-23 01:14:20.234: D/dalvikvm(14753): GC_EXTERNAL_ALLOC freed 53K, 47% free 2868K/5379K, external 0K/0K, paused 37ms
04-23 01:14:20.265: D/ATRecorder(14753): com.htc.autotest.dlib.RecordEngine in loader dalvik.system.DexClassLoader@405178e8
04-23 01:14:20.275: D/WindowManagerImpl(14753): addView, new view, mViews[0]: com.android.internal.policy.impl.PhoneWindow$DecorView@40523840
04-23 01:14:23.368: D/dalvikvm(14753): GC_EXTERNAL_ALLOC freed 17K, 47% free 2901K/5379K, external 1151K/1663K, paused 23ms
04-23 01:14:23.518: D/dalvikvm(14753): GC_EXTERNAL_ALLOC freed 86K, 45% free 2960K/5379K, external 2320K/2875K, paused 24ms
04-23 01:14:23.678: D/dalvikvm(14753): GC_EXTERNAL_ALLOC freed 3K, 45% free 2961K/5379K, external 8073K/10082K, paused 25ms
04-23 01:14:23.798: D/ATRecorder(14753): com.htc.autotest.dlib.RecordEngine in loader dalvik.system.DexClassLoader@4053b728
04-23 01:14:23.878: D/dalvikvm(14753): GC_EXTERNAL_ALLOC freed 10K, 45% free 2969K/5379K, external 13845K/15875K, paused 28ms
04-23 01:14:23.898: D/ATRecorder(14753): com.htc.autotest.dlib.RecordEngine in loader dalvik.system.DexClassLoader@40531240
04-23 01:14:23.908: D/WindowManagerImpl(14753): addView, new view, mViews[1]: com.android.internal.policy.impl.PhoneWindow$DecorView@40512848
04-23 01:14:24.108: W/dalvikvm(14753): threadid=10: thread exiting with uncaught exception (group=0x4001d5a0)
04-23 01:14:24.108: E/AndroidRuntime(14753): FATAL EXCEPTION: Thread-11
04-23 01:14:24.108: E/AndroidRuntime(14753): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
04-23 01:14:24.108: E/AndroidRuntime(14753):    at android.view.ViewRoot.checkThread(ViewRoot.java:3165)
04-23 01:14:24.108: E/AndroidRuntime(14753):    at android.view.ViewRoot.requestLayout(ViewRoot.java:677)
04-23 01:14:24.108: E/AndroidRuntime(14753):    at android.view.View.requestLayout(View.java:8507)
04-23 01:14:24.108: E/AndroidRuntime(14753):    at android.view.View.requestLayout(View.java:8507)
04-23 01:14:24.108: E/AndroidRuntime(14753):    at android.view.View.requestLayout(View.java:8507)
04-23 01:14:24.108: E/AndroidRuntime(14753):    at android.view.View.requestLayout(View.java:8507)
04-23 01:14:24.108: E/AndroidRuntime(14753):    at android.view.View.requestLayout(View.java:8507)
04-23 01:14:24.108: E/AndroidRuntime(14753):    at android.view.View.requestLayout(View.java:8507)
04-23 01:14:24.108: E/AndroidRuntime(14753):    at android.view.View.requestLayout(View.java:8507)
04-23 01:14:24.108: E/AndroidRuntime(14753):    at android.view.View.requestLayout(View.java:8507)
04-23 01:14:24.108: E/AndroidRuntime(14753):    at android.view.View.requestLayout(View.java:8507)
04-23 01:14:24.108: E/AndroidRuntime(14753):    at android.widget.ImageView.setImageDrawable(ImageView.java:330)
04-23 01:14:24.108: E/AndroidRuntime(14753):    at android.widget.ImageView.setImageBitmap(ImageView.java:344)
04-23 01:14:24.108: E/AndroidRuntime(14753):    at com.FYP.indoorGPS.TouchImageView.setImageBitmap(TouchImageView.java:153)
04-23 01:14:24.108: E/AndroidRuntime(14753):    at com.FYP.indoorGPS.MapActivity.drawMap(MapActivity.java:163)
04-23 01:14:24.108: E/AndroidRuntime(14753):    at com.FYP.indoorGPS.MapActivity$1.run(MapActivity.java:31)
04-23 01:14:24.108: E/AndroidRuntime(14753):    at java.lang.Thread.run(Thread.java:1027)
04-23 01:14:24.379: D/WindowManagerImpl(14753): finishRemoveViewLocked, mViews[0]: com.android.internal.policy.impl.PhoneWindow$DecorView@40523840
04-23 01:14:24.419: D/WindowManagerImpl(14753): finishRemoveViewLocked, mViews[0]: com.android.internal.policy.impl.PhoneWindow$DecorView@40512848
04-23 01:14:26.030: D/Process(14753): killProcess, pid=14753

can anyone tell me what should i do?

Was it helpful?

Solution

I'm guessing the issue is that your Runnable "r" is still running even after removeCallbacks(). removeCallbacks() doesn't stop a running Runnable, it just keeps it from getting started.

Also, your refresh() calls "r" again, so it will be called indefinitely. So, if removeCallbacks() is called while "r" is running, you have no code to stop "r" and it will loop forever.

A solution would to have a loop in your Runnable and call Thread.sleep() at the end of each loop. Then simply end the loop to stop the Runnable.

For example, in your Runnable:

public void run() {
    mVar = true;
    while (mVar == true){
        //do stuff
        Thread.sleep(2000);
    }

}

Let mVar be a static variable that you can set to false to end the loop.

Also, I would suggest not running this Runnable on the UI thread, as it will likely cause your app to stop responding during the Thread.sleep(2000) method. You could use the following:

new Thread(r).start();

EDIT: If you are going to be handling Views in your Runnable, then the code that handles the views must be run from the UI thread. So, any code altering your views from a runnable needs to be called via a handler.

OTHER TIPS

I think using Handler is better solution rather then Thread. See below code, it should work. I assume that mVar is a controlled variable, that is going to be set as false to stop handler.

private final Runnable r = new Runnable() {
    public void run() {
        if (mVar) {
            calculateResult();
            handler.postDelayed(this, 2000);
        }
    }
};

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    handler.removeCallbacks(r);
    setContentView(R.layout.result_view);
    refresh();
    setBackGround();
}

public void refresh() {
    handler.postDelayed(r, 1000);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top