13

IME を実装する Android アプリで作業しているときに、Eclipse ワークスペース ログに表示されるエラーを理解し、解決しようとしています。私はAndroidとEclipseが初めてです。

エラーは「com.utterkaos.keyboard.LatinKeyboardView のインスタンス化に失敗しました」です。

関連するスタック トレースは次のとおりです。

java.lang.UnsupportedOperationException: Unsupported Service: audio at com.android.layoutlib.bridge.android.BridgeContext.getSystemService(BridgeContext.java:434) at android.inputmethodservice.KeyboardView.(KeyboardView.java:376) at android.inputmethodservice. KeyboardView.(KeyboardView.java:279) で com.utterkaos.keyboard.LatinKeyboardView.(LatinKeyboardView.java:30) で sun.reflect.NativeConstructorAccessorImpl.newInstance0(ネイティブ メソッド) で sun.reflect.NativeConstructorAccessorImpl.newInstance(未知のソース) でcom.android.ide.eclipse.adt.internal.editors.layout.ProjectCallback.instantiateClass(ProjectCallback.java: 402) com.android.ide.eclipse.adt.internal.editors.layout.ProjectCallback.loadView(ProjectCallback.java:166) で android.view.BridgeInflater.loadCustomView(BridgeInflater.java:207) で android.view.BridgeInflater.createViewFromTag(BridgeInflater.java:135) で android.view .LayoutInflater.inflate(LayoutInflater.java:466) で android.view.LayoutInflater.inflate(LayoutInflater.java:372) com.android.layoutlib.bridge.impl.RenderSessionImpl.inflate(RenderSessionImpl.java:321) で com. android.layoutlib.bridge.Bridge.createSession(Bridge.java:324) com.android.ide.common.rendering.LayoutLibrary.createSession(LayoutLibrary.java:325) com.android.ide.eclipse.adt.internal. com.android.ide.eclipse.adt.internal.editors.layout.gle2.GraphicalEditorPart の editors.layout.gle2.RenderService.createRenderSession(RenderService.java:372)。renderWithBridge(GraphicalEditorPart.java:1361) com.android.ide.eclipse.adt.internal.editors.layout.gle2.GraphicalEditorPart.recomputeLayout(GraphicalEditorPart.java:1115) com.android.ide.eclipse.adt.internal. editors.layout.gle2.GraphicalEditorPart.activated(GraphicalEditorPart.java:941) com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditorDelegate.delegatePageChange(LayoutEditorDelegate.java:450) com.android.ide. org.eclipse.ui.part.MultiPageEditorPart.setActivePage(MultiPageEditorPart.java:1067) の org.eclipse.ui.forms.editor の eclipse.adt.internal.editors.common.CommonXmlEditor.pageChange(CommonXmlEditor.java:358)。 FormEditor.setActivePage(FormEditor.java:607) com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor.selectDefaultPage(AndroidXmlEditor.java:380) com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor.addPages(AndroidXmlEditor.java:285) com.android.ide.eclipse.adt.internal.editors.common.CommonXmlEditor.addPages(CommonXmlEditor.java:283) でorg.eclipse.ui.forms.editor.FormEditor.createPages(FormEditor.java:138) at org.eclipse.ui.part.MultiPageEditorPart.createPartControl(MultiPageEditorPart.java:348) at org.eclipse.ui.internal.EditorReference. org.eclipse.ui.internal.EditorReference.createPart(EditorReference.java:465) の createPartHelper(EditorReference.java:670) org.eclipse.ui.internal.WorkbenchPartReference.getPart(WorkbenchPartReference.java:595) の org.eclipse .ui.internal.EditorReference.getEditor(EditorReference.java:289) org.eclipse.ui.internal.WorkbenchPage.busyOpenEditorBatched(WorkbenchPage.java:2945) org.eclipse.ui.internal.WorkbenchPage.busyOpenEditor(WorkbenchPage.java:2850) at org.eclipse.ui.internal.WorkbenchPage.access$11(WorkbenchPage.java:2842) at org.eclipse.ui.internal.WorkbenchPage$10.run(WorkbenchPage. java:2793) org.eclipse.swt.custom.BusyIndi​​cator.showWhile(BusyIndi​​cator.java:70) で org.eclipse.ui.internal.WorkbenchPage.openEditor(WorkbenchPage.java:2789) で org.eclipse.ui.internal .WorkbenchPage.openEditor(WorkbenchPage.java:2773) at org.eclipse.ui.internal.WorkbenchPage.openEditor(WorkbenchPage.java:2764) at org.eclipse.ui.ide.IDE.openEditor(IDE.java:651) at org.eclipse.ui.ide.IDE.openEditor(IDE.java:651) org.eclipse.ui.ide.IDE.openEditor(IDE.java:610) at org.eclipse.jdt.internal.ui.javaeditor.EditorUtility.openInEditor(EditorUtility.java:355) at org.eclipse.jdt.internal. ui.javaeditor.EditorUtility.openInEditor(EditorUtility.java:164) org.eclipse.jdt.ui.actions.OpenAction.run(OpenAction.java:249) で org.eclipse.jdt.ui.actions.OpenAction.run(OpenAction.java:228) で org.eclipse.jdt .ui.actions.SelectionDispatchAction.dispatchRun(SelectionDispatchAction.java:275) の org.eclipse.jdt.ui.actions.SelectionDispatchAction.run(SelectionDispatchAction.java:251) の org.eclipse.jdt.internal.ui.packageview.PackageExplorerActionGroup .handleOpen(PackageExplorerActionGroup.java:376) at org.eclipse.jdt.internal.ui.packageview.PackageExplorerPart$4.open(PackageExplorerPart.java:538) at org.eclipse.ui.OpenAndLinkWithEditorHelper$InternalListener.open(OpenAndLinkWithEditorHelper.java: 48) org.eclipse.jface.viewers.StructuredViewer$2.run(StructuredViewer.java:866) で org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42) で org.eclipse.ui.internal.JFaceUtil$1.run(JFaceUtil.java:49) at org.eclipse.jface.util.SafeRunnable.run(SafeRunnable.java:175) at org.eclipse.jface.viewers.StructuredViewer.fireOpen(StructuredViewer.java) :864) org.eclipse.jface.viewers.StructuredViewer.handleOpen(StructuredViewer.java:1152) で org.eclipse.jface.viewers.StructuredViewer$6.handleOpen(StructuredViewer.java:1256) で org.eclipse.jface.util .OpenStrategy.fireOpenEvent(OpenStrategy.java:275) at org.eclipse.jface.util.OpenStrategy.access$2(OpenStrategy.java:269) at org.eclipse.jface.util.OpenStrategy$1.handleEvent(OpenStrategy.java:309) ) org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) で org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1053) で org.eclipse.swt.widgets.Display. runDeferredEvents(Display.java:4165) org.org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2701) の eclipse.swt.widgets.Display.readAndDispatch(Display.java:3754) org.eclipse.ui.internal.Workbench.runUI(Workbench. java:2665) org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2499) で org.eclipse.ui.internal.Workbench$7.run(Workbench.java:679) で org.eclipse.core org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:668) の .databinding.observable.Realm.runWithDefault(Realm.java:332) org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149) の) org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:123) で org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) で org.eclipse. core.runtime.internal.adaptor.EclipseAppLauncher.org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79) の runApplication(EclipseAppLauncher.java:110) org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java: 344) org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun. org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622) の java.lang.reflect.Method.invoke(不明なソース) のreflect.DelegatingMethodAccessorImpl.invoke(不明なソース) org.eclipse.equinox.launcher .Main.basicRun(Main.java:577) at org.eclipse.equinox.launcher.Main.run(Main.java:1410) at org.eclipse.equinox.launcher.Main.main(Main.java:1386)1386)1386)110) org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79) で org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:344) で org.eclipse .core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke( java.lang.reflect.Method.invoke(ソース不明) org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622) org.eclipse.equinox.launcher.Main.basicRun(Main) .java:577) org.eclipse.equinox.launcher.Main.run(Main.java:1410) で org.eclipse.equinox.launcher.Main.main(Main.java:1386) で110) org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79) で org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:344) で org.eclipse .core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke( java.lang.reflect.Method.invoke(ソース不明) org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622) org.eclipse.equinox.launcher.Main.basicRun(Main) .java:577) org.eclipse.equinox.launcher.Main.run(Main.java:1410) で org.eclipse.equinox.launcher.Main.main(Main.java:1386) でorg.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:344) の EclipseAppLauncher.start(EclipseAppLauncher.java:79) org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java: 179) sun.reflect.NativeMethodAccessorImpl.invoke0 (ネイティブ メソッド) で sun.reflect.NativeMethodAccessorImpl.invoke (不明なソース) で sun.reflect.DelegatingMethodAccessorImpl.invoke (不明なソース) で java.lang.reflect.Method.invoke(不明)ソース) org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622) で org.eclipse.equinox.launcher.Main.basicRun(Main.java:577) で org.eclipse.equinox.launcher.Main .run(Main.java:1410) at org.eclipse.equinox.launcher.Main.main(Main.java:1386)org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:344) の EclipseAppLauncher.start(EclipseAppLauncher.java:79) org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java: 179) sun.reflect.NativeMethodAccessorImpl.invoke0 (ネイティブ メソッド) で sun.reflect.NativeMethodAccessorImpl.invoke (不明なソース) で sun.reflect.DelegatingMethodAccessorImpl.invoke (不明なソース) で java.lang.reflect.Method.invoke(不明)ソース) org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622) で org.eclipse.equinox.launcher.Main.basicRun(Main.java:577) で org.eclipse.equinox.launcher.Main .run(Main.java:1410) at org.eclipse.equinox.launcher.Main.main(Main.java:1386)java:344) で org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179) で sun.reflect.NativeMethodAccessorImpl.invoke0(ネイティブ メソッド) で sun.reflect.NativeMethodAccessorImpl.invoke(不明なソース) でorg.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622) の java.lang.reflect.Method.invoke(未知のソース) の sun.reflect.DelegatingMethodAccessorImpl.invoke(未知のソース) org.eclipse.equinox の.launcher.Main.basicRun(Main.java:577) at org.eclipse.equinox.launcher.Main.run(Main.java:1410) at org.eclipse.equinox.launcher.Main.main(Main.java:1386) )java:344) で org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179) で sun.reflect.NativeMethodAccessorImpl.invoke0(ネイティブ メソッド) で sun.reflect.NativeMethodAccessorImpl.invoke(不明なソース) でorg.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622) の java.lang.reflect.Method.invoke(未知のソース) の sun.reflect.DelegatingMethodAccessorImpl.invoke(未知のソース) org.eclipse.equinox の.launcher.Main.basicRun(Main.java:577) at org.eclipse.equinox.launcher.Main.run(Main.java:1410) at org.eclipse.equinox.launcher.Main.main(Main.java:1386) )org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622) の java.lang.reflect.Method.invoke(不明なソース) のreflect.DelegatingMethodAccessorImpl.invoke(不明なソース) org.eclipse.equinox.launcher .Main.basicRun(Main.java:577) at org.eclipse.equinox.launcher.Main.run(Main.java:1410) at org.eclipse.equinox.launcher.Main.main(Main.java:1386)org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622) の java.lang.reflect.Method.invoke(不明なソース) のreflect.DelegatingMethodAccessorImpl.invoke(不明なソース) org.eclipse.equinox.launcher .Main.basicRun(Main.java:577) at org.eclipse.equinox.launcher.Main.run(Main.java:1410) at org.eclipse.equinox.launcher.Main.main(Main.java:1386)

