android の static 変数 が気持ち悪い

Android_Application_Framework_FAQ___Android_Developers

整理してメモ。

2つの状況。

その1:

static 変数がプロセスに保持されている。

プロセスが生きたままだとと思っていたら死んでいる。

そのアプリを画面に表示したときにプロセス再起動。

static 変数が初期化される。

その2:

static 変数がプロセスに保持されている。

プロセスが死んでいると思ったら生きている。

そのアプリを画面に表示したときに既存プロセス利用。

static 変数は初期化されず、そのまま利用される。

結局、アプリの画面を表示したときにそれが

「再起動されたプロセス(static変数初期化)」なのか
「再利用されたプロセス(保持されたstatic変数)」なのか

をはっきり認識しづらいのが問題。

めんどくさいので雑にいうと

その表示した画面が

「アプリ全体を新しく起動した画面」なのか
「一部しれっと生きてた情報を再利用した画面」なのか

と思ったほうが簡単で直感的なのか。

細かくいうといろいろあるのだろうけども。

極端に、

「アプリプロセスはいつでも死ぬ可能性がある」

ということにしておいて、消えて困る情報はアプリプロセス以外の
場所に保持しておくとよし、と。

Preference・データベース・ファイル…

(singleton がどうのこうのはアプリプロセスあっての)

なんで「static変数」がよく問題になるのかは、AndroidなJava 以外のように

「異なるライフサイクルを持つクラス間で、アプリ内で見通しよく簡単に情報を持ち回りたい」

から。

これには「Applicationクラス」を使う、と。

Applicationクラスを継承して、データの共有をする。 « Tech Booster

AndroidアプリでContextを持ち回したい話 - FLYING

MyAppのstatic変数を使うことで、アクティビティのライフサイクルに影響を受けずに値を保持し続けることができます。
またstaticメソッドを用意することで、アプリ内のどこからでもアクセスすることができます。

各オブジェクトの状態をアプリから監視させたり。

Android - Applicationクラスを使ってObserverパターンを実装する - Qiita

念のためそこら公式ドキュメントをみる。

続きを読む >>


Android API19 (KitKat) で com.android.internal.app.ChooserActivity まわりで leak !?

 

ブラウザからの「共有(share)」がひとつのアプリを固定して、選択できない状態に何回か遭遇。

正常であればこんなかんじのこの画面。

20131116-100144

この画面があたしの場合は表示されずFacebookに固定でインテントされるという現象。

そのときとったログはこれ。

