小编Dan*_*n J的帖子

如何转义传递给在Linux上使用exec选项查找的命令

让我把我的问题分解为最简单的例子.

创建包含一行文本的测试文件.

[root@myserver ] /tmp> echo "test ReplaceMe DoNotReplaceMe" > /tmp/daj.txt
Run Code Online (Sandbox Code Playgroud)

我们有一个现有的find命令,我们用它来替换匹配它的所有文件中的文本(在这个例子中,我简化了这个命令只能处理一个文件,并删除了它所做的其他事情).

问题在于它取代了"ReplaceMe"它出现的任何地方,而不仅仅是它本身就是一个单词.

[root@myserver ] /tmp> find /tmp/daj.txt -exec sh -c 'f="{}"; sed -e 's/ReplaceMe/#DONE#/gi' "${f#.}" ' \;
test #DONE# DoNot#DONE#
Run Code Online (Sandbox Code Playgroud)

我写了一个新sed命令,只在它自己是单词时替换"ReplaceMe",而不是当它是另一个单词的子串时.此命令的输出是正确的.

[root@myserver ] /tmp> cat /tmp/daj.txt | sed -e 's/\(\W\)\(ReplaceMe\)\(\W\)/\1#DONE#\3/gi'    
test #DONE# DoNotReplaceMe
Run Code Online (Sandbox Code Playgroud)

当我尝试将更新的sed命令合并到find命令中时,它会中断.看起来我正在遇到逃避问题,但我没有设法通过添加额外的转义来解决它.

