【问题标题】:Android: Cant find .html file in res/raw after obfuscationAndroid:混淆后无法在 res/raw 中找到 .html 文件
【发布时间】:2012-03-15 12:11:36
【问题描述】:

我在res/raw 中有一些html 文件,我在WebView 中打开这些文件。但经过混淆后,它们无法加载。

【问题讨论】:

  • 无法加载是什么意思?能否提供用于加载 html 文件的代码?
  • AFAIK,ProGuard 不会混淆资源。您有什么证据表明这个问题与 ProGuard 有关?您如何尝试“加载”这些数据?您的精确错误是什么(如果是运行时异常,包括堆栈跟踪)?
  • 我正在以这种方式加载网址 webView.loadUrl("file:///android_res/raw/help.html");创建混淆构建时出现“未加载网页”。否则它可以在没有混淆构建的情况下工作。
  • 请在此处查看第一个答案:stackoverflow.com/questions/6280188/… 这对我有用。

标签: android proguard


【解决方案1】:

我遇到了完全相同的问题。我有原始的帮助 html 文件,经过混淆处理后,我运行我的应用程序并收到找不到文件的错误。

这是我的 HelpActivity 类:

public class HelpActivity extends BaseActivity
{
  @Override
  protected void onCreate(Bundle savedInstanceState)
  {
      super.onCreate(savedInstanceState);
      // requesting to turn the title OFF
      //requestWindowFeature(Window.FEATURE_NO_TITLE);
      // making it full screen
      getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

      setContentView(R.layout.help);
      setTitle(getString(R.string.help_title));
      WebView webView = (WebView) findViewById(R.id.webView);
      webView.loadUrl("file:///android_" + getString(R.raw.how_to_play_zeewee));
  }
}

我通过将以下内容添加到我的 proguard.cfg 文件来解决此问题:

-keepclassmembers class **.R$* {public static <fields>;}
-keep class **.R$*

您可能已经有了第一行,但这并不能阻止问题。添加第二行完全消除了这个问题。我认为仍然不需要第一行,但我还没有测试过——而且因为它目前可以工作......;)。

【讨论】:

    【解决方案2】:

    建议在answer in this question -

    -keep class **.R$*
    

    不是最优雅的解决方案,因为它指示 ProGuard 保留所有 R 类,无论它们位于哪个包中。

    WebView 有同样的问题,我在我的 Logcat 中看到的错误:

    ... E/AndroidProtocolHandler: 无法打开资源 URL:file:///android_res/raw/$MISSING_RESOURCE_NAME.css java.lang.ClassNotFoundException:找不到类 路径上的“my.app.package.R$raw”:DexPathList[[...

    我添加到proguard-rules.pro 文件中的最大限制指令:

    -keepnames class my.app.package.R$raw { public static <fields>; }
    

    显然由于R类只包含字段并且所有这些字段都具有public static类型,在实践中,上面的和应该没有区别

    -keepnames class my.app.package.R$raw { *; } 
    

    但是,我来了

    1. 不禁用R 中除raw 之外的所有其余内部类的收缩和混淆。
    2. 仅在一个特定包中定位R

      如果您的项目中有多个模块提供自己的资源,而您正在构建的一个特定 APK 可能不需要这些资源(假设有多个 android_application 模块 - APK 源 – 在您的项目中也是如此)。

    要了解-keepnames-keep之间的区别,请参考以下内容。

    Distinguishing between the different ProGuard -keep directives - Tue May 29 04:10:50 MSK 2018

    【讨论】:

    • proguard 规则仅适用于 keep,如果我使用 keepnames 添加规则,webview 将找不到 html。示例:-keep class com.example.appname.R$raw { *; }
    【解决方案3】:

    在原始文件夹中创建一个文件

    keep.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources xmlns:tools="http://schemas.android.com/tools"
    tools:keep="@raw/*">
    </resources>
    

    就是这样!它会将所有文件保存在raw 文件夹中,如果您想将其限制为仅可以使用的一个特定文件

    tools:keep="@raw/fileName"
    

    请注意,您不应在末尾添加文件扩展名,因此它不应filename.html

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多