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


152

我正在为android应用程序开发自动化测试(使用Robotium)。为了确保测试的一致性和可靠性,我想以干净状态(正在测试的应用程序)开始每个测试。为此,我需要清除应用数据。可以在“设置/应用程序/管理应用程序/ [我的应用程序] /清除数据”中手动完成此操作

以编程方式完成此操作的推荐方法是什么?


使用adb工具清除应用程序启动之间的数据是否可行?adb -w
smith324'2

不幸的是,此选项不可用(adb帮助已过时)。
user597603 2011年

太好了 在调试数据库问题时,我必须导航至“清除数据”选项,这确实中断了我的流程。
杰森·普拉多

此处讨论了如何通过Android Studio进行操作:stackoverflow.com/q/31713579/905686
user905686

具体而言,请执行以下操作:stackoverflow.com/a/57461180/94557
马特·沃尔夫,

Answers:


171

您可以使用包管理器工具清除已安装应用程序的数据(类似于按设备上应用程序设置中的“清除数据”按钮)。因此,使用adb可以做到:

adb shell pm clear my.wonderful.app.package

1
在Android 2.1-update1上,不幸的是产生Error: unknown command 'clear'
Paul Lammertsma

@Palani:适用于2.1-r1(andoid-7)以上的任何版本。任何错误消息?
edovino 2012年

1
上面的命令连接到android shell并在android中执行“ pm clear my.wonderful.app.package”。在我的设备中,“ pm”命令没有“清除”选项。它与sdk无关。这取决于设备固件。
Palani 2012年

m从我的android应用程序中以编程方式在android设备中查找浏览器(默认)和chrome浏览器应用程序的清晰数据。请帮忙..
Brijesh Patel 2014年

并非在所有设备上都适用,但对于它所使用的设备而言,这是很棒的
Cory Trese 2014年

34

按照@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();
    }
}

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


5
如果在此之后运行任何测试代码,它将失败。
rajath

执行此操作是否需要在清单中声明权限?
reubenjohn

1
不,不需要任何特殊许可。
塞巴斯蒂

谢谢,你救了我的命!
2015年

1
如果我不想强制关闭应用程序呢?
新泽西州2015年

22

您可以使用此方法清除SharedPreferences应用数据

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

对于清除应用程序数据库,此答案是正确的-> 清除应用程序数据库


14

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

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

13
仅供参考,调用此操作将终止您的应用程序。
Zach Rattner 2015年

8

检查此代码以:

@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();
}

6

如果您只有几个共享的首选项需要清除,那么此解决方案会更好

@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());
}

这不要求启用“仪器模式”吗?那到底是什么模式?
ADTC

是的,这需要一个“仪表”的应用,即测试一起运行的应用程序代码在真实设备上的过程,这意味着您可以访问所有应用程序的状态,并改变它的运行时间用于测试目的。
Thomas Keller 2014年

(...)应该是什么?
NickUnuchek 2015年

@NickUnuchek首选项文件的名称。
Thomas Keller

3

使用上下文,我们可以清除应用程序特定的文件,如首选项,数据库文件。我已使用以下代码使用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");
    }

3

最简单的方法是

private void deleteAppData() {
         try {
        // clearing app data
        String packageName = getApplicationContext().getPackageName();
        Runtime runtime = Runtime.getRuntime();
        runtime.exec("pm clear "+packageName);

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

这将清除数据并从内存中删除您的应用程序。这等效于“设置”->“应用程序管理器”->您的应用程序->“清除数据”下的“清除数据”选项。

这将完全删除数据以及强制关闭应用程序


请不要对多个问题添加相同的答案。回答最好的一个,并将其余的标记为重复。请参阅为几个问题添加重复答案是否可以接受?
FelixSFD

1
我们如何在不关闭应用程序的情况下实现这一目标
Omkar Ghurye,

2

这个解决方案确实对我有帮助:

通过使用以下两种方法,我们可以以编程方式清除数据

    public void clearApplicationData() {
    File cacheDirectory = getCacheDir();
    File applicationDirectory = new File(cacheDirectory.getParent());
    if (applicationDirectory.exists()) {
    String[] fileNames = applicationDirectory.list();
        for (String fileName : fileNames) {
            if (!fileName.equals("lib")) {
                deleteFile(new File(applicationDirectory, fileName));
            }
        }
    }
}
    public static boolean deleteFile(File file) {
    boolean deletedAll = true;
    if (file != null) {
        if (file.isDirectory()) {
            String[] children = file.list();
            for (int i = 0; i < children.length; i++) {
                deletedAll = deleteFile(new File(file, children[i])) && deletedAll;
            }
        } else {
            deletedAll = file.delete();
        }
    }

    return deletedAll;
}

2

如果android版本高于kitkat,则也可以使用

public void onClick(View view){

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

0

以编程方式完成此操作的推荐方法是什么?

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

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

只需@ClearData在任何测试和tada before之前添加注释,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)
  • 转储数据库(sqlite)
  • 转储默认共享首选项(xml)
  • 收集dumpsys文件,例如:Battery,netstats等。

通常,添加更多选项很容易,因为测试是从bash脚本而不是gradle任务一个接一个地执行的。

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

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.