I/ActivityManager(  774): START u0 {act=android.intent.action.CHOOSER flg=0x1 cmp=android/com.android.internal.app.ChooserActivity (has clip) (has extras)} from pid 24582
D/dalvikvm(  774): GC_FOR_ALLOC freed 4732K, 17% free 45594K/54824K, paused 61ms, total 62ms
W/InputMethodManagerService(  774): Window already focused, ignoring focus gain of: com.android.internal.view.IInputMethodClient$Stub$Proxy@437ddc90 attribute=null, token = android.os.BinderProxy@430764a0
I/ActivityManager(  774): START u0 {act=android.intent.action.SEND typ=text/plain flg=0x3000001 cmp=com.facebook.katana/.activity.composer.ImplicitShareIntentHandler (has clip) (has extras)} from pid 24582
I/ActivityManager(  774): START u0 {cmp=com.facebook.katana/.activity.composer.ComposerActivity (has extras)} from pid 28268
W/l       (24582): [TiclService] Ticl being stopped: Client: com.google.protos.ipc.invalidation.ClientProtocol$ApplicationClientIdP@42641e80, \n\006\n\004\010\003\020\001\022\022\t;)\316\032<\326\326\246\021\250EC8\310\262\335\343\032\007\010\201\014\020\003\030\002, <RunState: STARTED>
E/ActivityThread(24582): Activity com.android.internal.app.ChooserActivity has leaked IntentReceiver com.android.internal.app.ResolverActivity$1@42df1160 that was originally registered here. Are you missing a call to unregisterReceiver()?
E/ActivityThread(24582): android.app.IntentReceiverLeaked: Activity com.android.internal.app.ChooserActivity has leaked IntentReceiver com.android.internal.app.ResolverActivity$1@42df1160 that was originally registered here. Are you missing a call to unregisterReceiver()?
E/ActivityThread(24582): 	at android.app.LoadedApk$ReceiverDispatcher.<init>(LoadedApk.java:805)
E/ActivityThread(24582): 	at android.app.LoadedApk.getReceiverDispatcher(LoadedApk.java:606)
E/ActivityThread(24582): 	at android.app.ContextImpl.registerReceiverInternal(ContextImpl.java:1430)
E/ActivityThread(24582): 	at android.app.ContextImpl.registerReceiver(ContextImpl.java:1410)
E/ActivityThread(24582): 	at android.content.ContextWrapper.registerReceiver(ContextWrapper.java:474)
E/ActivityThread(24582): 	at com.android.internal.content.PackageMonitor.register(PackageMonitor.java:91)
E/ActivityThread(24582): 	at com.android.internal.content.PackageMonitor.register(PackageMonitor.java:69)
E/ActivityThread(24582): 	at com.android.internal.app.ResolverActivity.onCreate(ResolverActivity.java:139)
E/ActivityThread(24582): 	at com.android.internal.app.ChooserActivity.onCreate(ChooserActivity.java:53)
E/ActivityThread(24582): 	at android.app.Activity.performCreate(Activity.java:5243)
E/ActivityThread(24582): 	at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
E/ActivityThread(24582): 	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2140)
E/ActivityThread(24582): 	at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2226)
E/ActivityThread(24582): 	at android.app.ActivityThread.access$700(ActivityThread.java:135)
E/ActivityThread(24582): 	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1397)
E/ActivityThread(24582): 	at android.os.Handler.dispatchMessage(Handler.java:102)
E/ActivityThread(24582): 	at android.os.Looper.loop(Looper.java:137)
E/ActivityThread(24582): 	at android.app.ActivityThread.main(ActivityThread.java:4998)
E/ActivityThread(24582): 	at java.lang.reflect.Method.invokeNative(Native Method)
E/ActivityThread(24582): 	at java.lang.reflect.Method.invoke(Method.java:515)
E/ActivityThread(24582): 	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:777)
E/ActivityThread(24582): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:593)
E/ActivityThread(24582): 	at dalvik.system.NativeStart.main(Native Method)
I/ActivityManager(  774): Displayed com.facebook.katana/.activity.composer.ComposerActivity: +198ms (total +453ms)
W/IInputConnectionWrapper(24582): showStatusIcon on inactive InputConnection
D/dalvikvm( 1257): GC_FOR_ALLOC freed 2953K, 19% free 17201K/21156K, paused 13ms, total 13ms
I/dalvikvm-heap( 1257): Grow heap (frag case) to 19.741MB for 2986688-byte allocation
D/dalvikvm( 1257): GC_FOR_ALLOC freed 1K, 17% free 20117K/24076K, paused 13ms, total 13ms
D/dalvikvm( 1257): GC_CONCURRENT freed 18K, 17% free 20104K/24076K, paused 2ms+4ms, total 19ms
W/IdleConnectionHandler(28268): Removing a connection that never existed!
W/MovesProd.c(25181): buffer is empty, nothing to flush
D/dalvikvm( 3437): GC_CONCURRENT freed 403K, 3% free 16539K/16980K, paused 3ms+1ms, total 21ms

ここですよね、これ。

/ActivityThread(24582): Activity com.android.internal.app.ChooserActivity has leaked IntentReceiver com.android.internal.app.ResolverActivity$1@42df1160 that was originally registered here. Are you missing a call to unregisterReceiver()?
E/ActivityThread(24582): android.app.IntentReceiverLeaked: Activity com.android.internal.app.ChooserActivity has leaked IntentReceiver com.android.internal.app.ResolverActivity$1@42df1160 that was originally registered here. Are you missing a call to unregisterReceiver()?

漏れてる。

最近少しネットでこの話出てきています。

続きを読む >>


PHP+MySQLで地図上に情報を集約・共有できるオープンソースなスグレモノ - Ushahidi

 

なんかAndroidでなくWEBチックなタイトルなのですがー。

今回の震災では,いろんな地図的情報共有サイトが乱立したような気がしますがー,

とりあえずー,GoogleMapを利用することが思いついたりしますがー。

 

sinsai.info 東日本大震災 | みんなでつくる復興支援プラットフォーム 

 

こんなサイトで利用されているオープンソースなパッケージがあったりします。

 

 

Ushahidi :: Home 

 

PHP+MySQLで動かせるようです。

 

ushahidi/Ushahidi_Web - GitHub 

 

 

で,WEBパッケージだけではなくて,各スマホ向けソース群も公開されてるわけで。

 

続きを読む >>