概述
今天同事问我这里怎么会提示这个
W/dalvikvm: VFY: unable to resolve virtual method 1886:
Landroid/preference/PreferenceFragment;.onAttach (Landroid/content/ContextV
D/dalvikvm: VFY: replacing opcode 0x6f at 0x0000
环境
是这样出现的
minSdkVersion 14
targetSdkVersion 27
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.setting_frame,new SettingWelcomeFragment());
transaction.commit();
SettingWelcomeFragment中
public class SettingWelcomeFragment中 extends Fragment {
protected boolean onKeyDown(int keyCode,KeyEvent event){
return false;
}
@Override
public void onAttach(Activity activity){
super.onAttach(activity);
Log.e("activity","onAttach");
}
@Override
public void onAttach(Context context){
Log.e("context","onAttach");
super.onAttach(context);
}
}
在api19的手机上会出现这个提示。
原因
1,onAttach(Context context)是API27新加的方法,在API14的手机上是没有这个方法的。
2,打印log的时候,可以看到android4.4的机器上没有打印出context的log(就是完全没被调用到。)
3,但是还是会提示,是因为加载class的时候,检查到有super.onAttach(context)
的方法,art试图建索引,但是没建成功,所以提示报错。
这个提示在哪里打印的
这个代码是在art中打印出来的,所以打印的时间点是在加载类的时候(即ClassLoader),所以这个提示只会出现一次.在加载类的时候,没找到方法的时候。提示
第一行提示是说找不到,第二行提示是把这个找不到的方法替换成空方法。
这个比较好找,因为源码中只有一个地方的前缀是VFY
method_verifier
std::ostream& MethodVerifier::LogVerifyInfo() {
return info_messages_ << "VFY: " << PrettyMethod(dex_method_idx_, *dex_file_)
<< '[' << reinterpret_cast<void*>(work_insn_idx_) << "] : ";
}
dex_to_dex_compiler
void DexCompiler::CompileReturnVoid(Instruction* inst, uint32_t dex_pc) {
DCHECK_EQ(inst->Opcode(), Instruction::RETURN_VOID);
if (unit_.IsConstructor()) {
// Are we compiling a non clinit constructor which needs a barrier ?
if (!unit_.IsStatic() &&
driver_.RequiresConstructorBarrier(Thread::Current(), unit_.GetDexFile(),
unit_.GetClassDefIndex())) {
return;
}
}
// Replace RETURN_VOID by RETURN_VOID_NO_BARRIER.
VLOG(compiler) << "Replacing " << Instruction::Name(inst->Opcode())
<< " by " << Instruction::Name(Instruction::RETURN_VOID_NO_BARRIER)
<< " at dex pc " << StringPrintf("0x%x", dex_pc) << " in method "
<< PrettyMethod(unit_.GetDexMethodIndex(), GetDexFile(), true);
inst->SetOpcode(Instruction::RETURN_VOID_NO_BARRIER);
}
为什么编译没报错呢,因为编译的时候有这个方法,但是实际跑的时候,手机上的库和编译时候的库有出入,所以art在这里做了简单的兼容/提示处理。
避免这个问题可以这样做:
解决方法一
把targetsdk修改成19,编译过程中as会提示错误的,最大程度的避免这个奇奇怪怪的错误
解决方法二
用SupportV4的方法getSupportFragmentManager,不用系统上的getFragmentManager的方法,SupportV4本身做了不少兼容处理,所以也不会有警告,也能被调用到。
最后
以上就是安详眼睛为你收集整理的android找不到方法(unable to resolve virtual method)的警告与分析的全部内容,希望文章能够帮你解决android找不到方法(unable to resolve virtual method)的警告与分析所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复