2011-10-14 6 views
0

내 주 AsyncTask 중 하나가 가끔 충돌하는 것 같습니다 (진행률 표시 줄이 멈추고 프로세스가 멈 춥니 다). 내 코드에서 뭔가 잘못되어 있는지 궁금해했습니다.AsyncTask가 때때로 충돌합니다

내 갤럭시 S2가 배터리 부족으로 작동하기 시작한 것처럼 보일 수 있습니다. 밝기 조절에 관한 일부 오류와 일치하는 것으로 보입니다. 이것이 오류의 원인인지 또는 오류의 결과인지 여부는 내가 결정할 수 없었던 것입니다. 또한 배터리가 항상 부족한 것처럼 보이기 때문에 이와 관련되지 않을 수도 있습니다!

내가이 AsyncTask에서 잘못하고있는 것이 있습니까? 실제로 처리기로 실제 컴퓨터를 실행하기 전에 AsyncTask를 사용하여 3 개의 진행 막대 (컴퓨터 플레이어) 중 하나를 표시합니다.

이 또한 Android 마켓에서보고 된 적이 없습니다. InterruptedException으로 인해 발생하는 경우 스택 추적을 인쇄하여 최종 사용자가 발생할 때 사용자 오류가 발생해야합니까?

//Declaration at top level of activity 
private ComputerPlayerTask mComputerPlayerTask = new ComputerPlayerTask(); 


// Execution of the task with a random integer value 
mComputerPlayerTask = new ComputerPlayerTask();   
mComputerPlayerTask.execute(randomInt); 

private class ComputerPlayerTask extends 
     AsyncTask<Integer, Integer, Boolean> { 

    private ProgressBar mProgressBar; 


    @Override 
    protected Boolean doInBackground(Integer... params) { 
     int delayTime = params[0]; 

     mProgressBar.setMax(delayTime - 1); 

     for (int i = 0; i < delayTime; i++) { 
      try { 
       Thread.sleep(500); 
      } catch (InterruptedException e) { 
       Log.e(DEBUG_TAG, "Can't sleep thread"); 
      } 
      if (mPause) { 
       i--; 
      } else { 
       publishProgress(1); 
      } 
     } 
     return true; 
    } 

    @Override 
    protected void onPostExecute(Boolean result) { 
     mProgressBar.setVisibility(View.INVISIBLE); 
     mMainHandler.sendEmptyMessage(WHAT_COMPUTER_TURN); 
     super.onPostExecute(result); 
    } 

    @Override 
    protected void onPreExecute() { 
     mProgressBar = (ProgressBar) findViewById(playerProgressBarMap 
       .get(Player.getCurrentPlayer())); 
     mProgressBar.setProgress(0); 
     if (!mSpeedUp) { 
      mProgressBar.setVisibility(View.VISIBLE); 
     } 
    } 

    @Override 
    protected void onCancelled() { 
     Log.i(DEBUG_TAG, "onCancelled"); 
     mProgressBar.setVisibility(View.INVISIBLE); 
    } 

    @Override 
    protected void onProgressUpdate(Integer... values) { 
     mProgressBar.incrementProgressBy(values[0]); 
    } 

} 

마침내이 문제에 대한 보고서를 얻었습니다. AsyncTasks가 모두 기다리고있는 것을 볼 수 있습니다. 다니엘과 비토가 진술 한 바와 같이 진도 막대기의 내구를 놓아서 이것이 원인 일 수 있었거나 다른 무언가가 틀린가?

