gpt4 book ai didi

android - 如何将动态加载的类转换为它的接口(interface)?

转载 作者:太空狗 更新时间:2023-10-29 12:52:50 26 4
gpt4 key购买 nike

我正在创建一个允许插件 View 的家庭自动化应用程序。

我有以下代码作为概念证明:

我已经创建了一个带有插件接口(interface)的 android 库项目:

package com.strutton.android.UIPlugInLib;

import android.app.Dialog;

public interface IRDroidInterface {
public Dialog buildConfigDialog(int ID);
// Other method signatures here
}

我已经能够在一个单独的项目中创建一个类作为示例插件(并将其导出到 apk)并将其推送到我的应用程序的文件目录:

package com.strutton.android.testloadclass;

import com.strutton.android.UIPlugInLib.IRDroidInterface;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.view.View;
import android.widget.Button;

public class MyTestClass_IRDroidUIPlugIn extends Button implements IRDroidInterface{
public final Activity mActivity;
public MyTestClass_IRDroidUIPlugIn(Activity activity) {
super((Context)activity);
mActivity = activity;
setText("I was loaded dynamically! (1)");
setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
setText("I was Clicked dynamically! (" + getId() +")");
}}
);
}

public Dialog buildConfigDialog(int ID){
AlertDialog.Builder builder = new AlertDialog.Builder((Context)mActivity);
builder.setMessage("Click the Button...(1)")
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
mActivity.dialogDismiss();
}
});
return builder.create();
}
}

我可以在运行时加载此类并使用以下代码创建它的一个实例(在我的 onCreate() 中):

package com.strutton.android.testplugin;

try {
final File filesDir = this.getFilesDir();
final File tmpDir = getDir("dex", 0);
final DexClassLoader classloader = new DexClassLoader( filesDir.getAbsolutePath()+"/testloadclass.apk",
tmpDir.getAbsolutePath(),
null, this.getClass().getClassLoader());
final Class<View> classToLoad =
(Class<View>) classloader.loadClass("com.strutton.android.testloadclass.MyTestClass_IRDroidUIPlugIn");
mybutton = (View) classToLoad.getDeclaredConstructor(Context.class).newInstance(this);
mybutton.setId(2);
main.addView((View)mybutton);
} catch (Exception e) {
e.printStackTrace();
}

setContentView(main);
}
protected Dialog onCreateDialog(int id) {
switch (id) {
case 1:
// this is the offending line 57
return ((IRDroidInterface) mybutton).buildConfigDialog(id);
}
return null;
}

我希望插件能够显示插件中定义的配置对话框。当我调用 buildConfigDialog(id) 时,我得到以下 ClassCastException:

04-20 20:49:45.865: W/System.err(354): java.lang.ClassCastException: com.strutton.android.testloadclass.MyTestClass_IRDroidUIPlugIn
04-20 20:49:45.894: W/System.err(354): at com.strutton.android.testplugin.TestpluginActivity.onCreate(TestpluginActivity.java:57)

我在这里错过了什么?我已经在谷歌上搜索了一天半,但找不到解决方案。

提前致谢。

最佳答案

我怀疑问题在于您的应用程序和您加载的 dex 文件中都存在 IRDroidInterface 接口(interface)。当您动态加载 MyTestClass_IRDroidUIPlugIn 类时,由于它来自 dex 文件,因此它实现了 dex 文件中的接口(interface)类,而不是您的应用程序中的接口(interface)类。

如果您能确保接口(interface)类不会包含在插件的 dex 文件中,我相信您所拥有的应该可以正常工作。

不幸的是,如果您使用 eclipse 或 ant 构建插件 apk,这可能会很棘手。一种(相当丑陋的)解决方案是在构建 dex 文件后从中删除接口(interface)类。即用baksmali反汇编,删除接口(interface)的.smali文件,再用smali重新组装。

关于android - 如何将动态加载的类转换为它的接口(interface)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10254170/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com