我想创建第二个构建类型,它应该与现有的调试类型完全一样.目前我有两种构建类型:调试和发布.可以通过单击运行调试版本,并使用调试密钥库自动签名.我通过Build -> Generate signed APK向导手动编译发布版本.
因此,为了克隆调试构建类型,我首先在app build.graddle文件中添加了名为"local"的第二个构建类型:
buildTypes {
...
debug {
debuggable true
minifyEnabled false
}
local {
debuggable true
minifyEnabled false
}
}
Run Code Online (Sandbox Code Playgroud)
然后我创建app/src/local/res并添加了一些文件.
然后我执行gradle resync并在左侧选项卡中选择新的构建类型:

最后我点击了运行按钮,我希望它能正常工作.这篇IntelliJ帮助文章说调试签名配置是默认的:
这意味着如果您未手动配置工件并在"运行/调试配置:Android应用程序"对话框中选择"部署默认APK"选项,则IntelliJ IDEA将使用证书中的预定义值生成
而是显示此对话框:
当我单击修复按钮时,它会打开整个应用程序模块的签名配置对话框.但是,我不想签署这个apk用于发布,我需要使用调试证书签名.另外我注意到assembleLocal已经创建了一个新的gradle任务,但它生成了一个未对齐的apk.在这个文件夹中,我可以看到常规调试apks在未对齐和最终版本中正确生成.
我怎样才能克隆调试版本类型?
我一步一步跟着正式的入门.我从干净的Linux安装开始,按照"使用本机代码构建项目"选项卡安装所需的所有内容.我还阅读了故障排除部分.我已经使用终端创建了项目.
这是运行时的错误react-native run-android:
Starting JS server...
Building and installing the app on the device (cd android && ./gradlew installDebug)...
ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation.
Could not install the app on the device, read the error above for details.
Make sure you have an Android emulator running or a device connected …Run Code Online (Sandbox Code Playgroud) 我正在尝试编写一个测试用例来验证写入共享首选项的类.我正在使用Android Studio v1.5.
在良好的旧日食中,使用时AndroidTestCase,第二个apk文件被部署到设备,并且可以使用检测上下文运行测试,因此您可以使用检测apk的共享首选项运行测试,而无需更改主apk的现有共享首选项文件.
我花了整个上午试图弄清楚如何在Android Studio测试中获得非空上下文.显然,为eclipse进行的单元测试与Android Studio测试框架不兼容,因为调用getContext()返回null.我以为我在这个问题中找到了答案:
在Android junit测试用例中获取测试项目的上下文
随着旧版本的Android Studio没有完整的测试支持,事情已经发生了变化.所以很多答案都只是黑客攻击.显然现在不是扩展InstrumentationTestCase,AndroidTestCase你应该像这样编写测试:
@RunWith(AndroidJUnit4.class)
public class MyTest {
@Test
public void testFoo(){
Context instrumentationContext = InstrumentationRegistry.getContext();
Context mainProjectContext = InstrumentationRegistry.getTargetContext();
}
}
Run Code Online (Sandbox Code Playgroud)
所以我现在有一个非null的检测上下文,并且该getSharedPreferences方法返回一个似乎有效的实例,但实际上没有写入首选项文件.
如果我做:
context = InstrumentationRegistry.getContext();
Run Code Online (Sandbox Code Playgroud)
然后,SharedPreferences编辑器正确写入和提交,不会抛出任何异常.仔细观察后,我可以看到编辑器正在尝试写入此文件:
data/data/<package>.test/shared_prefs/PREFS_FILE_NAME.xml
Run Code Online (Sandbox Code Playgroud)
但是文件永远不会被创建或写入.
但是使用这个:
context = InstrumentationRegistry.getTargetContext();
Run Code Online (Sandbox Code Playgroud)
编辑器正常工作,并将首选项写入此文件:
/data/data/<package>/shared_prefs/PREFS_FILE_NAME.xml
Run Code Online (Sandbox Code Playgroud)
首选项以私有模式实例化:
SharedPreferences sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE);
Run Code Online (Sandbox Code Playgroud)
据我所知,运行测试后没有测试apk上传到设备.这可能解释了为什么文件不是使用检测上下文编写的.这个上下文是否可能是一个无声地失败的虚假上下文?
如果是这种情况,我怎样才能获得真实的仪器上下文,以便我可以在不改变主项目偏好的情况下编写首选项?
instrumentation android unit-testing android-context android-studio
我在项目中遇到了这个问题:有一系列嵌套对象,例如:类A包含一个B类的实例变量,它实际上有一个类C的实例变量,......,直到我们有一个节点Z级树.
----- ----- ----- ----- -----
| A | ---> | B | ---> | C | ---> | D | ---> ... ---> | Z |
----- ----- ----- ----- -----
Run Code Online (Sandbox Code Playgroud)
每个类为其成员提供getter和setter.父A实例由XML解析器创建,链中的任何对象都为空是合法的.
现在假设在应用程序的某个点上,我们引用了一个A实例,并且只有它包含一个Z对象时,我们必须在它上面调用一个方法.使用定期检查,我们得到以下代码:
A parentObject;
if(parentObject.getB() != null &&
parentObject.getB().getC() != null &&
parentObject.getB().getC().getD() != null &&
parentObject.getB().getC().getD().getE() != null &&
...
parentObject.getB().getC().getD().getE().get...getZ() != null){
parentObject.getB().getC().getD().getE().get...getZ().doSomething();
}
Run Code Online (Sandbox Code Playgroud)
我知道异常不应该用于普通的控制流,但是我看到一些程序员这样做,而不是以前的代码:
try {
parentObject.getB().getC().getD().getE().get...getZ().doSomething();
} catch (NullPointerException e){}
Run Code Online (Sandbox Code Playgroud)
这段代码的问题在于它在维护时可能会混淆,因为它没有清楚地显示允许哪些对象为null.但另一方面更简洁,更不"伸缩".
这样做可以节省开发时间吗?如何重新设计API以避免此问题?
我唯一能想到的就是避免isValid长空检查是为了提供嵌套对象的void实例并为它们中的每一个提供方法,但这不会在内存中创建很多不必要的对象吗?
(我使用过Java代码,但同样的问题可以应用于C#属性)
谢谢.
我想存根一个存储库类来测试另一个具有存储库的类(Holder类).存储库接口支持CRUD操作,并且有很多方法,但我对Holder类的单元测试只需要调用其中的两个.存储库界面:
public interface IRepo {
public void remove(String... sarr);
public void add(String... sarr);
//Lots of other methods I don't need now
}
Run Code Online (Sandbox Code Playgroud)
我想创建一个可以存储的情况下,用于定义逻辑库模拟add和remove唯一的,并提供检查什么叫添加和删除后存储在其上的一种手段.
如果我做:
IRepo repoMock = mock(IRepo.class);
Run Code Online (Sandbox Code Playgroud)
然后我有一个愚蠢的对象,对每种方法都没有任何作用.没关系,现在我只需要定义添加和删除的行为.
我可以创建一个Set<String>和存根只有那两个方法来处理集合.然后我将实例化一个具有IRepo的Holder,注入部分存根模拟,并在执行持有者之后,检查该集以验证它包含它应该是什么.
我设法部分存根一个void方法,比如remove使用弃用的方法stubVoid:
Set<String> mySet = new HashSet<>();
stubVoid(repoMock).toAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments();
String[] stringsToDelete = (String[]) args[0];
mySet.removeAll(Arrays.asList(stringsToDelete));
return null;
}
}).on().remove(Matchers.<String>anyVararg());
Run Code Online (Sandbox Code Playgroud)
但是已被弃用,并且它比为IRepo创建部分实现要好得多.有没有更好的办法?
注意:Java 7只应答,这应该在Android中运行.
我正在尝试处理按钮点击."按钮"是一个自定义div,也可以包含子项.当用户在元素内单击并释放时,应触发单击回调.如果用户单击内部然后拖动并释放到外部,则处理程序不应该触发.我需要在桌面和移动设备上使用它,因此我正在使用mousedown/mouseup和touchstart/touchend事件.
即使用户在外面发布,我也需要将按钮类从"按下"更改为"正常",因此我需要添加一个侦听器来捕获文档上的发布事件:
var $myElement = $("#myelement"); //This is a div and can also contain children.
$myElement.on("mousedown touchstart", function(e){
$(this).addClass("pressed");
$(document).on("mouseup touchend", function listener(e){
$myElement.removeClass("pressed");
$(document).off("mouseup touchend", listener);
var $target = $(e.target);
if ($target.is($myElement) || $target.parents().is($myElement)){
//FIXME
alert("Inside!");
//do something here
return false;
} else {
//FIXME
alert("Outside!");
//let event bubble
}
});
return false;
});
Run Code Online (Sandbox Code Playgroud)
它适用于点击,但它不能按预期的方式使用触摸事件.我在Chrome for Android中进行了测试,当按下元素时,然后拖出"Inside!" 警报显示.
问题出在这种情况:
if ($target.is($myElement) || $target.parents().is($myElement)){
Run Code Online (Sandbox Code Playgroud)
我正在尝试检查touchend按钮或任何子项中是否发生了事件.如果按钮没有子节点,单击它然后释放到外部时,OR子句的第一部分将解析为true.如果按钮有子项并且我单击子项,然后在屏幕的任何其他部分释放,则该子句的第二部分为真.
这段代码有什么问题?
提前致谢.
更新
我在BlackBerry 10中也测试了它,结果相同.显然,touchend事件的目标是按钮(或孩子们),即使我在外面点击也是如此.这是它应该如何工作?
更新
这就是原因.这就是 …
我需要在给定的时间每天设置一个闹钟.我正在使用编程警报AlarmManager.RTC_WAKEUP,因此它使用系统时间作为参考.我将警报设置为首先在所需的小时执行,然后每天重复:
alarmManager.setRepeating(
AlarmManager.RTC_WAKEUP,
getTimestampToday("12:00"),
AlarmManager.INTERVAL_DAY,
pendingIntent
);
Run Code Online (Sandbox Code Playgroud)
该getTimestampToday方法在所需的小时返回今天的长时间戳.它通过获取今天的本地日期,然后设置所需的小时,最后将其转换回时间戳(基于UTC)来实现.
这里的问题是警报应该根据当地时间工作.因此,如果在安排警报后更改时间(例如,DST时间更改,或者用户前往其他国家/地区,或者他手动更改日期,时间或时区),则警报将在错误的当地时间触发下次.
例:
该应用程序应该运行很长一段时间(它是一个仅供企业使用的自助服务终端应用程序).我在应用程序启动时重新安排警报,但这并不能解决我的问题,因为应用程序可以运行数天而无需重新启动.我需要检测时间的变化,以便根据新的本地时间再次安排警报.
我正在使用这个接收器:
<receiver android:name="foo.bar.receivers.TimeChangeReceiver" >
<intent-filter>
<action android:name="android.intent.action.ACTION_TIMEZONE_CHANGED" />
<action android:name="android.intent.action.ACTION_TIME_CHANGED" />
<action android:name="android.intent.action.DATE_CHANGED"></action>
</intent-filter>
</receiver>
Run Code Online (Sandbox Code Playgroud)
它会检测日期更改,但不适用于时间更改或时区更改.(在运行OS 4.0.3的平板电脑上测试过).这真的很奇怪,因为我可以清楚地看到在logcat中广播的事件.
所以我的问题:
ACTION_TIMEZONE_CHANGED和ACTION_TIME_CHANGED事件,我怎么能解决它.提前致谢.
我已经阅读了2小时的logback手册,仍然无法想象如何做我需要的.
它就像标题所说的那样简单:我只想将错误记录到文件中,而将其他级别(包括ERROR)记录到控制台.
这是我的logcat.xml文件的根部分:
<root level="TRACE" >
<appender-ref ref="CONSOLE_APPENDER" />
<appender-ref ref="FILE_APPENDER" />
</root>
Run Code Online (Sandbox Code Playgroud)
此配置的问题是它将每个级别> = TRACE记录到两个appender.
我可以让root用户只用控制台,并定义一个文件记录器:
<logger name='file_logger' level='ERROR' >
<appender-ref ref="FILE_APPENDER" />
</logger>
Run Code Online (Sandbox Code Playgroud)
但是我必须像这样调用普通记录器:
LoggerFactory.getLogger(ClientClass.class);
Run Code Online (Sandbox Code Playgroud)
和文件记录器这样:
LoggerFactory.getLogger("file_logger");
Run Code Online (Sandbox Code Playgroud)
我不想为每个班级选择记录器.我只想使用class as参数从工厂获取根记录器,并根据级别让它做正确的事情.
这可能吗?
我想从单元测试中测试通知是否能够从资产中播放自定义声音.测试并不是为了验证任何东西,我把它写成一种快速的方式来演示一个功能而不会混淆主应用程序代码.
所以在测试项目中,我在里面添加了一个wav文件/res/raw.我将在通知构建器中使用此URL:
Uri path = Uri.parse("android.resource://<main app package name>/testsound.wav");
Run Code Online (Sandbox Code Playgroud)
该URL应该根据我在SO中阅读的问题工作.我们假设它有效.
现在因为我不想将测试wav文件包含在主项目的/res/raw文件夹中但是在测试项目中,我不得不进行单元测试扩展,InstrumentationTestCase以便我可以访问测试项目中的资源.
这是代码:
NotificationCompat.Builder builder = new NotificationCompat.Builder(getInstrumentation().getContext());
...
builder.setSound(path, AudioManager.STREAM_NOTIFICATION);
...
NotificationManager notificationManager = (NotificationManager) getInstrumentation().getContext().getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(NOTIFICATION_ID, builder.build());
Run Code Online (Sandbox Code Playgroud)
该notify调用抛出以下异常:
java.lang.SecurityException: Calling uid 10198 gave package <main app package name> which is owned by uid 10199
at android.os.Parcel.readException(Parcel.java:1540)
at android.os.Parcel.readException(Parcel.java:1493)
at android.app.INotificationManager$Stub$Proxy.enqueueNotificationWithTag(INotificationManager.java:611)
at android.app.NotificationManager.notify(NotificationManager.java:187)
at android.app.NotificationManager.notify(NotificationManager.java:140)
...
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1873)
Run Code Online (Sandbox Code Playgroud)
我已将此异常跟踪到NotificationManagerService课程:
void checkCallerIsSystemOrSameApp(String pkg) {
int uid = Binder.getCallingUid();
if (UserHandle.getAppId(uid) == …Run Code Online (Sandbox Code Playgroud) java notifications android unit-testing android-instrumentation
我的一个应用程序在某些Kitkat Samsung设备中存在严重的活动娱乐问题.拍照时问题会更频繁地出现,并且在Jellybean Samsung具有一半RAM的蹩脚中没有观察到.日志显示内存不足,但没有OutOfMemoryException抛出s.我认为有更积极的活动关闭政策Kitkat(或者默认的相机应用程序漏洞).
当我的应用程序的内存很高时,我想知道操作系统是否会关闭我的活动,或者当所有应用程序使用的总内存很高时,它会关闭它们.如果操作系统具有每个进程阈值,那么可能在不同的进程中打开相机可能会有所帮助.
我知道可以使用process清单中的属性在自己的进程中启动服务.假设不存在等效属性Activities,如果我在自己的进程中启动了代理服务,然后从该服务启动了一个活动,那么活动是否也会在此过程中运行?