LatinKeyboardView.java の関連部分は次のとおりです。

public class LatinKeyboardView extends KeyboardView {

    static final int KEYCODE_OPTIONS = -100;

    public LatinKeyboardView(Context context, AttributeSet attrs) {
        super(context, attrs);

}

30行目は「super(context, attrs);」です。

KeyboardView.java の 376 行目:

mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);

ここで、「Context.AUDIO_SERVICE」は文字列「audio」のように見え、エラー スタック トレースに表示されます。

BridgeContext.java の関連ビットは次のとおりです。

    public Object getSystemService(String service) {
414        if (LAYOUT_INFLATER_SERVICE.equals(service)) {
415            return mBridgeInflater;
416        }
417
418        if (TEXT_SERVICES_MANAGER_SERVICE.equals(service)) {
419            // we need to return a valid service to avoid NPE
420            return TextServicesManager.getInstance();
421        }
422
423        // AutoCompleteTextView and MultiAutoCompleteTextView want a window
424        // service. We don't have any but it's not worth an exception.
425        if (WINDOW_SERVICE.equals(service)) {
426            return null;
427        }
428
429        // needed by SearchView
430        if (INPUT_METHOD_SERVICE.equals(service)) {
431            return null;
432        }
433
434        throw new UnsupportedOperationException("Unsupported Service: " + service);
435    }

