我有一个严重的问题。在我运行测试时使用espresso进行测试后,出现此复杂错误
java.lang.NoSuchMethodError:没有静态方法 setFactory2(Landroid / view / LayoutInflater; Landroid / view / LayoutInflater $ Factory2;)V 在类Landroid / support / v4 / view / LayoutInflaterCompat中;或其超级 类(“ android.support.v4.view.LayoutInflaterCompat”的声明 出现在 /data/app/com.example.master.bakingapp.test-ZVHwTuzx1ipxW0iPyBZKBw==/base.apk) 在 android.support.v7.app.AppCompatDelegateImpl.installViewFactory(AppCompatDelegateImpl.java:1299) 在 android.support.v7.app.AppCompatActivity.onCreate(AppCompatActivity.java:72) 在 com.example.master.bakingapp.MainActivity.onCreate(MainActivity.java:61) 在android.app.Activity.performCreate(Activity.java:7136)处 android.app.Activity.performCreate(Activity.java:7127)在 android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271) 在 android.support.test.runner.MonitoringInstrumentation.callActivityOnCreate(MonitoringInstrumentation.java:667) 在 android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2893) 在 android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048) 在 android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78) 在 android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) 在 android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) 在 android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1808) 在android.os.Handler.dispatchMessage(Handler.java:106) android.os.Looper.loop(Looper.java:193)在 android.app.ActivityThread.main(ActivityThread.java:6669)在 java.lang.reflect.Method.invoke(本机方法)位于 com.android.internal.os.RuntimeInit $ MethodAndArgsCaller.run(RuntimeInit.java:493) 在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
测试运行失败:由于“过程”,仪表运行失败 崩溃了。”
它指向MainActivity上的onCreate
在android.support.v7.app.AppCompatActivity.onCreate(AppCompatActivity.java:72) 在 com.example.master.bakingapp.MainActivity.onCreate(MainActivity.java:61)
我试图调试测试。它卡在了onCreate
这是我的整个测试代码
package com.example.master.bakingapp;
import android.support.test.espresso.Espresso;
import android.support.test.espresso.IdlingResource;
import android.support.test.espresso.contrib.RecyclerViewActions;
import android.support.test.espresso.matcher.ViewMatchers;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import static android.support.test.espresso.Espresso.onData;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.action.ViewActions.click;
import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static android.support.test.espresso.matcher.ViewMatchers.withText;
import static org.hamcrest.Matchers.anything;
@RunWith(AndroidJUnit4.class)
public class ClickUiTest {
@Rule
public ActivityTestRule<MainActivity> mActivityTestRule =
new ActivityTestRule<>(MainActivity.class);
private static final String RECIPE_ITEM_BROWNIE = "Brownies";
private IdlingResource mIdlingResource;
// Registers any resource that needs to be synchronized with Espresso before the test is run.
@Before
public void registerIdlingResource() {
mIdlingResource = mActivityTestRule.getActivity().getIdlingResource();
// To prove that the test fails, omit this call:
Espresso.registerIdlingResources(mIdlingResource);
}
@Test
public void checkSelectedItem_InRecycleView() {
onView(ViewMatchers.withId(R.id.recycle_recipe)).perform(RecyclerViewActions.scrollToPosition(1));
onView(withId(R.id.Ingredient_TextView)).check(matches(withText(RECIPE_ITEM_BROWNIE)));
}
@After
public void unregisterIdlingResource() {
if (mIdlingResource != null) {
Espresso.unregisterIdlingResources(mIdlingResource);
}
}
}
和gradle模块
apply plugin: 'com.android.application'
android {
compileSdkVersion 28
buildToolsVersion '28'
defaultConfig {
applicationId "com.example.master.bakingapp"
minSdkVersion 25
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
sourceSets { main { res.srcDirs = ['src/main/res', 'src/androidTest'] } }
}
ext {
lifecycle_version = "1.1.1"
butterLibVersion = '8.8.1'
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0-alpha3'
// ViewModel and LiveData
implementation "android.arch.lifecycle:extensions:${lifecycle_version}"
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
implementation 'com.google.android.exoplayer:exoplayer:r2.2.0'
implementation 'com.android.support.test.espresso:espresso-idling-resource:3.0.1'
implementation "com.jakewharton:butterknife:${butterLibVersion}"
annotationProcessor "com.jakewharton:butterknife-compiler:${butterLibVersion}"
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-intents:3.0.1'
androidTestImplementation('com.android.support.test.espresso:espresso-contrib:2.2')
androidTestImplementation "com.android.support.test.espresso.idling:idling-concurrent:3.0.1"
implementation 'com.android.support:recyclerview-v7:28.0.0-alpha3'
implementation 'com.android.support.test.espresso:espresso-idling-resource:3.0.1'
}
MainActivity
public class MainActivity extends AppCompatActivity implements RecipeCardFragment.OnRecycleClick
{
private Recipes[] mRecipes;
MyViewModel mViewModel;
String json;
public static final String mURL = "https://d17h27t6h515a5.cloudfront.net/topher/2017/May/59121517_baking/baking.json";
public static final String Bundle_Object = "BUNDLE_OBJ";
ProgressBar progressBar;
FragmentManager fragmentManager;
RecipeCardFragment cardFragment;
boolean mTabletbool;
@Nullable
private SimpleIdlingResource mIdlingResource;
/**
* Only called from test, creates and returns a new {@link SimpleIdlingResource}.
*/
@VisibleForTesting
@NonNull
public IdlingResource getIdlingResource() {
if (mIdlingResource == null) {
mIdlingResource = new SimpleIdlingResource();
}
return mIdlingResource;
}
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getIdlingResource();
}
@Override
protected void onPostResume() {
super.onPostResume();
}
@Override
public void onclick(int pos) {
Intent intent = new Intent(MainActivity.this, StepsActivity.class);
try {
Recipes recipes;
recipes = Networkutils.ParseJsonIndex(json, pos);
//updateWidget(recipes);
Bundle bundle = new Bundle();
bundle.putParcelable(Bundle_Object, recipes);
intent.putExtras(bundle);
fragmentManager=null;
cardFragment=null;
startActivity(intent);
} catch (JSONException e) {
e.printStackTrace();
}
}
@Override
public void jsonPass(String json) {
this.json=json;
}
private void updateWidget(Recipes recipes) {
ArrayList<String> ingredients = new ArrayList<>();
for(Ingredients ingre:recipes.getIngredients()){
String q=ingre.getQuantity()+"";
ingredients.add(ingre.getIngredient()+"\n"+
"Quantity: "+q+"\n"+
"Measure: "+ingre.getMeasure()+"\n");
}
UpdateBakingService.startBakingService(MainActivity.this,ingredients);
}
MainActivity.xml
<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.example.master.bakingapp.Fragments.RecipeCardFragment"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainActivity"/>
和MainActivity托管的我的片段
public class RecipeCardFragment extends android.app.Fragment {
public interface OnRecycleClick {
void onclick(int pos);
void jsonPass(String json);
}
private OnRecycleClick mOnRecycleClick;
Recipes[] mRecipes;
boolean mTablet;
//MainActivity
MyViewModel mViewModel;
String json;
public static final String mURL = "https://d17h27t6h515a5.cloudfront.net/topher/2017/May/59121517_baking/baking.json";
ProgressBar progressBar;
////
@Override
public void onAttach(Context context) {
super.onAttach(context);
try {
mOnRecycleClick=(OnRecycleClick) context;
}catch (ClassCastException e){
//TODO therows new Execption
}
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@SuppressLint("StaticFieldLeak")
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.fragment_recipe_recycle,container,false);
final RecyclerView recyclerView=view.findViewById(R.id.recycle_recipe);
//final Context context=container.getContext();
if(savedInstanceState!=null){
mRecipes= (Recipes[]) savedInstanceState.getParcelableArray("Recipes");
}
final SimpleIdlingResource idlingResource = new SimpleIdlingResource();
if (idlingResource != null) {
idlingResource.setIdleState(false);
}
URL url=null;
try {
url=new URL(mURL);
} catch (MalformedURLException e) {
e.printStackTrace();
}
new AsyncTask<URL, Void, String>() {
@Override
protected String doInBackground(URL... urls) {
String jsons="";
try {
jsons= Networkutils.HttpRequest(urls[0]);
} catch (IOException e) {
e.printStackTrace();
}
return jsons;
}
@Override
protected void onPostExecute(String json) {
super.onPostExecute(json);
try {
mRecipes = Networkutils.parseRecipeCard(json);
} catch (JSONException e) {
e.printStackTrace();
}
RecipeCardAdapter recipeCardAdapter= new RecipeCardAdapter(mRecipes,mOnRecycleClick);
mOnRecycleClick.jsonPass(json);
if(mTablet){
GridLayoutManager gridLayoutManager = new
GridLayoutManager(getActivity(), 3);
recyclerView.setLayoutManager(gridLayoutManager);
recyclerView.setHasFixedSize(true);
recyclerView.setAdapter(recipeCardAdapter);
}
else {
LinearLayoutManager linearLayoutManager=new LinearLayoutManager(getContext());
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setHasFixedSize(true);
recyclerView.setAdapter(recipeCardAdapter);
}
if (idlingResource != null) {
idlingResource.setIdleState(true);
}
}
}.execute(url);
return view;
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelableArray("Recipes",mRecipes);
}
}
注意:当我更改MainActivity以扩展Activity而不是AppCompatActivity时,它可以工作,但是支持版本太多
3天内我没有解决此问题。我真的需要帮助
答案 0 :(得分:0)
好:“ setFactory2()”是 NOT 静态;它应该是LayoutInflator类实例的成员。例如:
https://www.programcreek.com/java-api-examples/?class=android.view.LayoutInflater&method=setFactory2
static void setFactory(LayoutInflater inflater, LayoutInflaterFactory factory) {
Factory2 factory2 = factory != null ? new FactoryWrapperHC(factory) : null;
inflater.setFactory2(factory2);
Factory f = inflater.getFactory();
if (f instanceof Factory2) {
forceSetFactory2(inflater, (Factory2) f);
} else {
forceSetFactory2(inflater, factory2);
}
}
建议:
问:您有(XML)布局吗? (他们)配置正确吗?
问:您的Android应用是否可以独立运行(独立于espresso)?