3

私のアプリでは、タブビューを使用しています。タブの1つに、次のような更新機能を実装します。

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

私はすでにhandler.removeCallbacks(r);ハンドラーを停止してそれを自分で繰り返すために使用しようとしています。しかし、起動するとシステムがクラッシュします。

これが私のエラーログです:

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

誰かが私に何をすべきか教えてもらえますか?

4

2 に答える 2

1

問題は、実行可能な「r」が。の後でも実行されていることだと思いますremoveCallbacks()removeCallbacks()Runnableの実行を停止するのではなく、開始を妨げるだけです。

また、refresh()もう一度「r」を呼び出すので、無期限に呼び出されます。したがって、removeCallbacks()「r」の実行中にが呼び出された場合、「r」を停止するコードはなく、永久ループになります。

Thread.sleep()解決策は、Runnableにループを作成し、各ループの最後に呼び出すことです。次に、ループを終了してRunnableを停止します。

たとえば、Runnableでは次のようになります。

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

}

mVarを静的変数とし、falseに設定してループを終了します。

また、UIスレッドでこのRunnableを実行しないことをお勧めします。これにより、Thread.sleep(2000)メソッド中にアプリが応答しなくなる可能性があります。次を使用できます。

new Thread(r).start();

編集:Runnableでビューを処理する場合は、ビューを処理するコードをUIスレッドから実行する必要があります。したがって、ランナブルからビューを変更するコードは、ハンドラーを介して呼び出す必要があります。

于 2012-04-22T15:45:16.033 に答える
0

スレッドよりもハンドラーを使用する方が良い解決策だと思います。以下のコードを参照してください、それは動作するはずです。mVarは制御変数であり、ハンドラーを停止するためにfalseとして設定されると想定しています。

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);
}
于 2013-05-24T09:50:14.867 に答える