このルーチンで特に困惑しているのは、「オーディオ」サービスをどのように処理できるかがわからないことですが、BridgeContext.java と KeyboardView.java はどちらも Android コードの一部であり、私が間違って記述したクラスではありません。

このエラーが発生する理由とそれを回避する方法を理解するのに役立つポインタがあれば、大歓迎です。

4

5 に答える 5

4

API 14 以降を使用していますか? もしそうなら、それが問題です。そのバージョンのバグだと思います。API 11 では動作します。

API 11 を試す場合は、 getResources() メソッドをオーバーライドしてハックする必要があります。詳細については、これを確認してください。この後、動作します。

実際には、ビューのコンストラクターをスーパーで呼び出す必要があるため、 isInEditMode() を使用することさえできないため、API 14 (またはそれ以上) の LatinKeyboardView からこれをジャンプする方法はないと思います。そして、そのコンストラクターはオーディオシステムサービスを取得しようとしますが、これはEclipseグラフィカルエディターで実行しようとしていると思われるため、単に失敗します(実際、カスタムビューをグラフィカルレイアウトエディターのレイアウトに配置しようとしたときにこのエラーが発生しました)

これをハッキングする唯一の方法は、getSystemService を使用せずに独自の KeyboardView を実装することだと思います。isInEditMode == true の場合、そのメソッドを呼び出さないでください。

