2012年12月1日土曜日

[Android] Javaのstaticクラス(Handler)から非sataticクラス(Activity)のメソッドを呼び出すには(弱参照)

How to call non-static methods from static classes
Activityの内部にHandlerのインナークラスを作り、一定時間後にActivityを終了するアプリケーションを作ろうとしました。
非同期処理尾のためHandlerクラスを使います。

その1 ※パーミッション不要のためマニフェストは省略します。

このソースのままだとエラーにはなりませんが、「Handlerはstaticにするべき」という警告が出てしまいます。
This Handler class should be static or leaks might occur
リークは起こしたくないのでHandlerをstaticに変更しました。
注意するべき点は、staticで定義したオブジェクトの内容はと異なるインスタンス間で同じ内容になってしまうことです。
ただし、このアプリは1度に一つのActivityしか起動しない仕様のため、Handlerをstaticにしても影響はありません。
というわけでstaticに変更してみました。

その2 今度はエラーになってしまいました。
スコープ内で型 MainActivity のエンクロージング・インスタンスがアクセス不可能です
staticクラスから非staticメソッドにアクセスできないためです。

そこでこの様にしたら解決しました。

その3 (1) staticなActivity(の入れ物)を用意
(2) (1)の内容をActivity自身とする
(3) Acvitityクラスのfinishメソッドを呼び出してActivityを終了する

とりあえずこれで警告やエラーがなく動くようになりました。

もっといい方法はないかと調べたら、WeakReferenceという弱参照オブジェクトがあるのでさらに改善してみました。

その4 (1) WeakReference(弱参照)のAcvitityを用意
(2) (1)の内容をActivity自身とする
(3) Acvitityクラスのfinishメソッドを呼び出してActivityを終了する

これでうまくいきました。

ただし上で書いた通り、staticで定義した変数やインナークラスは異なるインスタンス間で同じ内容になってしまいます。
このMainActivityクラスは1度に一つのインスタンスしか起動しないのでこの方法でうまくいきました。
すべてのJavaアプリケーションで同じ方法が通用するとは限りませんのでご注意ください。

以上、参考になれば幸いです。

関連ブログ
[Android] Activityに時計を表示する(Activityの非同期更新)

2 件のコメント:

  1. 利用させてもらいました。ありがとうございます。

    返信削除
    返信
    1. コメントありがとうございます

      削除