Android 膨胀类片段时出错。无法在google play服务中获取碎片管理器
这是我的Maven项目,我尝试在其中测试GoogleMap活动Android 膨胀类片段时出错。无法在google play服务中获取碎片管理器,android,maven,google-play-services,robolectric,Android,Maven,Google Play Services,Robolectric,这是我的Maven项目,我尝试在其中测试GoogleMap活动 ... <dependency> <groupId>com.almende.eve</groupId> <artifactId>eve-bundle-android-ws</artifactId> <version>3.1.1</version> </dependency>
...
<dependency>
<groupId>com.almende.eve</groupId>
<artifactId>eve-bundle-android-ws</artifactId>
<version>3.1.1</version>
</dependency>
...
该ID对应于R类的常用\u google\u play\u services\u install\u text\u phone constats
如果x.y.z为7.0.0,则具有
android.view.InflateException: XML file ./src/main/res/layout/main.xml line #-1 (sorry, not yet implemented): Error inflating class fragment
at com.eduonix.app.EduonixActivityTest.setup(EduonixActivityTest.java:38)
Caused by: android.content.res.Resources$NotFoundException: String resource ID #0x7f070028
at com.eduonix.app.EduonixActivityTest.setup(EduonixActivityTest.java:38)
java.lang.NoSuchFieldError: MapAttrs_ambientEnabled
at com.eduonix.app.EduonixActivityTest.setup(EduonixActivityTest.java:38)
Android sdk是22,所以8.3.0更为正确,但9.2.0也显示了同样的错误
我的活动是
public class EduonixActivity extends android.support.v4.app.FragmentActivity {
protected com.google.android.gms.maps.GoogleMap map;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main); System.out.println("hello!");
android.support.v4.app.FragmentManager fM = getSupportFragmentManager(); // error line
System.out.println("FragmentManager is initiated"); // this line is not achieved
SupportMapFragment fm = (SupportMapFragment)fM.findFragmentById(R.id.map);
System.out.println("fm is initiated");
map = fm.getMap();
System.out.println("map is initiated");
}
}
当尝试使用Robolectic框架进行测试时,Maven构建过程被破坏
@Config(manifest = "src/main/AndroidManifest.xml")
@RunWith(RobolectricTestRunner.class)
public class EduonixActivityTest {
private EduonixActivity activity;
@Before
public void setup() {
activity = Robolectric.buildActivity(EduonixActivity.class).create().start().get();// error
}
@Test
public void testEduonixActivity() {
assertThat(activity).isNotNull();
}
}
AndroidManifest.xml是
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="2"
android:versionName="1.0.0-SNAPSHOT"
package="com.eduonix.app">
<uses-sdk android:minSdkVersion="22"
android:targetSdkVersion="22"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
<!-- External storage for caching. -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!-- My Location -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<!-- Maps API needs OpenGL ES 2.0. -->
<uses-feature
android:glEsVersion="0x00020000"
android:required="true"/>
<application android:name="com.eduonix.app.EduonixApplication">
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="@string/google_maps_key" />
<activity android:name=".EduonixActivity" android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
任何想法都将受到欢迎。在对android.app.Fragment与android.app.support.v4.Fragment进行了深入的比较之后,答案是:Robolectic无法膨胀碎片,因为谷歌服务无法为其提供。所以,一个解决方案是像这样指定碎片膨胀器
public class MyFragment extends com.google.android.gms.maps.SupportMapFragment{
static private MyFragment fragment = new MyFragment();
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_stub_for_test, container);
return view;
}
// public constructor must be empty
static public MyFragment getInstance(){
return fragment;
}
}
其中,测试存根可以是布局中的一些xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/LinearLayout2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
tools:context="com.example.zheka.gmapexample1.MapsActivity" >
<TextView
android:id="@+id/tvDisplayText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="No Passed Bundle :(" />
</LinearLayout>
对于8.1.0以上版本的play services和play services maps,所有的测试现在都很好。在对android.app.Fragment和android.app.support.v4.Fragment进行了一些深入的比较之后,答案是:Robolectic无法膨胀碎片,因为谷歌服务不适用于它。所以,一个解决方案是像这样指定碎片膨胀器
public class MyFragment extends com.google.android.gms.maps.SupportMapFragment{
static private MyFragment fragment = new MyFragment();
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_stub_for_test, container);
return view;
}
// public constructor must be empty
static public MyFragment getInstance(){
return fragment;
}
}
其中,测试存根可以是布局中的一些xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/LinearLayout2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
tools:context="com.example.zheka.gmapexample1.MapsActivity" >
<TextView
android:id="@+id/tvDisplayText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="No Passed Bundle :(" />
</LinearLayout>
现在,对于8.1.0以上版本的play services和play services maps,所有测试都正常。问题显然是Robolectric无法找到
AndroidManifest
和/或资源。如果是gradle build,它将更容易处理,因为我有很多经验。我会写一些日志来了解Robolectric是否解析了您的AndroidManifest
。我还想看看RobolectricGradleTestRunner
与RobolectricTestRunner
的区别,我真的不知道如何将AndroidManifest解析为Robolectric,它在主文件夹中,或者您可能会假设测试的清单?我测试了FragmentActivity和另外一个从activity扩展而来的activity,它们构建得很好。我没有提到google_play_版本,它实际上低于android的预期。@RunWith(RobolectricGradeleteStrunner.class)没有帮助,它已被弃用。RobolectricGradeleteStrunner
弃用在哪里?来自robolectric:3.2-SNAPSHOT是可以的,但是Eclipse显示它已经被破坏了,问题是Robolectric肯定找不到AndroidManifest
和/或资源。如果是gradle build,它将更容易处理,因为我有很多经验。我会写一些日志来了解Robolectric是否解析了您的AndroidManifest
。我还想看看RobolectricGradleTestRunner
与RobolectricTestRunner
的区别,我真的不知道如何将AndroidManifest解析为Robolectric,它在主文件夹中,或者您可能会假设测试的清单?我测试了FragmentActivity和另外一个从activity扩展而来的activity,它们构建得很好。我没有提到google_play_版本,它实际上比android的预期要低。@RunWith(RobolectricGradleTestRunner.class)没有帮助,它已被弃用。RobolectricGradleTestRunner
deprecated在哪里?来自robolectric:3.2-SNAPSHOT是可以的,但Eclipse显示它已被弃用。
@Config(manifest = "src/main/AndroidManifest.xml"
,shadows = {
//ShadowActivity.class
//,ShadowGooglePlayServicesUtil.class
//ShadowMapsActivity.class
}
)
@RunWith(RobolectricTestRunner.class)
//@RunWith(MyTestRunner.class)
public class ExampleUnitTest {
MapsActivity activity;
android.support.v4.app.Fragment fragment;
@Before
public void setup(){
activity = Robolectric.buildActivity(MapsActivity.class)
.create()
.start() //no activity error can happen, if so just commment
.get();
}
@Test
public void testActivity() {
assertThat(activity).isNotNull();
}
@Test
public void testMap() {
fragment = (SupportMapFragment)activity.getSupportFragmentManager().findFragmentById(R.id.map);
assertThat(fragment).isNotNull();
((SupportMapFragment)fragment).getMapAsync(new OnMapReadyCallback(){
@Override
public void onMapReady(GoogleMap map) {
org.junit.Assert.assertTrue(map!=null);
}
});
}
}