Blog16 of GrrrNeko BASE

このコーナーではデベロッパー向けに、私がハマってしまったポイントとその解決法を書いていきます。

2012-10-8

android: 異なるスコープ(ブロック、スレッド)間での値の受け渡し(3) - faction を使う方法 -

症状:

 異なるスコープ(ブロック、スレッド)間での値の受け渡しができない。

 例えば、以下のようなコードを書いたとする。

int = a

final AlertDialog.Builder adb = new AlertDialog.Builder(this);
adb.setMessage("SELECT")
       .setPositiveButton("YES",
                new DialogInterface.OnClickListener() {
                         public void onClick(DialogInterface dialog, int which) {
	                a = 100;
		}
	})
        .setNegativeButton("NO",
	new DialogInterface.OnClickListener() {
	         public void onClick(DialogInterface dialog, int which) {
                                a = 200;
                                }
	})
         .show();

TextView tv = (TextView) findViewById(R.id.textview1);
tv.setText("Result: " + a);

 ここで、はじめの変数 a の宣言を final にすると alertdialog ブロック内の a に値を代入できず、かといって static にすると今度は a が参照できない、と言われてしまう。

  • final にした場合:
    • エンクロージング型に定義されているため final のローカル変数 a を代入することができません
  • static にした場合:
    • 異なるメソッドで定義されたインナー・クラス内で非 final 変数 a を参照できません

解決法:

 私が求めていた本当の解決策は、alertdialog の挙動がおかしいで記したとおりだが、解決策を求めて放浪している間に、異なるスコープ(ブロック、スレッド)間での値の受け渡しと同じ結果になるが異なる方法をいくつか発見した。

 その一つが setFaction で送る方法。

static int a = 0;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
        
    final AlertDialog.Builder adb = new AlertDialog.Builder(this);
    adb.setMessage("SELECT")
        .setPositiveButton("YES",
    	new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
    	setFaction("100");
            }
        })
        .setNegativeButton("NO",
  	new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
    	setFaction("200");
            }
        })
        .show();
}
            
private void setFaction(String faction) {
    a = Integer.parseInt(faction);
    final TextView tv = (TextView) findViewById(R.id.textview1);
    tv.setText("Result: " + a);       	
}

 この方法を見つけた時には、かなり惹かれたし、これはこれで完結しているので使途はあると思うが、私の場合は setFaction メソッドの置き場の問題で残念ながら製品プロジェクトへの実装には至らなかった。
 ところでこの方法は、大黒学 著 ”Android 実習マニュアル” p.60 に掲載されていた例を参考にしたものだが、不思議なことにこの Faction は、Android Developers に出ていない。が、コンパイルも通るし、黄色の波線も含め、エラーの類も一切出ないし、ちゃんと動く。

 「裏ワザ」なのかもしれないが、将来的な互換性を考えると、Android Developers に載っていないものを使用するのはちと汎用性に欠けるのでオススメできない。

ページトップへ