DALVIK THREADS: 
(mutexes: tll=0 tsl=0 tscl=0 ghl=0 hwl=0 hwll=0) 
"main" prio=5 tid=1 NATIVE 
    | group="main" sCount=1 dsCount=0 obj=0x400281b8 self=0xcec0 
    | sysTid=19207 nice=0 sched=0/0 cgrp=default handle=-1345006496 
    | schedstat=(108745487102 22285195732 39534) 
    at android.media.SoundPool.play(Native Method) 
    at com.bazsoft.yaniv.SoundManager.playSound(SoundManager.java:83) 
    at com.bazsoft.yaniv.YanivGameActivity.displayPileCards(YanivGameActivity.java:551) 
    at com.bazsoft.yaniv.YanivGameActivity.displayCards(YanivGameActivity.java:506) 
    at com.bazsoft.yaniv.YanivGameActivity.access$6(YanivGameActivity.java:500) 
    at com.bazsoft.yaniv.YanivGameActivity$ComputerHandler.handleMessage(YanivGameActivity.java:111) 
    at android.os.Handler.dispatchMessage(Handler.java:99) 
    at android.os.Looper.loop(Looper.java:123) 
    at android.app.ActivityThread.main(ActivityThread.java:3691) 
    at java.lang.reflect.Method.invokeNative(Native Method) 
    at java.lang.reflect.Method.invoke(Method.java:507) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:847) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:605) 
    at dalvik.system.NativeStart.main(Native Method) 

"AsyncTask #5" prio=5 tid=14 WAIT 
    | group="main" sCount=1 dsCount=0 obj=0x40573f38 self=0x27bca0 
    | sysTid=19282 nice=10 sched=0/0 cgrp=bg_non_interactive handle=2118216 
    | schedstat=(101862790 1754080269 477) 
    at java.lang.Object.wait(Native Method) 
    - waiting on <0x4052b1a8> (a java.lang.VMThread) 
    at java.lang.Thread.parkFor(Thread.java:1424) 
    at java.lang.LangAccessImpl.parkFor(LangAccessImpl.java:48) 
    at sun.misc.Unsafe.park(Unsafe.java:337) 
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:157) 
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2016) 
    at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:411) 
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1021) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1081) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581) 
    at java.lang.Thread.run(Thread.java:1019) 

"AsyncTask #4" prio=5 tid=13 WAIT 
    | group="main" sCount=1 dsCount=0 obj=0x40584508 self=0x27b8c0 
    | sysTid=19278 nice=10 sched=0/0 cgrp=bg_non_interactive handle=2712376 
    | schedstat=(45122127 1293929987 198) 
    at java.lang.Object.wait(Native Method) 
    - waiting on <0x40584668> (a java.lang.VMThread) 
    at java.lang.Thread.parkFor(Thread.java:1424) 
    at java.lang.LangAccessImpl.parkFor(LangAccessImpl.java:48) 
    at sun.misc.Unsafe.park(Unsafe.java:337) 
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:157) 
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2016) 
    at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:411) 
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1021) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1081) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581) 
    at java.lang.Thread.run(Thread.java:1019) 

"AsyncTask #3" prio=5 tid=12 WAIT 
    | group="main" sCount=1 dsCount=0 obj=0x4056ffb8 self=0x27b378 
    | sysTid=19271 nice=10 sched=0/0 cgrp=bg_non_interactive handle=1318248 
    | schedstat=(50782335 1392327423 217) 
    at java.lang.Object.wait(Native Method) 
    - waiting on <0x405700e8> (a java.lang.VMThread) 
    at java.lang.Thread.parkFor(Thread.java:1424) 
    at java.lang.LangAccessImpl.parkFor(LangAccessImpl.java:48) 
    at sun.misc.Unsafe.park(Unsafe.java:337) 
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:157) 
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2016) 
    at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:411) 
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1021) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1081) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581) 
    at java.lang.Thread.run(Thread.java:1019) 

