2012/10/27
ClipboardManager で NoClassDefFoundError
Android の ClipboardManager もそんなクラスの一つです。
テキストを Clipboard にコピーする方法として、以下の様なコードがよく提示されています。
あえて import 文を見せているところが重要。
import android.content.ClipboardManager; // 省略 private void copyToClipboard(String text) { ClipboardManager clipboardManager = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); clipboardManager.setText(text); }
これ、最近のADTでは、"Class requires API level 11 (current min is 7)" というように怒られます。
このエラー、「API11 未満ではこのクラスは提供されていないよ。」という意味ですから、この時点で何かおかしいとは思うわけですが、とりあえず、@TargetApi(11) をつけて問題を回避してみます。
import android.content.ClipboardManager; // 省略 @TargetApi(11) private void copyToClipboard(String text) { ClipboardManager clipboardManager = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); clipboardManager.setText(text); }
これを、API11 未満の端末で動作させると、NoClassDefFoundError が発生します。
E/AndroidRuntime(221): java.lang.NoClassDefFoundError: android.content.ClipboardManager
先ほど Eclipse で警告が出ていたように、Class が存在していないようです。
「本に書いてある通りなのにおかしいなぁ」と思ってよく見てみると、ClipboarManager には以下の2種類があるではないですか。
- android.content.ClipboardManager
- android.text.ClipboardManager
こういう時に、IDEは便利だなーって思いますね。
つまり、API11 未満と API11 以上では次のように ClipboardManager を呼び分けてやらないといけないわけです。
(Deprecated なのを承知の上で古い方法だけを使うという方法もあります。)
// 呼び出し元 (詳細省略) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { copyToClipboard("hoge"); } else { copyToClipboardUnder11("piyo"); } // 省略 // API11 未満の時に使用 @SuppressWarnings("deprecation") private void copyToClipboardUnder11(String text) { android.text.ClipboardManager clipboardManager = (android.text.ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); clipboardManager.setText(text); } // API11 以上の時に使用 @TargetApi(11) private void copyToClipboard(String text) { android.content.ClipboardManager clipboardManager = (android.content.ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); ClipData.Item item = new ClipData.Item(text); String[] mimeTypes = new String[] { ClipDescription.MIMETYPE_TEXT_PLAIN }; ClipData clip = new ClipData("data", mimeTypes, item); clipboardManager.setPrimaryClip(clip); }
API11 以降では ClipboardManager の使用方法も変わっています。
android.content.ClipboardManager は android.text.ClipboardManager を継承しているので、古い使い方も出来ますが、そのような使い方をするメリットはないでしょう。
1 件のコメント:
参考になりました、ありがとうございます
コメントを投稿