我正在尝试开发一个" Dynamic" Android应用程序。
动态,即我在清单中列出的活动是"内置"在运行时。
我可以很好地构建所需的活动,但是,当我尝试启动它时,我的应用程序失败了......
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.research.ps/com.research.Dynamic}: java.lang.ClassNotFoundException:
Didn't find class "com.research.Dynamic" on path: DexPathList[[zip file "/data/app/com.research.ps-1/base.apk"],nativeLibraryDirectories=[/data/app/com.research.ps-1/lib/arm,
/data/app/com.research.ps-1/base.apk!/lib/armeabi-v7a, /vendor/lib, /system/lib]]
我是否可以采用一种方法在运行时成功实例化Android Activity?
有没有办法可以添加"临时"或者" shell"活动到我的申请路径?然后替换"临时"我的动态实例的活动?
更新
My Manifest XML包含此条目
<activity
android:name=".Dynamic"
android:label="@string/title_activity_dynamic"
android:theme="@style/AppTheme.NoActionBar" />
然而,没有名为&#34; Dynamic&#34;包含在我的申请中。
我正在使用ByteBuddy构建我的动态活动: -
final Class<? extends android.support.v7.app.AppCompatActivity> dynamicType = new ByteBuddy(ClassFileVersion.JAVA_V8)
.subclass(android.support.v7.app.AppCompatActivity.class, IMITATE_SUPER_CLASS)
.name("com.research.Dynamic")
.make()
.load(getClass().getClassLoader(), new AndroidClassLoadingStrategy.Wrapping(this.getDir("dexgen", Context.MODE_PRIVATE)))
.getLoaded();
final Intent intent = new Intent(this, dynamicType);
startActivity(intent);
答案 0 :(得分:12)
是您 CAN 启动此类Activity
(假设您有 虚拟 清单{ {1}}条目。)如果您不喜欢这种技巧,请使用 Activity
(他们不需要清单中的条目)。<或者使用WebView和JavaScript,例如Apache Cordova et-al(跨平台!)。
ByteBuddy(作为Byte Buddy的作者@Rafael Winterhalter的赞誉)看起来很酷,也许是一个学习曲线。为什么不下载linked project并尝试这两种技术
以下是Android Studio Fragments
项目include
中ByteBuddy
Gradle
的方式:
build.gradle
我怎样才能找到&#34;我在运行时动态实例化类?
See my answer here并按照源代码和教程(Apache Ant {android {
compileSdkVersion 25
buildToolsVersion '25'
dependencies {
compile 'com.android.support:appcompat-v7:25'
compile 'net.bytebuddy:byte-buddy:1.7.9'
compile 'net.bytebuddy:byte-buddy-android:1.7.9'
}
}
兼容,Eclipse
}和Android Studio build.xml
示例Gradle
的链接进行操作相同的代码,您需要一些这些项目提供的自定义构建步骤
代码段:
build.gradle
问:如何添加活动,我无法将其添加到清单?
答:使用 片段,他们不需要清单中的条目。
答案 1 :(得分:5)
我已设法调用动态实例化的Activity并使用ByteBuddy设置所需的布局内容。
继承人
final DynamicType.Unloaded<? extends AppCompatActivity> dynamicType = new ByteBuddy(ClassFileVersion.JAVA_V8)
.subclass(AppCompatActivity.class)
.name(CLASS_NAME)
.method(named("onCreate").and(takesArguments(1)))
.intercept(MethodDelegation.to(TargetActivity.class).andThen(SuperMethodCall.INSTANCE))
.make();
final Class<? extends AppCompatActivity> dynamicTypeClass = dynamicType.load(getClassLoader(), new AndroidClassLoadingStrategy.Injecting(this.getDir("dexgen", Context.MODE_PRIVATE))).getLoaded();
final Intent intent = new Intent(this, dynamicTypeClass);
startActivity(intent);
方法委派类
public class TargetActivity {
public static void intercept(Bundle savedInstanceState, @This AppCompatActivity thiz) {
thiz.setContentView(R.layout.activity_fourth);
}
}
即使这会产生预期的结果,但在我调用super.onCreate(savedInstanceState)
(我认为)之后调用setContent
时仍会出现问题。
使用优秀的ByteBuddy库是一种比使用DEX操作更好的方法。