d e p u b l i c v o i d o n C r e a t e ( B u n d l e s a v e d I n s t a n c e S t a t e ) { s u p e r . o n C r e a t e ( s a v e d I n s t a n c e S t a t e ) ; . . . n e w A s y n c T a s k < V o i d , S t r i n g , V o i d > ( ) { @ O v e r r i d e p r o t e c t e d v o i d o n P r e E x e c u t e ( ) { s u p e r . o n P r e E x e c u t e ( ) ; m P r o g r e s s D i a l o g . s h o w ( ) ; } @ O v e r r i d e p r o t e c t e d S t r i n g d o I n B a c k g r o u n d ( V o i d . . . v a l u e ) { t r y { T h r e a d . s l e e p ( 1 5 0 0 0 ) ; } c a t c h ( I n t e r r u p t e d E x c e p t i o n e ) { } r e t u r n " A s y n c T a s k D o n e " ; } @ O v e r r i d e p r o t e c t e d v o i d o n P o s t E x e c u t e ( S t r i n g r e s u l t ) { m P r o g r e s s D i a l o g . d i s m i s s ( ) ; m T e x t V i e w . s e t T e x t ( r e s u l t ) ; } } . e x e c u t e ( ) ;
detach されるので m P r o g r e s s D i a l o g . d i s m i s s ( ) で I l l e g a l A r g u m e n t E x c e p t i o n が発生する。 ウェブの記事では、画面固定を推奨しているものもあるが、 画面回転以外(キーボードの表示とか)にも Configuration Change は起き得るので、これではダメ。
o y 時にダイアログを閉じて n u l l にしておく @ O v e r r i d e p u b l i c v o i d o n C r e a t e ( B u n d l e s a v e d I n s t a n c e S t a t e ) { . . . n e w A s y n c T a s k < V o i d , V o i d , S t r i n g > ( ) { . . . @ O v e r r i d e p r o t e c t e d v o i d o n P o s t E x e c u t e ( S t r i n g r e s u l t ) { i f ( m P r o g r e s s D i a l o g ! = n u l l ) { m P r o g r e s s D i a l o g . d i s m i s s ( ) ; } i f ( m T e x t V i e w ! = n u l l ) { m T e x t V i e w . s e t T e x t ( r e s u l t ) ; } } } . e x e c u t e ( ) ; } @ O v e r r i d e p u b l i c v o i d o n D e s t r o y ( ) { i f ( m P r o g r e s s D i a l o g ! = n u l l & & m P r o g r e s s D i a l o g . i s S h o w i n g ( ) ) { m P r o g r e s s D i a l o g . d i s m i s s ( ) ; } m P r o g r e s s D i a l o g = n u l l ; } というか、ガイドライン通り、ProgressDialog は使わない!
t # g e t A c t i v i t y ( ) が n u l l になることがある 画面回転などで Configuration Chage が発生すると、Fragment が detach されてしまう @ O v e r r i d e p u b l i c V i e w o n C r e a t e V i e w ( L a y o u t I n f l a t e r i n f l a t e r , V i e w G r o u p c o n t a i n e r , B u n d l e s a v e d I n s t a n c e S t a t e ) { . . . n e w A s y n c T a s k < V o i d , V o i d , S t r i n g [ ] > ( ) { . . . @ O v e r r i d e p r o t e c t e d v o i d o n P o s t E x e c u t e ( S t r i n g [ ] r e s u l t ) { m A d a p t e r = n e w A r r a y A d a p t e r < S t r i n g > ( g e t A c t i v i t y ( ) , R . l a y o u t . l i s t r o w , r e s u m L i s t V i e w . s e t A d a p t e r ( m A d a p t e r ) ; } } . e x e c u t e ( ) ; }
# i s A d d e d ( ) で確認する あと、個人的には m A d a p t e r はコールバックで作らない方 が好き @ O v e r r i d e p u b l i c V i e w o n C r e a t e V i e w ( L a y o u t I n f l a t e r i n f l a t e r , V i e w G r o u p c o n t a i n e r , B u n d l e s a v e d I n s t a n c e S t a t e ) { . . . n e w A s y n c T a s k < V o i d , V o i d , S t r i n g [ ] > ( ) { . . . @ O v e r r i d e p r o t e c t e d v o i d o n P o s t E x e c u t e ( S t r i n g [ ] r e s u l t ) { i f ( i s A d d e d ( ) & & m A d a p t e r ! = n u l l ) { m A d a p t e r . a d d A l l ( A r r a y s . a s L i s t ( r e s u l t ) ) ; m A d a p t e r . n o t i f y D a t a s e t C h a n g e d ( ) ; } } } . e x e c u t e ( ) ; }
e w A s y n c T a s k < V o i d , S t r i n g , V o i d > ( ) { . . . } . e x e c u t e ( ) ; non-static な内部クラスは暗黙に親オブジェクト(Activity オブジェクト)への参照を持っている AsyncTask が内部的に利用しているスレッドが生きている 限り、このオブジェクトは GC されない 出典: Efficient Android Threading
i t y # o n D e s t o r y ( ) 時に Activity への参照を破棄し て A s y n c T a s k # c a n c e l ( ) を呼ぶ もしくは、Activity への参照を弱参照(Weak Reference) にする @ O v e r r i d e p u b l i c v o i d o n C r e a t e ( B u n d l e s a v e d I n s t a n c e S t a t e ) { . . . m T a s k = n e w M y T a s k ( t h i s ) ; m T a s k . e x e c u t e ( ) ; } @ O v e r r i d e p r o t e c t e d v o i d o n D e s t r o y ( ) { s u p e r . o n D e s t r o y ( ) ; m T a s k . s e t A c t i v i t y ( n u l l ) ; m T a s k . c a n c e l ( t r u e ) ; } p r i v a t e s t a t i c c l a s s M y T a s k e x t e n d s A s y n c T a s k < S t r i n g , B i t m a p , V o i d > { . . . }
# c a n c e l ( f a l s e ) は、i s C a n c e l e d をt r u e に セットして、実行中のタスクが終わるまで待機する。 A s y n c T a s k # c a n c e l ( t r u e ) にしても、即座にスレッドが 終了することを保証しない。 p r i v a t e s t a t i c c l a s s M y T a s k e x t e n d s A s y n c T a s k < V o i d , V o i d , S t r i n g > { @ O v e r r i d e p r o t e c t e d S t r i n g d o I n B a c k g r o u n d ( V o i d . . . p a r a m s ) { f o r ( i n t i = 0 ; i < N U M _ T A S K S ; i + + ) { i f ( t h i s . i s C a n c e l l e d ( ) ) { r e t u r n n u l l ; } e l s e { t r y { / / D o a n y t a s k } c a t c h ( I n t e r r u p t e d E x c e p t i o n i e x ) { / / t h e b l o c k i n g m e t h o d t h r o w s a n I n t e r r u p t e d E x c e p t i o n r e t u r n n u l l ; } } } r e t u r n " A s y n c T a s k D o n e " ; } }
AsyncTask が別 Activity の AsyncTask をブロックしうる) API targetSdkVersion e x e c u t e e x e c u t e O n E x e c u t o r 1-3 Any Sequential Not available 4-10 Any Concurrent Not available 11-12 Any Concurrent Sequential/Concurrent (customizable) 13+ <13 Concurrent Sequential/Concurrent (customizable) 13+ ≥13 Sequential Sequential/Concurrent (customizable)
a s k を諦めてく ださい。 同時実行 targetSdkVersion を < 13 にするか、API レベルによって処理 を変える必要があります。 i f ( B u i l d . V E R S I O N . S D K _ I N T < = B u i l d . V E R S I O N _ C O D E S . H O N E Y C O M B _ M R 1 ) { n e w M y A s y n c T a s k ( ) . e x e c u t e ( ) ; } e l s e { n e w M y A s y n c T a s k ( ) . e x e c u t e O n E x e c u t o r ( A s y n c T a s k . T H R E A D _ P O O L _ E X E C U T O R ) ; }
k の使い方 軽い処理だけにしておく non-static な inner class にしない A c t i v i t y # o n D e s t r o y ( ) で、キャンセルと Activity の参 照の解放を忘れずに行う 場合に応じて A s y n c T a s k L o a d e r 、 E x e c u t o r 、 H a n d l e r T h r e a d の利用も検討する