我正在尝试从实现特定接口的 APK 中获取视图,但我的应用程序一直在崩溃。我可能弄错了什么?以下是我的方法:
这是传递并由其他应用程序实现的接口:
package ca.rev.libs.core;
import android.content.Context;
import android.view.View;
public interface MyViewCreator {
View createMyView(Context context);
}
实现接口并提供视图的应用程序:
package ca.rev.service.core.rev_views;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
public class TestView implements MyViewCreator {
@Override
public View createMyView(Context context) {
LayoutInflater revInfl = LayoutInflater.from(context);
View toolBarItemsLL = revInfl.inflate(R.layout.layout, null, false);
Button button = (Button) toolBarItemsLL.findViewById(R.id.testButton);
return button;
}
}
在主应用程序中,我浏览了所有已安装的应用程序,并检查具有接口实现的 Dex 文件:
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
PackageManager pm = getPackageManager();
for (ApplicationInfo app : pm.getInstalledApplications(0)) {
String dexPath = app.sourceDir;
String libraryPath = null;
DexClassLoader dexClassLoader = null;
try {
dexClassLoader = new DexClassLoader(dexPath, File.createTempFile("opt", "dex", this.getCacheDir()).getPath(), libraryPath, ClassLoader.getSystemClassLoader());
} catch (IOException e) {
e.printStackTrace();
}
DexFile dexFile;
Button myView;
try {
dexFile = DexFile.loadDex(dexPath, File.createTempFile("opt", "dex", this.getCacheDir()).getPath(), 0);
for (Enumeration<String> classNames = dexFile.entries(); classNames.hasMoreElements(); ) {
String className = classNames.nextElement();
Class myClass = dexClassLoader.loadClass(className);
if (myClass.isAssignableFrom(MyViewCreator.class)) {
MyViewCreator creator = (MyViewCreator) myClass.getConstructor().newInstance();
myView = (Button) creator.createMyView(this);
// add myView wherever you want
navigationView.addView(myView);
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
更新
感谢@JesusFreke,我设法获得了堆栈跟踪:
--------- beginning of crash
08-03 22:57:38.067 4864-4864/ca.rev.revcore E/AndroidRuntime: FATAL EXCEPTION: main
Process: ca.rev.revcore, PID: 4864
java.lang.IllegalAccessError: Class android.support.v4.app.NotificationCompat$BuilderExtender extended by class android.support.v7.app.NotificationCompat$IceCreamSandwichExtender is inaccessible (declaration of 'android.support.v7.app.NotificationCompat$IceCreamSandwichExtender' appears in /system/app/PrebuiltBugle/PrebuiltBugle.apk)
at dalvik.system.DexFile.defineClassNative(Native Method)
at dalvik.system.DexFile.defineClass(DexFile.java:296)
at dalvik.system.DexFile.loadClassBinaryName(DexFile.java:289)
at dalvik.system.DexPathList.findClass(DexPathList.java:418)
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:54)
at java.lang.ClassLoader.loadClass(ClassLoader.java:380)
at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
at ca.rev.revcore.MainActivity.onCreate(MainActivity.java:108)
at android.app.Activity.performCreate(Activity.java:6679)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2618)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
at ca.rev.revcore.MainActivity.onCreate(MainActivity.java:108)
位于Class myClass = dexClassLoader.loadClass(className);