首页 \ 问答 \ NoSuchMethodException,尽管它在那里(NoSuchMethodException, despite it beeing there)

NoSuchMethodException,尽管它在那里(NoSuchMethodException, despite it beeing there)

我正在开发一个可以使用外部apks的应用程序。 为此,我使用DexClassLoader将类从外部apks加载到classes -Array中,并使用如下所示的类:

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 *;
}

我已经知道,加载的类没有问题,因为“newInstance”函数可以被称为EXACT相同的方式,除了稍微调整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);

当我启动应用程序时,它仍会抛出NoSuchMethodException ,当我调用m.invoke(); 被抓住了,好吧......不应该发生。 唯一的区别,我可以看到, getInstance()被使用,但是proguard-rule应该已经阻止了。

感谢帮助

干杯,雅各布斯


I am working on an Application, which can work with external apks. For this i used the DexClassLoader , to load classes, from external apks into an classes-Array, and work with the classes like this:

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");
            }
        }
    }
}

external 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();
}
}

and the proguard, to prevent unused methods to not be assembled:

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

i already know, that there isnt a problem with the loaded class, as the "newInstance" function can be called the EXACT same way, except tweaking the cArg-Array slightly, to match the sought after method, like follows:

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); 

into

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

When i start the Application, it still throws a NoSuchMethodException, when i call m.invoke();, which gets caught, and well... that isnt supposed to happen. The only difference, i can see is, that getInstance() isnt used, but the proguard-rule should have prevented that.

Help is appreciated

Cheers, Jacobus


原文:https://stackoverflow.com/questions/34763275
更新时间:2022-12-08 09:12

最满意答案

使用RSpec 2.0.0.beta.19

# Gemfile
group :test do
  gem "rspec", ">= 2.0.0.beta.19"
  gem "rspec-rails", ">= 2.0.0.beta.17"
  gem "shoulda"
end

# spec/spec_helper.rb
require 'rspec/rails'
require 'shoulda/integrations/rspec2' # Add this line

# In your specs....
it { should validate_presence_of(:name) }

运行rake spec现在应该加载并运行包括RSpec 2匹配器在内的规范。


Using RSpec 2.0.0.beta.19

# Gemfile
group :test do
  gem "rspec", ">= 2.0.0.beta.19"
  gem "rspec-rails", ">= 2.0.0.beta.17"
  gem "shoulda"
end

# spec/spec_helper.rb
require 'rspec/rails'
require 'shoulda/integrations/rspec2' # Add this line

# In your specs....
it { should validate_presence_of(:name) }

Running rake spec should now load and run specs including the RSpec 2 matchers.

相关问答

更多

相关文章

更多

最新问答

更多
  • 获取MVC 4使用的DisplayMode后缀(Get the DisplayMode Suffix being used by MVC 4)
  • 如何通过引用返回对象?(How is returning an object by reference possible?)
  • 矩阵如何存储在内存中?(How are matrices stored in memory?)
  • 每个请求的Java新会话?(Java New Session For Each Request?)
  • css:浮动div中重叠的标题h1(css: overlapping headlines h1 in floated divs)
  • 无论图像如何,Caffe预测同一类(Caffe predicts same class regardless of image)
  • xcode语法颜色编码解释?(xcode syntax color coding explained?)
  • 在Access 2010 Runtime中使用Office 2000校对工具(Use Office 2000 proofing tools in Access 2010 Runtime)
  • 从单独的Web主机将图像传输到服务器上(Getting images onto server from separate web host)
  • 从旧版本复制文件并保留它们(旧/新版本)(Copy a file from old revision and keep both of them (old / new revision))
  • 西安哪有PLC可控制编程的培训
  • 在Entity Framework中选择基类(Select base class in Entity Framework)
  • 在Android中出现错误“数据集和渲染器应该不为null,并且应该具有相同数量的系列”(Error “Dataset and renderer should be not null and should have the same number of series” in Android)
  • 电脑二级VF有什么用
  • Datamapper Ruby如何添加Hook方法(Datamapper Ruby How to add Hook Method)
  • 金华英语角.
  • 手机软件如何制作
  • 用于Android webview中图像保存的上下文菜单(Context Menu for Image Saving in an Android webview)
  • 注意:未定义的偏移量:PHP(Notice: Undefined offset: PHP)
  • 如何读R中的大数据集[复制](How to read large dataset in R [duplicate])
  • Unity 5 Heighmap与地形宽度/地形长度的分辨率关系?(Unity 5 Heighmap Resolution relationship to terrain width / terrain length?)
  • 如何通知PipedOutputStream线程写入最后一个字节的PipedInputStream线程?(How to notify PipedInputStream thread that PipedOutputStream thread has written last byte?)
  • python的访问器方法有哪些
  • DeviceNetworkInformation:哪个是哪个?(DeviceNetworkInformation: Which is which?)
  • 在Ruby中对组合进行排序(Sorting a combination in Ruby)
  • 网站开发的流程?
  • 使用Zend Framework 2中的JOIN sql检索数据(Retrieve data using JOIN sql in Zend Framework 2)
  • 条带格式类型格式模式编号无法正常工作(Stripes format type format pattern number not working properly)
  • 透明度错误IE11(Transparency bug IE11)
  • linux的基本操作命令。。。