我遇到的问题表明,为给定活动的layoutXML 选择的资源桶与从values文件夹中选择的资源不一致,尽管在每组文件夹中使用完全相同的资源限定符.
在我的应用程序的抽象父活动中放置一些日志代码后,我可以看到,当通过Nexus 7类型模拟器(Android 4.1)启动我的应用程序时,最小宽度确实是600dp,该layout-sw600dp-*文件夹用于获取活动的UI但是用于valuesis的文件夹values-large-*.我希望这能values-sw600dp-*为我提供关于活动所运行的资源桶的重要信息.
代码在我的应用程序的父活动中记录所有android.app.Activitys
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final Configuration config = getResources().getConfiguration();
Log.i(this.getClass().getSimpleName(), String.format("Smallest width is [%s]", config.smallestScreenWidthDp));
configurationContext = SupportedDeviceConfiguration.fromResourceQualifer(getString(string.resourceQualifier));
Log.i(this.getClass().getSimpleName(), String.format("Running under the [%s] configuration context.", configurationContext.getResourceQualifier()));
...
Run Code Online (Sandbox Code Playgroud)
记录在Nexus 7类型设备上运行此代码时的输出;
[Logging fluff] Smallest width is [600]
[Logging fluff] Running under the [layout-large-land] configuration context.
Run Code Online (Sandbox Code Playgroud)
我知道你在想什么 - 那个布局大片土地的衍生来自哪里?继续阅读......
我正在试验这里概述的方法,这将允许我在运行时检查正在使用的资源桶.基本上我实现的方法具有以下资源限定符结构;
- res …Run Code Online (Sandbox Code Playgroud) android android-layout android-screen-support android-resources
我一直在试用Google API for Android OSS许可证工具并遇到问题.
该活动正在从包含首选项方面的库模块启动到我的应用程序.但是,Play服务代码崩溃了很多!有没有人在点击找到的OSS列表项目时看到这个?
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.oceanlife/com.google.android.gms.oss.licenses.OssLicensesActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.app.ActionBar.setTitle(java.lang.CharSequence)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2665)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.app.ActionBar.setTitle(java.lang.CharSequence)' on a null object reference
at com.google.android.gms.oss.licenses.OssLicensesActivity.onCreate(Unknown Source)
at android.app.Activity.performCreate(Activity.java:6679)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2618)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
at android.os.Handler.dispatchMessage(Handler.java:102) …Run Code Online (Sandbox Code Playgroud) 像许多其他人一样,我很高兴听到Mockito现在可以使用Android并按照本教程亲眼看到它.一切似乎都是扇动的,我开始将模拟解决方案纳入我的Android测试项目...
然而,在建立我的应用程序的测试项目,以充分利用mockito-all-1.9.5,dexmaker-1.0而且dexmaker-mockito-1.0罐子我遇到一个问题,我的第一个测试案例.事实上恰恰是这个问题.我想要帮助的部分是;
Caused by: java.lang.VerifyError: org/mockito/cglib/core/ReflectUtils
at org.mockito.cglib.core.KeyFactory$Generator.generateClass(KeyFactory.java:167)
at org.mockito.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
at org.mockito.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:217)
at org.mockito.cglib.core.KeyFactory$Generator.create(KeyFactory.java:145)
at org.mockito.cglib.core.KeyFactory.create(KeyFactory.java:117)
at org.mockito.cglib.core.KeyFactory.create(KeyFactory.java:109)
at org.mockito.cglib.core.KeyFactory.create(KeyFactory.java:105)
at org.mockito.cglib.proxy.Enhancer.<clinit>(Enhancer.java:70)
Run Code Online (Sandbox Code Playgroud)
我被告知这个"还没有完全奏效",因为堆栈跟踪意味着没有使用DexMaker jar - 引用此响应.但是,我怀疑我在项目设置方面做错了所以我想从这里的集体知识库中抽取来看看这确实是用户错误还是beta-bug.
请在下面找到我的测试项目配置的屏幕截图.该项目是通过Android向导创建的,除了在目录下包含Mockito和DexMaker jar(如上所述)之外,没有共享任何特殊功能libs.

