AsyncTask иногда вылетает - PullRequest
       22

AsyncTask иногда вылетает

0 голосов
/ 14 октября 2011

Одна из моих основных задач 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)

Ответы [ 3 ]

5 голосов
/ 14 октября 2011

Вы не можете манипулировать пользовательским интерфейсом из других потоков.И я вижу, что вы вызываете mProgressBar.setMax(delayTime - 1); внутри метода doInBackground (), который выполняется в фоновом потоке.Это вызовет проблемы.Вы должны переместить этот код внутри onPreExecute () или другого метода.

3 голосов
/ 15 октября 2011

Метод doInBackground AsyncTask выполняется в отдельном потоке. Методы onPreExecute и onPostExecute выполняются в потоке пользовательского интерфейса. Вы можете манипулировать элементами пользовательского интерфейса, только если вы находитесь в потоке пользовательского интерфейса. Если вы хотите манипулировать пользовательским интерфейсом из 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. Вы можете использовать его, как я написал, только если вы объявите класс AsyncTask внутри своей Activity. Если он объявлен вне класса Activity, вы можете передать ссылку на Activity в конструкторе AsyncTask, чтобы использовать его для вызова 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 голосов
/ 18 апреля 2013

Я думаю, что проблема здесь (помимо попыток манипулировать пользовательским интерфейсом из неосновного потока, что, конечно, неправильно) лежит в устройстве Samsung S2: пожалуйста, посмотрите на это .

...