最近のSupport Libraryで(Activity)view.getContext()するとクラッシュするので注意

# 概要
Support Library 24.1.1を利用しようとしてクラッシュしたのでちょっとメモしておきます。


# 何が起こるのか？

```java
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final TextView text = (TextView) findViewById(R.id.text);
        final Activity activity = (Activity)text.getContext();
    }
}

```

ClassCastExceptionでクラッシュする模様

```
java.lang.ClassCastException: android.support.v7.widget.TintContextWrapper cannot be cast to android.app.Activity
   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2646)
   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707)
   at android.app.ActivityThread.-wrap12(ActivityThread.java)
   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460)
   at android.os.Handler.dispatchMessage(Handler.java:102)
   at android.os.Looper.loop(Looper.java:154)
   at android.app.ActivityThread.main(ActivityThread.java:6077)
   at java.lang.reflect.Method.invoke(Native Method)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
Caused by: java.lang.ClassCastException: android.support.v7.widget.TintContextWrapper cannot be cast to android.app.Activity
   at com.github.takahirom.myapplication.MainActivity.onCreate(MainActivity.java:16)
   at android.app.Activity.performCreate(Activity.java:6664)
   at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2599)
   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707) 
   at android.app.ActivityThread.-wrap12(ActivityThread.java) 
   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460) 
   at android.os.Handler.dispatchMessage(Handler.java:102) 
   at android.os.Looper.loop(Looper.java:154) 
   at android.app.ActivityThread.main(ActivityThread.java:6077) 
   at java.lang.reflect.Method.invoke(Native Method) 
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865) 
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755) 

```

# なぜ起こるのか？

レイアウト内のTextViewなどはAppCompatActivityによって、AppCompatTextViewに置き換えがされます。(https://github.com/android/platform_frameworks_support/blob/66698bb15ba0f873aa1c2290cc50d6bb839a474a/v7/appcompat/src/android/support/v7/app/AppCompatViewInflater.java#L91 )
以下はAppCompatTextViewのコンストラクタです。
こんな風にActivityをそのまま渡すのではなくTintContextWrapperとしてwrapしてViewクラスなどにContextを渡すためです。
このように行うViewが多くなっているようです

```java
public class AppCompatTextView extends TextView implements TintableBackgroundView {

...

    public AppCompatTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(TintContextWrapper.wrap(context), attrs, defStyleAttr);
```

# どうしてもViewのContextからActivityを取りたい

wrapしてしまっているだけなので、以下のようにwrapを解除してあげれば取得できるようです。

```java
final Activity activity = (Activity) ((ContextWrapper) text.getContext()).getBaseContext();
```


ただSupport Libraryの実装に依存してしまうので良くないと思います。
できるだけActivityから普通に渡してあげたり、何か他の仕組みを使いましょう。