[root@myserver ] /tmp> find /tmp/daj.txt -exec sh -c 'f="{}"; sed -e 's/\(\W\)\(ReplaceMe\)\(\W\)/\1#DONE#\3/gi' "${f#.}" ' \;
sh: -c: line 0: syntax error near unexpected token `('
sh: -c: …
Run Code Online (Sandbox Code Playgroud)

linux escaping sed exec find

6
推荐指数
1
解决办法
3730
查看次数

在支持GSM的AVD中没有电话功能

我在Android模拟器(AVD)中添加了GSM支持,但仍然找不到电话功能.我使用以下几个步骤检查:

boolean isTelephony = getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
Run Code Online (Sandbox Code Playgroud)

isTelephony是假的.

FeatureInfo[] featureList = pm.getSystemAvailableFeatures();
Run Code Online (Sandbox Code Playgroud)

featureList不包含"android.hardware.telephony".

添加GSM支持后是否有任何步骤?

谢谢

android telephony android-virtual-device

6
推荐指数
1
解决办法
338
查看次数

使用Android Studio和Gradle的未知类"对象"的Proguard注意事项

我在Android Studio中创建了一个新项目,并使用Gradle构建它.

我已经为发布版本添加了我的Proguard集成,每次运行我的assembleRelease步骤时我都会看到这个注释:

Note: the configuration refers to the unknown class 'Object'
      Maybe you meant the fully qualified name 'java.lang.Object'?
Run Code Online (Sandbox Code Playgroud)

我的Proguard配置文件或Android SDK文件夹中的所有文件都不包含非限定名称Object.

我的build.gradle包括:

buildTypes {
    release {
        runProguard true
        proguardFile 'proguard-project.txt'
        proguardFile getDefaultProguardFile('proguard-android-optimize.txt')

        signingConfig signingConfigs.release
    }
}
Run Code Online (Sandbox Code Playgroud)

当我删除proguardFile上面的两行时,我甚至会看到相同的注释,如果我删除了我的自定义Proguard规则(每次在重建之前进行清理).

我猜这是Gradle的Proguard插件的一个良性问题?

android proguard gradle android-studio

6
推荐指数
2
解决办法
5177
查看次数

Robotium是否可靠地测试活动和碎片的开始速度?

我正在尝试编写黑盒自动化测试来断言"确保登陆页面在启动应用程序的500毫秒内出现"和"确保登录时间不到2秒".我想通过推动真实应用的UI来尽可能地模拟真实用户.

我正在使用Robotium 5.0.1进行黑盒UI测试,我希望添加一些简单的计时代码会很简单.但是,测试似乎在不同的地方间歇性地失败,即使在没有发出网络请求的地方也是如此.看起来在模拟器中本地运行多个测试时会偶尔出现约2秒的延迟(我们还使用CloudBees在云中运行Jenkins测试,尽管我还没有在那里尝试过测试).

Robotium是否适合用于此类测试? 您是否有关于进行这些测试的最佳方法的任何提示?

这是我的测试:

public void testLogin() {
    AppData.getAppData().clear();

    startTimer();
    launchActivity();
    assertTrue(solo.waitForFragmentByTag("landingfragment", 3000));
    stopTimer();
    assertWasQuickerThan(500);

    startTimer();
    solo.clickOnButton("Log In");
    assertTrue(solo.waitForFragmentByTag("loginfragment", 3000));
    stopTimer();
    assertWasQuickerThan(500);

    solo.enterText(0, TestUtils.EXISTING_USER_EMAIL);
    solo.enterText(1, TestUtils.EXISTING_USER_PASSWORD);

    startTimer();
    solo.clickOnButton("Next");
    assertTrue(solo.waitForActivity(LaunchActivity.class, 3000));
    stopTimer();
    assertWasQuickerThan(2000);
}
Run Code Online (Sandbox Code Playgroud)

这是logcat(这表示登陆页面出现在16ms内,但按下登录按钮后,登录页面出现了2079ms):

03-12 14:46:11.535      386-571/system_process I/ActivityManager? START u0 {cmp=com.example/com.example.ui.LaunchActivity} from pid 1180
03-12 14:46:11.555    1180-1193/com.example D/MyApp? LoginTest: Step took 16ms to complete,
03-12 14:46:12.035    1180-1180/com.example D/dalvikvm? GC_FOR_ALLOC freed 1470K, 47% free 3456K/6424K, paused 96ms, total 98ms
03-12 14:46:12.045    1180-1180/com.example I/dalvikvm-heap? Grow heap (frag case) …
Run Code Online (Sandbox Code Playgroud)

performance android automated-tests robotium

6
推荐指数
1
解决办法
582
查看次数

在Android Studio中的Android项目中运行快速JUnit测试的最佳方法

我在Android Studio项目中有一些简单的旧Java类和简单的JUnit测试.他们目前住在我的Android模块中.如果我将它们作为Android测试运行它们会很好地通过,但它们确实很慢,因为它需要启动或连接到模拟器.

如果我尝试运行一个作为JUnit测试,我遇到了!!! JUnit version 3.8 or later expectedJUnit版本问题.此答案解释了如何解决该问题.不幸的是,我然后点击了java.lang.NoClassDefFoundError: junit/textui/ResultPrinter,我无法弄清楚如何解决.

然后我尝试将我的JUnit测试移动到依赖于Android模块的单独Java模块中.一切都很好.我添加了一个新配置来启动JUnit测试(:MyJUnitTests:test),但测试失败了package com.myproject.util does not exist.看起来类似路径可能不包括依赖Android模块中的类.

有人知道如何解决这个类路径问题吗?我看了很多相关的答案,但似乎没有一个对我有用.或者尝试将JUnit测试保存在自己的模块中是一个坏主意?

我可以让JUnit测试快速运行并传递,如果我将我的普通Java类及其JUnit测试移动到一个完全独立的模块(例如此处),并反转依赖性,以便Android模块依赖于Java模块.这是首选解决方案吗?

junit android unit-testing gradle android-studio

6
推荐指数
1
解决办法
2243
查看次数

processViewSoSupportEmoji中的TextView StringIndexOutOfBoundsException和IndexOutOfBoundsException崩溃

我收到了少量的Crittercism崩溃报告,堆栈跟踪类似于下面的堆栈跟踪.崩溃不是源于我的代码.

此论坛帖子表明,可能是由于TextView的自定义OEM实施中的错误:https://groups.google.com/forum/ fromgroups =#!topic / android-Developers/_53F4WBM8-I

任何人都可以确认是否是这种情况?即使很少有用户受到影响,我也有兴趣知道是否有修复/解决方法?

到目前为止,我的崩溃报告显示这些设备受到影响

  • OS 2.3.6上的ALCATEL ONE TOUCH 903
  • OS 2.3.6上的ALCATEL ONE TOUCH 918D
  • OS 2.3.6上的ALCATEL ONE TOUCH 991D
  • 操作系统2.3.5上的Parrot
  • OS 2.3.4上的A102S_MULA
  • OS 2.3.5上的T9199 +
  • OS 2.3.6上的Trident A7

堆栈跟踪StringIndexOutOfBoundsException:

java.lang.StringIndexOutOfBoundsException
at  java.lang.String.getChars(String.java:1059)
at  android.text.SpannableStringInternal.getChars(SpannableStringInternal.java:102)
at  android.text.TextUtils.getChars(TextUtils.java:101)
at  android.text.Layout.processToSupportEmoji(Layout.java:3752)
at  android.text.Layout.supportTabandEmoji(Layout.java:3790)
at  android.text.Layout.measureText2(Layout.java:3148)
at  android.text.Layout.getDesiredWidth2(Layout.java:183)
at  android.text.Layout.getDesiredWidth2(Layout.java:161)
at  android.widget.TextView.onMeasure2(TextView.java:5950)
at  android.widget.TextView.onMeasure(TextView.java:6163)
at  android.view.View.measure(View.java:8396)
at  android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:612)
at  android.widget.RelativeLayout.onMeasure(RelativeLayout.java:396)
at  android.view.View.measure(View.java:8396)
at  android.widget.ListView.setupChild(ListView.java:1862)
at  android.widget.ListView.makeAndAddView(ListView.java:1789)
at  android.widget.ListView.fillDown(ListView.java:705)
at  android.widget.ListView.fillFromTop(ListView.java:762)
at  android.widget.ListView.layoutChildren(ListView.java:1625)
at  android.widget.AbsListView.onLayout(AbsListView.java:1299)
at …
Run Code Online (Sandbox Code Playgroud)

android textview

5
推荐指数
0
解决办法
1082
查看次数

如何使用 Gradle 运行一组特定的 Android 检测测试?

我有多个测试包:

com.mypackage.blackbox    - Robotium UI tests
com.mypackage.integration - REST integration tests
com.mypackage.unit        - low level unit tests
Run Code Online (Sandbox Code Playgroud)

我们的服务器团队需要能够在每次推送时只运行集成测试(它们需要几分钟),然后每晚运行所有测试(黑盒 UI 测试需要超过 10 分钟)。

这个很好的答案通过重载现有的 JUnit 注释(如@SmallTest或),提供了一种稍微笨拙(但有效)的方法@LargeTest

Gradle 文档建议测试过滤器是这样做的方法,例如

./gradlew connectedAndroidTestDevDebug --tests com.mypackage.integration.*
Run Code Online (Sandbox Code Playgroud)

但是,这会失败并出现> Unknown command-line option '--tests'.错误(大概是因为 Android Gradle 插件不支持 vanilla Gradle 所做的一切?)。

同一份文件说,他们计划在未来支持这些替代方案:

  • 基于自定义注解的过滤(未来)
  • 基于测试层次的过滤;执行扩展ceratain基类的所有测试(未来)
  • 基于某些自定义运行时规则的过滤,例如系统属性的特定值或某些静态(未来)

有没有人知道一种干净的方法来让它现在工作?现在,我计划@MediumTest在所有集成测试扩展的基类上使用注释,但我希望能够指定特定的包。使用@MediumTest@LargeTest滥用这些注释,因为我的集成和黑盒测试都是根据指南进行的大型测试。

continuous-integration android android-studio android-gradle-plugin

5
推荐指数
1
解决办法
4785
查看次数

如何在build.gradle依赖项的命令行调用中包含applicationId?

我正在尝试按照此要点禁用系统动画:

task grantAnimationPermission(type: Exec, dependsOn: 'installDevDebug') {
    commandLine "adb shell pm grant $android.defaultConfig.applicationId android.permission.SET_ANIMATION_SCALE".split(' ')
}

tasks.whenTaskAdded { task ->
    if (task.name.startsWith('installDevDebugAndroidTest')) {
        task.dependsOn grantAnimationPermission
    }
}
Run Code Online (Sandbox Code Playgroud)

每当运行调试版本时,此代码都会尝试用来adb授予SET_ANIMATION_SCALE权限(上述代码的替代方案也可以).

不幸的是,当我运行它时,applicationId总是出现为null:

$ ./gradlew installDevDebugAndroidTest
<snip>
:CookBrite:grantAnimationPermission
Bad argument: java.lang.IllegalArgumentException: Unknown package: null
Run Code Online (Sandbox Code Playgroud)

如果我打印$android.defaultConfig,似乎确认applicationId为null:

ProductFlavor_Decorated{name=main, minSdkVersion=ApiVersionImpl{mApiLevel=14, mCodename='null'}, targetSdkVersion=ApiVersionImpl{mApiLevel=21, mCodename='null'}, renderscriptTargetApi=null, renderscriptSupportModeEnabled=null, renderscriptNdkModeEnabled=null, versionCode=119, versionName=1.1.4, applicationId=null, testApplicationId=null, testInstrumentationRunner=android.support.test.runner.AndroidJUnitRunner, testHandleProfiling=null, testFunctionalTest=null, signingConfig=null, resConfig=null, mBuildConfigFields={}, mResValues={}, mProguardFiles=[], mConsumerProguardFiles=[], mManifestPlaceholders={}}
Run Code Online (Sandbox Code Playgroud)

即使我的工作build.gradle很乐意支持更改所有构建版本的包名称.救命!

我也尝试将build.gradle的这些新部分包装在一个afterEvaluate部分中,但这似乎阻止它们运行(可能因为tasks.whenTaskAdded在评估后不起作用).

android build.gradle android-gradle-plugin

5
推荐指数
0
解决办法
543
查看次数

使用v7支持库AlertDialog时Robolectric InflateException

使用正常android.app.AlertDialog工作ShadowAlertDialog.getLatestAlertDialog(),但如果您使用支持库android.support.v7.app.AlertDialog,则会发生以下异常:

android.view.InflateException: XML file app/build/intermediates/res/qa/debug/layout/abc_alert_dialog_material.xml line #-1 (sorry, not yet implemented): Error inflating class android.support.v7.internal.widget.DialogTitle
    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:713)
    at android.view.LayoutInflater.rInflate(LayoutInflater.java:755)
    at android.view.LayoutInflater.rInflate(LayoutInflater.java:758)
    at android.view.LayoutInflater.rInflate(LayoutInflater.java:758)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
    at uk.co.chrisjenx.calligraphy.CalligraphyLayoutInflater.inflate(CalligraphyLayoutInflater.java:60)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:353)
    at android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:249)
    at android.support.v7.app.AppCompatDialog.setContentView(AppCompatDialog.java:75)
    at android.support.v7.app.AlertController.installContent(AlertController.java:216)
    at android.support.v7.app.AlertDialog.onCreate(AlertDialog.java:240)
    at android.app.Dialog.dispatchOnCreate(Dialog.java:361)
    at android.app.Dialog.show(Dialog.java:262)
    at org.robolectric.shadows.ShadowDialog.show(ShadowDialog.java:65)
    at android.app.Dialog.show(Dialog.java)
<snip>
Caused by: java.lang.StringIndexOutOfBoundsException: String index out of range: -9
    at java.lang.String.substring(String.java:1955)
    at org.robolectric.res.ResName.qualifyResName(ResName.java:51)
    at org.robolectric.res.Attribute.getStyleReference(Attribute.java:147)
    at org.robolectric.res.builder.XmlFileBuilder$XmlResourceParserImpl.getResourceId(XmlFileBuilder.java:789)
Run Code Online (Sandbox Code Playgroud)

这是一个已知问题,但解决问题的最佳方法是什么?
https://github.com/robolectric/robolectric/issues/1736

android robolectric android-alertdialog android-support-library

5
推荐指数
1
解决办法
981
查看次数

如何在Android中以编程方式打开/更改Google Ads退出设置?

有没有一种简单的方法可以帮助用户Opt out of Ads Personalization在应用程序内更改其设置?

可以从Android设置应用中手动打开,方法是浏览至Google->广告:

ads_opt_out

我知道可以使用Settings类以编程方式打开很多“设置”屏幕,例如

Intent intent = new Intent(Settings.ACTION_NFC_SETTINGS);
activity.startActivity(intent);
Run Code Online (Sandbox Code Playgroud)

但是,我看不到打开Ads屏幕的选项。

我也知道Google Play服务提供了一些有用的实用程序,可让用户调整其位置设置,例如LocationSettingsRequest

设置是否有相似之处Ads

settings android google-play-services

5
推荐指数
1
解决办法
563
查看次数