"AsyncTask #2" prio=5 tid=11 WAIT 
    | group="main" sCount=1 dsCount=0 obj=0x4057aa50 self=0x2b08b8 
    | sysTid=19266 nice=10 sched=0/0 cgrp=bg_non_interactive handle=2107320 
    | schedstat=(47150870 1245297244 204) 
    at java.lang.Object.wait(Native Method) 
    - waiting on <0x4057ab80> (a java.lang.VMThread) 
    at java.lang.Thread.parkFor(Thread.java:1424) 
    at java.lang.LangAccessImpl.parkFor(LangAccessImpl.java:48) 
    at sun.misc.Unsafe.park(Unsafe.java:337) 
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:157) 
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2016) 
    at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:411) 
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1021) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1081) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581) 
    at java.lang.Thread.run(Thread.java:1019) 

"AsyncTask #1" prio=5 tid=10 WAIT 
    | group="main" sCount=1 dsCount=0 obj=0x4057e3e0 self=0x225e60 
    | sysTid=19260 nice=10 sched=0/0 cgrp=bg_non_interactive handle=2252696 
    | schedstat=(47511668 1323908745 205) 
    at java.lang.Object.wait(Native Method) 
    - waiting on <0x4057e5b8> (a java.lang.VMThread) 
    at java.lang.Thread.parkFor(Thread.java:1424) 
    at java.lang.LangAccessImpl.parkFor(LangAccessImpl.java:48) 
    at sun.misc.Unsafe.park(Unsafe.java:337) 
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:157) 
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2016) 
    at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:411) 
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1021) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1081) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581) 
    at java.lang.Thread.run(Thread.java:1019) 

"SoundPoolThread" prio=5 tid=9 NATIVE 
    | group="main" sCount=1 dsCount=0 obj=0x40513680 self=0x188e38 
    | sysTid=19234 nice=0 sched=0/0 cgrp=default handle=1798920 
    | schedstat=(4164749 2002043 34) 
    at dalvik.system.NativeStart.run(Native Method) 

"SoundPool" prio=5 tid=8 NATIVE 
    | group="main" sCount=1 dsCount=0 obj=0x40518668 self=0x188d00 
    | sysTid=19233 nice=0 sched=0/0 cgrp=default handle=1799064 
    | schedstat=(154125 0 1) 
    at dalvik.system.NativeStart.run(Native Method) 

"Binder Thread #2" prio=5 tid=7 NATIVE 
    | group="main" sCount=1 dsCount=0 obj=0x4051e608 self=0x8ad90 
    | sysTid=19213 nice=0 sched=0/0 cgrp=default handle=1104984 
    | schedstat=(7442210 75731553 65) 
    at dalvik.system.NativeStart.run(Native Method) 

"Binder Thread #1" prio=5 tid=6 NATIVE 
    | group="main" sCount=1 dsCount=0 obj=0x4051ca20 self=0x10cf90 
    | sysTid=19212 nice=0 sched=0/0 cgrp=default handle=1098888 
    | schedstat=(8834252 62834840 68) 
    at dalvik.system.NativeStart.run(Native Method) 

"Compiler" daemon prio=5 tid=5 VMWAIT 
    | group="system" sCount=1 dsCount=0 obj=0x405189a0 self=0x10c978 
    | sysTid=19211 nice=0 sched=0/0 cgrp=default handle=1105168 
    | schedstat=(826648662 443778935 3811) 
    at dalvik.system.NativeStart.run(Native Method) 

"Signal Catcher" daemon prio=5 tid=4 RUNNABLE 
    | group="system" sCount=0 dsCount=0 obj=0x405188e0 self=0x10c810 
    | sysTid=19210 nice=0 sched=0/0 cgrp=default handle=1093320 
    | schedstat=(2793168 631667 8) 
    at dalvik.system.NativeStart.run(Native Method) 

"GC" daemon prio=5 tid=3 VMWAIT 
    | group="system" sCount=1 dsCount=0 obj=0x40518838 self=0x10c6a0 
    | sysTid=19209 nice=0 sched=0/0 cgrp=default handle=1097888 
    | schedstat=(40991755 61721634 20) 
    at dalvik.system.NativeStart.run(Native Method) 