不要介意测试内容(测试在执行单元测试之前失败),设置如下所述;
public class TestSpotRatingCalculator extends InstrumentationTestCase {
@Mock
private AService aService; // Changed the service names being used here - not important.
@Mock
private BService bService;
@Mock
private CService cService;
@Mock
private DService …Run Code Online (Sandbox Code Playgroud) 我正在尝试测试我正在对我的Android服务进行的一系列更改(android.app.Service) - 我正在使用Dagger和Robolectric,我需要使用一些模拟来替换服务中的字段注入类以减少测试范围. .(稍微)更多'单位'之类的.
我注入Providers.of(Guice语法那里......)到我的android.app.Service.如何在单元测试期间用MockProviders替换它们?
这就是相关服务代码的样子;
@Inject SpotService spotService;
@Inject Provider<SynchroniseTidePosition> syncTidePosition;
@Inject Provider<SynchroniseSwellDataTask> syncBuoyData;
@Inject Provider<SynchroniseConditionsTask> syncConditionsData;
@Inject SpotRatingCalculator spotRatingCalculator;
@Inject LocalBroadcastManager localBroadcastManager;
@Inject NotificationManager notificationManager;
/**
* @see android.app.Service#onCreate()
*/
@Override
public void onCreate() {
super.onCreate();
inject(this);
...
Run Code Online (Sandbox Code Playgroud)
因此,在正常操作下,startService(intent)调用允许服务注入它的依赖关系,onCreate并且我们都很好.
根据我的测试,我想用Mockito模拟替换注入的Providers get()调用.我试图遵循Dagger测试示例并创建一个看起来像这样的测试模块;
@Module(includes = OceanLifeModule.class,
injects = {TestSynchronisationServiceNotifications.class},
overrides = true)
static class TestSynchronisationServiceNotificationsModule {
@Provides LocalBroadcastManager provideLocalBroadcastManager() {
return LocalBroadcastManager.getInstance(Robolectric.application);
} …Run Code Online (Sandbox Code Playgroud) 猜猜看,另一个Android-Bitmap-OOM问题!
背景
虽然压力测试我们的应用程序,但已经注意到,可以在持续的大量使用(像猴子赛跑者)之后最大化应用程序的进程内存分配,OutOfMemory并在随后的堆栈跟踪中记录异常.当选择a下的页面时,应用程序会下载图像(一次大约3个)ViewPager.当应用程序的长度和呼吸被执行时,可以下载280多个图像.该应用程序使用Picasso by Square进行图像下载抽象.值得注意的是,在我们的应用程序代码中,我们没有直接操作Bitmaps ...我们相信,非常有才华的Square Inc.员工正在做得比我们更好.
这是一张照片
下图显示了dalvikvm-heap日志消息下记录的堆分配.红点表示用户将一组新文章带入应用程序,以加强未完成的工作量并对应用程序施加压力......
DALVIKVM堆分配http://snag.gy/FgsiN.jpg 图1: Nexus One堆分配; OOM发生在80MB +
到目前为止的调查
针对Nexus S,Nexus 4,Wildfire,HTC Incredible以及众多其他测试设备,轶事测试表明,内存管理足以让DVM GC"跟上"应用程序完成的繁重工作.然而,在诸如Galaxy S II,III,IV和HTC One的高端设备上,OOM是普遍的.事实上,如果有足够的工作要做,我会想象我们所有的设备最终都会出现故障.
这个问题
屏幕密度(我们请求的图像大小基于ImageView的大小),进程内存分配和给定大小的图像数量之间存在明显的关系,这将导致应用程序超出其堆限制.我即将开始量化这种关系,但希望SO社区能够关注这个问题,并且(a)同意或不同意这种关系是值得的,以及(b)提供文献,说明如何最好地建立这种关系.
重要的是要注意,如果我们破坏图像质量,我们的OOM都会消失,但是唉UX越来越差,这就是为什么我们想要最有效地使用可用堆来进行切割.
附注:这是负责将这些图像加载到已经布局的视图中的代码部分;
picassoInstance.load(entry.getKey())
.resize(imageView.getMeasuredWidth(),
imageView.getMeasuredHeight())
.centerCrop()
.into(imageView);
Run Code Online (Sandbox Code Playgroud)
上面提到的"图像质量的潇洒"只是将imageView.getMeasured...数字除以"4"之类的数字.
我在Android 6.0,Marshmallow上遇到了日期格式问题.抛出下面提到的异常的代码是我的应用程序用于API请求("客户端")的纯Java库(单独构建).该库是用Java 1.6构建的,如果它是相关的...无论如何,这是代码;
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd E hh:mm aa", Locale.UK);
Date eventDate = dateFormat.parse(StringUtils.substring(record, 0, 23).trim());
Run Code Online (Sandbox Code Playgroud)
...... record有价值;
2015-10-23 Fri 10:59 PM BST 3.60 meters
Run Code Online (Sandbox Code Playgroud)
......"修剪"之后;
2015-10-23 Fri 10:59 PM
yyyy-MM-dd E hh:mm aa
Run Code Online (Sandbox Code Playgroud)
这段代码自Froyo的古老时代以来一直有效,并经过单元测试.除了棉花糖之外,抛出异常;
10-23 21:01:56.816 4091-4110/com.oceanlife E/ParseException: SynchroniseTidePosition.doInBackground
10-23 21:01:56.816 4091-4110/com.oceanlife E/ParseException: java.text.ParseException: Unparseable date: "2015-10-23 Fri 10:59 PM" (at offset 21)
10-23 21:01:56.816 4091-4110/com.oceanlife E/ParseException: at java.text.DateFormat.parse(DateFormat.java:579)
10-23 21:01:56.816 4091-4110/com.oceanlife E/ParseException: at com.oceanlife.rover.handler.XTideParser.parseResponse(XTideParser.java:69)
10-23 21:01:56.816 4091-4110/com.oceanlife E/ParseException: at com.brantapps.oceanlife.task.SynchroniseTidePosition.doInBackground(SynchroniseTidePosition.java:107)
10-23 21:01:56.816 4091-4110/com.oceanlife E/ParseException: at …Run Code Online (Sandbox Code Playgroud) 我为我的应用程序构建了一个API,它位于一个带有请求限制的网关后面.在我构建API之前,我的应用程序协调自己的请求,因此可以在几毫秒内启动许多请求,以便在用于获取数据的9个提供程序之间同步应用程序的数据.现在,这个逻辑被推到了我的API适配器层,我需要考虑如何控制每秒的请求数量,以避免达到我自己的速率限制.提高速率限制不是一种选择,因为它需要网关提供商中的一个层级冲击,我不愿意支付.
为了在Java社区内进行这种强有力的运动,我选择将RxJava与Retrofit和Retrolamba一起用于我构建的API SDK.这基本上是成功的,并且在没有问题的情况下在现场运行.
现在,我的应用程序允许用户保存"点",当同步检索该区域的当地天气,潮汐和膨胀条件时.每个点使用4个API资源来获得完整的数据集,具体而言;
/luna/locations/xtide/{id} - Luna Event detail (read: tide times)
/solar/locations/xtide/{id} - Solar Event detail (read: sunrise/sunset)
/water/locations/{provider}/{id}{?daysData} - Water Event detail (read: swell measures)
/meteo/wwo/weather{?query,daysData} - Meteo Event detail (read: weather data)
Run Code Online (Sandbox Code Playgroud)
该应用程序允许任意数量的点,n意味着使用当前代码我每个点有4n个请求.例如,如果我保存了10个点并尝试同步 - 我将导致4*10 = 40个API请求在0.75秒左右被触发!
我想使用Rx来简化我的API请求的自我编程过程.这是我希望实现的(希望是准确的)大理石图表;
该SynchronisationService.java代码看起来有点像这样;
Observable.zip(
Observable.from(spots),
Observable.interval(SYNC_TICK, TimeUnit.MILLISECONDS),
(obs, timer) -> obs)
.subscribeOn(scheduler)
.observeOn(scheduler)
.unsubscribeOn(scheduler)
.flatMap(spot -> syncTidePosition.get().buildObservable(spot))
.subscribe(spotAndTideEvent -> new TideEventSubscriber(
lunaEventService,
synchronisationIntentProvider.get(),
spotAndTideEvent.spot,
String.format( …Run Code Online (Sandbox Code Playgroud) 其他Dagger用户……我是在尝试做一些不可能的事情吗?下面是我的应用程序的degraph生成的 Gradle 模块视图。
想象一下我的应用程序有一个导航抽屉。我希望基于通过多重绑定填充的集合添加抽屉中的列表项。这种多重绑定的贡献者跨越 > 1 个 Gradle 模块。例如,从user模块中添加了一个名为“帐户”的列表项,从模块中添加了一个名为“条款和条件”的第二项,legal并从searchGradle 模块中添加了一个“搜索”导航条目。这些模块可以被认为是独立的应用程序,捆绑在一起形成完整的应用程序体验。它们可以自己运行。
关于此的 Dagger 文档看起来像是 Guice 的复制粘贴,但有一个很大的复杂性。它指出;
“Dagger 允许您将多个对象绑定到一个集合中,即使这些对象使用多重绑定绑定在不同的模块中。”
...但这意味着 Dagger @Modules,对吗?是否可以跨 Gradle 模块填充多重绑定?我已经尝试过类似的东西,但这不是我所期望的(并非所有的贡献都被收集了);
父应用
@Module
abstract class PluginModule {
@Multibinds @NavigationContribution abstract Set<NavigationEntry> navigables();
}
Run Code Online (Sandbox Code Playgroud)
legal 包含 Dagger @Module 的 Gradle 模块
@Module
class LegalModule {
@Provides
@NavigationContribution
@IntoSet
static NavigationEntry provideLegalNavigation() {
return ...;
}
}
Run Code Online (Sandbox Code Playgroud)
user 包含 Dagger @Module 的 Gradle 模块
@Module
class AccountModule {
@Provides
@NavigationContribution
@IntoSet …Run Code Online (Sandbox Code Playgroud) 我无法让我的Robolectric单元测试在实验性AS 1.1单元测试变体下运行.我得到的错误如下所示;
java.lang.NoClassDefFoundError: com/my/app/R$string
at com.my.app.MoneyFormatter.formatDealMessage(MoneyFormatter.java:63)
...
Caused by: java.lang.ClassNotFoundException: com.my.app.R$string
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
at org.robolectric.bytecode.AsmInstrumentingClassLoader.loadClass(AsmInstrumentingClassLoader.java:100)
... 46 more
Run Code Online (Sandbox Code Playgroud)
我通过执行从命令行在root(snippet1中的 app-name )命令执行此错误;
./gradlew core:library:test
Run Code Online (Sandbox Code Playgroud)
这种方法适用于Android Studio 1.1,无需启用单元测试,并在v1.0上使用android gradle工具(com.android.tools.build:gradle:1.0.0).
我的项目具有如下规定的复杂结构;
app-name
|
|->app
|->src
|-> androidTest // Espresso helper classes reside here
|-> androidTestFlavour1 // Espresso int tests relating to 'flavour 1'
|-> androidTestFlavour2 // Espresso int tests relating to 'flavour 2'
|-> flavour1
|- … android unit-testing noclassdeffounderror robolectric android-studio
我已将可绘制形状的自定义地图标记添加到我的 Google 地图。这些标记是各种颜色的点。当用户点击其中一个标记时,会从源位置到所选标记绘制一条折线;参见图1 ;
![]](https://i.stack.imgur.com/0JSFS.png)
图 1:我当前的地图
该线直接绘制到由彩色圆点标记的坐标。然而,正如紫色点清楚地表明,标记绘制在顶部 - 我宁愿折线与圆的中心相交,这样从每个角度看的线看起来更像这样;
/] http://milspace.viecorefsd.com/~nlehman/example.png
图 2:所需的折线与圆的交点
为了实现这一点,我试图通过点半径平移支持可绘制的画布。这是我的尝试;
// Circular marker.
final int px = getResources().getDimensionPixelSize(dimen.map_dot_marker_size);
final Bitmap mDotMarkerBitmap = Bitmap.createBitmap(px, px, Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(mDotMarkerBitmap);
final Drawable shape = getResources().getDrawable(drawable.purple_map_dot);
shape.setBounds(0, 0, px, px);
canvas.translate(0, px/2);
shape.draw(canvas);
final MarkerOptions options = new MarkerOptions();
options.position(spot.getNearestCityLatLng());
options.icon(BitmapDescriptorFactory.fromBitmap(mDotMarkerBitmap));
options.title(spot.getNearestCity());
lastLocationSelectionMarker.addMarker(options);
Run Code Online (Sandbox Code Playgroud)
这段代码确实移动了可绘制对象,但支持画布的大小保持不变,这意味着圆圈被切成两半,另一半不可见。
社区能否建议如何最好地实现我在图 2 中所追求的效果,并将标记中心直接放在它所标记的坐标上?
我正在努力将我们的Android团队转移到基于云的CI解决方案上.公司内部的其他部门已经完成了这项任务,我们有一个企业TeamCity许可证,利用安装了Docker的Linux EC2.整个公司使用TC,所以虽然CircleCI等是很好的选择,但我正在探索使用我们自己的TC解决方案.
到目前为止,它已经运行良好并使用Amazon ECR,我们托管了我们的Docker镜像,其中安装了所需的Android SDK,Gradle和Java组件.由于运行一些Robolectric测试用例时出错,我们的构建大部分时间都是正常的,但仍然比我们的物理本地代理更失败.谁看过这个吗?
java.lang.NoClassDefFoundError: java.lang.NoClassDefFoundError: Landroid/content/res/Resources;
java.lang.NoClassDefFoundError: Landroid/content/res/Resources;
at java.lang.Class.getDeclaredFields0(Native Method)
at java.lang.Class.privateGetDeclaredFields(Class.java:2583)
at java.lang.Class.getDeclaredFields(Class.java:1916)
at org.junit.runners.model.TestClass.getSortedDeclaredFields(TestClass.java:77)
at org.junit.runners.model.TestClass.scanAnnotatedMembers(TestClass.java:70)
at org.junit.runners.model.TestClass.<init>(TestClass.java:57)
at org.junit.runners.ParentRunner.createTestClass(ParentRunner.java:88)
at org.junit.runners.ParentRunner.<init>(ParentRunner.java:83)
at org.junit.runners.BlockJUnit4ClassRunner.<init>(BlockJUnit4ClassRunner.java:65)
at org.robolectric.internal.SandboxTestRunner$HelperTestRunner.<init>(SandboxTestRunner.java:242)
at org.robolectric.RobolectricTestRunner$HelperTestRunner.<init>(RobolectricTestRunner.java:467)
at org.robolectric.RobolectricTestRunner.getHelperTestRunner(RobolectricTestRunner.java:319)
at org.robolectric.internal.SandboxTestRunner$2.evaluate(SandboxTestRunner.java:188)
at org.robolectric.internal.SandboxTestRunner.runChild(SandboxTestRunner.java:109)
at org.robolectric.internal.SandboxTestRunner.runChild(SandboxTestRunner.java:36)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.robolectric.internal.SandboxTestRunner$1.evaluate(SandboxTestRunner.java:63)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.runTestClass(JUnitTestClassExecuter.java:114)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.execute(JUnitTestClassExecuter.java:57)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassProcessor.processTestClass(JUnitTestClassProcessor.java:66)
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:51)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32)
at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93) …Run Code Online (Sandbox Code Playgroud)