如何以编程方式清除应用程序数据

我正在为一个 Android 应用程序开发自动化测试(使用 Robotium)。为了确保测试的一致性和可靠性,我想以清洁状态(被测应用程序的清洁状态)开始每个测试。为了做到这一点,我需要清除应用程序数据。这可以在设置/应用程序/管理应用程序/[我的应用程序]/清除数据中手动完成

以编程方式完成这项工作的推荐方法是什么?

122077 次浏览

你可以用这个来清除 SharedPreferences 应用程序数据

Editor editor =
context.getSharedPreferences(PREF_FILE_NAME, Context.MODE_PRIVATE).edit();
editor.clear();
editor.commit();

对于清除 app db,这个答案是正确的—— > 清除应用程序数据库

检查以下代码:

@Override
protected void onDestroy() {
// closing Entire Application
android.os.Process.killProcess(android.os.Process.myPid());
Editor editor = getSharedPreferences("clear_cache", Context.MODE_PRIVATE).edit();
editor.clear();
editor.commit();
trimCache(this);
super.onDestroy();
}




public static void trimCache(Context context) {
try {
File dir = context.getCacheDir();
if (dir != null && dir.isDirectory()) {
deleteDir(dir);


}
} catch (Exception e) {
// TODO: handle exception
}
}




public static boolean deleteDir(File dir) {
if (dir != null && dir.isDirectory()) {
String[] children = dir.list();
for (int i = 0; i < children.length; i++) {
boolean success = deleteDir(new File(dir, children[i]));
if (!success) {
return false;
}
}
}


// <uses-permission
// android:name="android.permission.CLEAR_APP_CACHE"></uses-permission>
// The directory is now empty so delete it


return dir.delete();
}

你可以使用软件包管理器工具来清除已安装的应用程序的数据(类似于按下设备上应用程序设置中的“清除数据”按钮)。 所以你可以使用 adb:

adb shell pm clear my.wonderful.app.package

如果您只需要清除几个共享首选项,那么就可以清除 这个解决方案好多了

@Override
protected void setUp() throws Exception {
super.setUp();
Instrumentation instrumentation = getInstrumentation();
SharedPreferences preferences = instrumentation.getTargetContext().getSharedPreferences(...), Context.MODE_PRIVATE);
preferences.edit().clear().commit();
solo = new Solo(instrumentation, getActivity());
}

按照@edovino 的回答,通过编程方式清除应用程序的 所有首选项的方法是

private void clearPreferences() {
try {
// clearing app data
Runtime runtime = Runtime.getRuntime();
runtime.exec("pm clear YOUR_APP_PACKAGE_GOES HERE");


} catch (Exception e) {
e.printStackTrace();
}
}

警告 : 应用程序将强制关闭。

从 API 版本19可以调用 ActivityManager.clearApplicationUserData ()。

((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE)).clearApplicationUserData();

使用 背景,我们可以清除应用程序特定的文件,如首选项,数据库文件。 我已经使用下面的代码来使用 Espresso 进行 UI 测试。

    @Rule
public ActivityTestRule<HomeActivity> mActivityRule = new ActivityTestRule<>(
HomeActivity.class);


public static void clearAppInfo() {
Activity mActivity = testRule.getActivity();
SharedPreferences prefs =
PreferenceManager.getDefaultSharedPreferences(mActivity);
prefs.edit().clear().commit();
mActivity.deleteDatabase("app_db_name.db");
}

如果 android 版本在 kitkat 之上,你也可以使用这个

Public void onClick (视图){

    Context context = getApplicationContext(); // add this line
if (Build.VERSION_CODES.KITKAT <= Build.VERSION.SDK_INT) {
((ActivityManager) context.getSystemService(ACTIVITY_SERVICE))
.clearApplicationUserData();
return;
}

以编程方式完成这项工作的推荐方法是什么?

唯一可能的选择是在测试之前运行 ADB 命令 adb shell pm clear package。最大的问题是,将测试执行和 shell 命令结合起来是一种令人头疼的问题。

但是,我们(在 Mediafe)提供了一些解决方案,可以在常规的非根设备上为您工作。您所需要做的就是添加一个注释。其余的工作都是通过运行简单的 Bash 脚本完成的。

只需在任何测试和 tada 之前添加 @ClearData注释,ADB clear 命令将在测试执行之前执行。

这就是这种测试的一个例子:

@Test
@ClearData
public void someTest() {
// your test
}

这个想法是这样的

  1. 使用 adb shell am instrument -e log true读取所有测试
  2. 通过解析(1)的输出来构建执行计划
  3. 逐行运行执行计划

使用相同的想法,你可以很容易地支持这些 所有选择:

  • 数据清晰
  • 清除通知栏
  • 参数化
  • 过滤并按标记运行

只使用注释,像这样:

@Test
@ClearData
@Tags(tags = {"sanity", "medium"})
@Parameterized.Repeat(count = 3)
public void myTest() throws Exception {
String param = params[index];
// ...
}

奖励! 每次失败的测试:

  • 收集 Logcat + stacktrace
  • 录影带(mp4)
  • 转储 DB (sqlite)
  • 转储默认共享首选项(xml)
  • 收集 Dumpsys 文件,如: 电池,netstats 和其他。

一般来说,添加更多选项很容易,因为测试是通过 bash 脚本而不是 gradle 任务逐个执行的。

完整的博客文章: https://medium.com/medisafe-tech-blog/running-android-ui-tests-53e85e5c8da8

带有示例的源代码: https://github.com/medisafe/run-android-tests

希望这回答了6年的问题;)

Sebastiano 添加的这种方式是可以的,但是在运行 IntelliJ IDE 的测试时需要添加:

 try {
// clearing app data
Runtime runtime = Runtime.getRuntime();
runtime.exec("adb shell pm clear YOUR_APP_PACKAGE_GOES HERE");


}

而不是只有“下午包...”

更重要的是: 将其添加到 driver.setability (App _ package,package _ name)之前。