"HeapWorker" daemon prio=5 tid=2 VMWAIT 
    | group="system" sCount=1 dsCount=0 obj=0x40518780 self=0x10c538 
    | sysTid=19208 nice=0 sched=0/0 cgrp=default handle=1098528 
    | schedstat=(624790039 112243012 376) 
    at dalvik.system.NativeStart.run(Native Method) 

답변

5

다른 스레드에서 UI를 조작 할 수 없습니다. 그리고 백그라운드 스레드에서 실행되는 doInBackground() 메서드 내에서 mProgressBar.setMax(delayTime - 1); 메서드를 호출하고 있음을 알 수 있습니다. 이로 인해 문제가 발생합니다. onPreExecute() 또는 다른 메서드 내에서이 코드를 이동해야합니다.

+0

감사합니다. Daniel. 백그라운드 스레드에서 UI를 업데이트 할 수 없다는 것을 알았지 만 오류를 발생시키지 않았고 나쁜 점을 보이지 않았기 때문에 진행 막대의 길이를 업데이트하면 이런 식으로 영향을 미칠 수 있다고 생각조차하지 않았습니다. –

+0

다른 스레드에서 UI를 업데이트한다고해서 항상 예외가 발생하는 것은 아닙니다 (Android에서는 예외를 거의 발생시키지 않지만, 예를 들어 .NET에서는 즉시 런타임 예외가 발생합니다). 스레드는 UI 구성 요소에 액세스하면 멈추거나 멈출 수 있습니다. –

+0

질문에 대한 답변이 나옵니까? 답변으로 표시 할 수 있습니까? 고맙습니다 :-). –

3

AsyncTask의 doInBackground 메서드는 분리 된 스레드에서 실행됩니다. onPreExecuteonPostExecute 메서드는 UI 스레드에서 실행됩니다. UI 스레드에있는 경우에만 UI 요소를 조작 할 수 있습니다.

@Override 
protected Boolean doInBackground(Integer... params) { 
    int delayTime = params[0]; 

    runOnUiTread(new Runnable() { 
     @Override 
     public void run() { 
      mProgressBar.setMax(delayTime - 1); 
     } 
    }); 

    for (int i = 0; i < delayTime; i++) { 
     try { 
      Thread.sleep(500); 
     } catch (InterruptedException e) { 
      Log.e(DEBUG_TAG, "Can't sleep thread"); 
     } 
     if (mPause) { 
      i--; 
     } else { 
      publishProgress(1); 
     } 
    } 
    return true; 
} 

runOnUiThread()이 활동 클래스의 방법이다 : 당신이 AsyncTask.doInBackground에서 UI를 조작하려면 , 당신은 runOnUiThread 방법을 사용해야합니다. 액티비티 안에 AsyncTask 클래스를 선언 한 경우에만 필자는이 스크립트를 사용할 수 있습니다. 이 액티비티 클래스에서 밖으로 선언하는 경우, 당신은 내가 떨어져에서 UI를 조작하는 시도에서 (여기에 문제를 생각 runOnUiThread()

public class MyAsyncTask extends AsyncTask { 
    Activity a; 

    public MyAsyncTask(Activity a) { 
     this.a = a; 
    } 

    ... 

    @Override 
    protected Boolean doInBackground(Integer... params) { 
     int delayTime = params[0]; 

     a.runOnUiTread(new Runnable() { 
      @Override 
      public void run() { 
       mProgressBar.setMax(delayTime - 1); 
      } 
     }); 

     ... 
    } 

    ... 
} 
+0

감사합니다. Vito. 내 AsyncTask는 기본 액티비티 내의 비공개 클래스이므로 별도로 액티비티를 보낼 필요는 없지만 멋지게 보입니다. –

0

전화를 사용하여 들어, AsyncTask를의 생성자에서 활동에 대한 참조를 전달할 수 있습니다 비 주 스레드, 당연히 틀린) 삼성 S2 장치에 낳는다 : this를 보아라.

관련 문제