我的一个主要AsyncTasks似乎偶尔崩溃(进度条冻结,进程停止),我想知道我的代码是否出错了。
看起来当我的Galaxy S2开始耗尽电量时可能会发生这种情况 - 这似乎与亮度控制方面的一些错误相吻合。虽然这些是错误的原因还是错误导致的结果是我无法确定的。此外,由于电池似乎总是低电量,这可能甚至没有关联!
我在AsyncTask中做的任何事情是错的吗?我实际上只是在使用处理程序执行实际计算机之前,使用AsyncTask显示三个进度条中的一个(计算机播放器)。
此外,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)
答案 0 :(得分:5)
您无法从其他线程操纵UI。我看到你在doInBackground()方法中调用mProgressBar.setMax(delayTime - 1);
,该方法在后台线程中执行。这会引起问题。您必须在onPreExecute()或其他方法中移动此代码。
答案 1 :(得分:3)
AsyncTask的方法doInBackground
在一个单独的Thread中执行。在UI线程中执行onPreExecute
和onPostExecute
方法。只有在UI线程上才能操作UI元素。
如果您想从AsyncTask.doInBackground
操纵用户界面,则必须使用runOnUiThread
方法:
@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()
是Activity类的一种方法。只有在Activity中声明了AsyncTask类时,才可以使用它。如果从Activity类声明它,您可以在AsyncTask的构造函数中传递对Activity的引用,以便使用它来调用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);
}
});
...
}
...
}
答案 2 :(得分:0)
我认为这里的问题(除了试图从非主线程操纵UI,这当然是错误的)存在于三星S2设备中:请查看this。