于 2013-03-14T23:55:37.190 に答える
2

解決策を見つけました。

KeyboardViewFix置換として使用KeyboardView:

public class KeyboardViewFix extends KeyboardView {
    public static boolean inEditMode = true;

    @TargetApi(21) // Build.VERSION_CODES.L
    public KeyboardViewFix(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(inEditMode ? new ContextWrapperInner(context) : context, attrs, defStyleAttr, defStyleRes);
    }

    public KeyboardViewFix(Context context, AttributeSet attrs, int defStyleAttr) {
        super(inEditMode ? new ContextWrapperInner(context) : context, attrs, defStyleAttr);
    }

    public KeyboardViewFix(Context context, AttributeSet attrs) {
        super(inEditMode ? new ContextWrapperInner(context) : context, attrs);
    }

    public static class ContextWrapperInner extends ContextWrapper {
        Context base;
        public ContextWrapperInner(Context base) {
            super(base);
            this.base = base;
        }
        public Object getSystemService(String name) {
            return Context.AUDIO_SERVICE.equals(name) ? null : base.getSystemService(name);
        }       
    }
}

1 つの注意: アプリの起動時に、他のコードを設定する前に設定しKeyboardViewFix.inEditMode = false;ないと、エラーが発生する可能性があります。

于 2015-11-28T22:29:55.480 に答える