NoSuchMethodException,尽管它在那里

NoSuchMethodException, despite it beeing there

我正在开发一个可以与外部 apk 一起使用的应用程序。为此,我使用 DexClassLoader 将 classes 从外部 apks 加载到 classes-Array,并像这样使用 classes:

getFragment(){
    for (Class<?> cls : classes) {
        Log.v("loadDexClasses", "Class loaded " + cls.getName());
        if (cls.getName().contains("OpenQuestionFragment")) {
            Method m = null;
            Fragment xb = null;
            try
            {
                Class[] cArg = new Class[3];
                cArg[0] = Integer.class;
                cArg[1] = String.class;
                cArg[2] = String[].class;
                m = cls.getMethod("getInstance",cArg);
                xb = (Fragment) m.invoke(null,INTNULL,STRINGNULL,STRINGARRAYNULL);
                showFragment(xb);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                }
                if(xb==null){
                    return;
                }
                if (xb.equals(ClassLoader.getSystemClassLoader()))
                    Log.v("loadDexClasses", "Same ClassLoader");
                else
                    Log.v("loadDexClasses", "Different ClassLoader");
            }
        }
    }
}

外部 apk:

public class OpenQuestionFragment extends Fragment{

//flags
final static int INTNULL = -1;
final static String STRINGNULL = null;
final static String[] STRINGARRAYNULL = null;

static View view;
static String setter;
static boolean run = true;
private static int edittextid;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    RelativeLayout rl = new RelativeLayout(getActivity());
    EditText et = new EditText(getActivity());
    edittextid = view.generateViewId();
    et.setId(edittextid);
    rl.addView(et);
    et.setTextSize(70);
    //blub
    et.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
    RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams)et.getLayoutParams();
    layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT,RelativeLayout.TRUE);
    et.setLayoutParams(layoutParams);
    et.setHint("hier eingeben");
    view = rl; //inflater.inflate(R.layout.testlayout, container, false);
    if(setter!=STRINGNULL && setter != ""){
        ((EditText) view.findViewById(edittextid)).setText(setter);
    }
    //initializeListenerThread();
    return view;
}


public static OpenQuestionFragment newInstance(String seter){
    /*setter=seter;
    run = true;*/
    return new OpenQuestionFragment();
}

public static Fragment getInstance(int intloader, String stringloader, String[] arrayloader){
    setter = stringloader;
    return newInstance(null);
}

public String getResult(){
    EditText ET = (EditText) view.findViewById(edittextid);
    return ET.getText().toString();
}

public String getQuestionTag(){
    return "OpenQuestion";
}

public boolean isAnswered(){
    EditText ET = (EditText) view.findViewById(edittextid);
    if(ET.getText().toString()!=""){
        return false;
    }else{
        return true;
    }
}

@Override
public void onDestroy(){
    run = false;
    super.onDestroy();
}
}

和proguard,以防止未使用的方法不被组装:

-keepclassmembers class dexloader.openquestion.OpenQuestionFragment {
   public *;
}

我已经知道,加载的 class 没有问题,因为 "newInstance" 函数可以完全相同的方式调用,除了稍微调整 cArg-Array 以匹配追捧方法,如下:

Class[] cArg = new Class[3];
cArg[0] = Integer.class;
cArg[1] = String.class;
cArg[2] = String[].class;
m = cls.getMethod("getInstance",cArg);
xb = (Fragment) m.invoke(null,INTNULL,STRINGNULL,STRINGARRAYNULL); 

进入

Class[] cArg = new Class[1];
cArg[0] = String.class;
m = cls.getMethod("newInstance",cArg);
xb = (Fragment) m.invoke(null,STRINGNULL);

当我启动应用程序时,当我调用 m.invoke(); 时,它仍然会抛出 NoSuchMethodException,它会被捕获,嗯......这不应该发生。我能看到的唯一区别是 getInstance() 没有被使用,但是 proguard-rule 应该已经阻止了。

感谢帮助

干杯,雅各布斯

在尝试了一切之后,我自己解决了这个问题。结果 Integer.class != int 应该是

                Class[] cArg = new Class[3];
            cArg[0] = int.class;
            cArg[1] = String.class;
            cArg[2] = String[].class;