【问题标题】:How to programmatically clear application data如何以编程方式清除应用程序数据
【发布时间】:2011-06-18 22:07:58
【问题描述】:

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

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

【问题讨论】:

  • 应用启动之间使用adb工具清除数据是否可行? adb -w
  • 很遗憾,此选项不可用(adb 帮助已过时)。
  • 这太好了。在调试数据库问题时,我不得不导航到“清除数据”选项,这真的打乱了我的流程。
  • 这里讨论了如何通过 Android Studio 进行操作:stackoverflow.com/q/31713579/905686
  • 具体来说,这样做:stackoverflow.com/a/57461180/94557

标签: android


【解决方案1】:

您可以使用包管理器工具清除已安装应用的数据(类似于在设备上的应用设置中按“清除数据”按钮)。 所以使用 adb 你可以这样做:

adb shell pm clear my.wonderful.app.package

【讨论】:

  • 在 Android 2.1-update1 上,不幸的是,这会产生 Error: unknown command 'clear'
  • @Palani:适用于 2.1-r1 (andoid-7) 以上的任何版本。有任何错误信息吗?
  • 以上命令连接到android shell并在android中执行“pm clear my.wonderful.app.package”。在我的设备中,“pm”命令没有“clear”选项。它与sdk无关。这取决于设备固件。
  • 我正在从我的 android 应用程序中以编程方式在 android 设备中寻找浏览器(默认)和 chrome 浏览器应用程序的清晰数据。请帮忙..
  • 不适用于所有设备,但适用于它的设备非常棒
【解决方案2】:

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

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

【讨论】:

  • 如果你有任何测试代码在此之后运行,它会失败。
  • 执行此操作是否需要在清单中声明权限?
  • 不,它不需要任何特殊权限。
  • 谢谢,你救了我的命!
  • 如果我不想强制关闭应用程序然后?
【解决方案3】:

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

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

对于清除应用程序数据库,这个答案是正确的 -> Clearing Application database

【讨论】:

    【解决方案4】:

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

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

    【讨论】:

    • 仅供参考,调用它会终止您的应用程序。
    【解决方案5】:

    检查此代码:

    @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】:

      如果您只有几个共享偏好需要清除,那么this solution is much nicer

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

      【讨论】:

      • 这不需要启用"instrumentation mode"吗?那到底是什么模式?
      • 是的,这需要一个“仪表化”应用程序,即您的测试与您的应用程序代码一起在真实设备上运行in process,这意味着您可以访问所有应用程序的状态并在运行时更改它以进行测试。
      • 什么应该在 (...) 中?
      • @NickUnuchek 首选项文件的名称。
      【解决方案7】:

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

      【讨论】:

        【解决方案8】:

        最简单的方法是

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

        这将清除数据并从内存中删除您的应用。相当于 Settings --> Application Manager --> Your App --> Clear data 下的 clear data 选项。

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

        【讨论】:

        【解决方案9】:

        这个解决方案真的帮助了我:

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

            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;
        }
        

        【讨论】:

          【解决方案10】:

          如果 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;
              }
          

          【讨论】:

            【解决方案11】:

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

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

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

            只需在您的任何测试和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 + 堆栈跟踪
            • 录制视频 (mp4)
            • 转储数据库 (sqlite)
            • 转储默认共享首选项 (xml)
            • 收集 dumpsys 文件,例如:battery、netstats 等。

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

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

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

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

            【讨论】:

              【解决方案12】:

              Sebastiano 添加的这种方式没问题,但是当您从 IntelliJ IDE 运行测试时添加:

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

              而不仅仅是“pm package...”

              更重要的是:在 driver.setCapability(App_package, package_name) 之前添加它。

              【讨论】:

                猜你喜欢
                • 2014-06-22
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2014-07-21
                • 1970-01-01
                • 2021-10-07
                • 1970-01-01
                相关资源
                最近更新 更多