从主模块访问动态要素模块的可绘制文件夹中的图形

时间:2019-08-26 18:13:28

标签: android graphics module dynamic-feature

通过动态模块拆分API交付,我将全力以赴,以便将我的游戏应用分解为Instant和Installable版本。我一直在https://codelabs.developers.google.com/codelabs/on-demand-dynamic-delivery/index.html#0处关注Codelabs教程。不幸的是,它使用Kotlin编写MainActivity代码,该代码不像Java那样具体,但是如果您完成了Kotlin教程,它仍然相当可观。该示例包括使用以下命令访问“资产”功能模块中“资产”文件夹中的文本图块:

private const val packageName = "com.google.android.samples.dynamicfeatures.ondemand"

val assetManager = createPackageContext(packageName, 0).assets
// Now treat it like any other asset file.
val assets = assetManager.open("assets.txt")
val assetContent = assets.bufferedReader()
           .use {
               it.readText()
           }

现在,我只想访问动态功能模块的可绘制文件夹中的图形文件。我将仅使用动态功能模块来存储大型图形,这些图形将使我超过10 MG的即时应用程序下载限制。这样做最干净的方法是什么?

“应用”主模块:

enter image description here

“应用”中的Java代码:

loadTexture(R.drawable.aaa_image);

Bitmap bitmap;
public void loadTexture(final int resourceId){
    bitmap = BitmapFactory.decodeResource(context.getResources(), resourceId, options);
    ***

动态交付的“ installationassets”模块:

enter image description here

“应用”中的Java代码仍然无法访问:

 loadTexture(R.drawable.testgraphic);
 cannot resolve symbol 'testgraphic'

4 个答案:

答案 0 :(得分:4)

我找到了一个从功能模块资源加载可绘制对象的可行解决方案。诀窍是为模块使用正确的软件包名称。

示例:

  • 基本模块软件包名称为“ com.project
  • 在build.gradle“ FeatureModule ” 中定义的
  • 功能模块名称
  • 功能模块程序包名称“ com.project.FeatureModule

build.gradle

dynamicFeatures = [":FeatureModule"]

Java

int drawableResId = context.getResources().getIdentifier("your_drawable_name", "drawable", "com.project.FeatureModule");
context.getDrawable(drawableResId);

Reference article

答案 1 :(得分:0)

传统上,您无法访问其他模块的资源,而只能访问资产(原始存储)。现在显然可以了,但是很混乱。但是,拆分API安排的全部目的是,您确实可以访问所有部分(模块)的代码和资源,就像它们在其中一样。我发现资产文件夹确实如此,因为您无需为动态模块引用动态创建新的上下文。我发现,如果您在主模块和动态即时模块资产文件夹中碰巧有相同标题的资产,则会从动态模块中提取该资产。

但是,我仍然无法从动态模块资源(R)中提取信息,但是在找到示例或得到更好的答案之前,我将提供一种解决方法来回答我自己的问题。您可以将图像文件放置在动态模块的资产文件夹中,然后按如下所示进行拉伸和转换:

loadTextureResource("testimage.png");//include file type (.png)

Bitmap bitmap;
public void loadTextureResource(String imagename){

    ImageView mImage=new ImageView(context);
    InputStream ims;

    try {
        // get input stream
        ims = context.getAssets().open(imagename);
        // load image as Drawable
        Drawable d = Drawable.createFromStream(ims, null);
        // set image to ImageView
        mImage.setImageDrawable(d);

        bitmap = ((BitmapDrawable)mImage.getDrawable()).getBitmap();
        ***

答案 2 :(得分:0)

com.android.application模块无意访问com.android.dynamic-feature模块的资源,因为应用程序无法访问动态功能模块的资源表。

答案 3 :(得分:0)

对@pumnao 发布的答案进行了改进,我仍然觉得有些困惑。也许这会对下一个疲惫的旅行者有所帮助。

如果您的应用程序/基础 build.gradle 包括:

dynamicFeatures = [':dynamicfeature']

然后您可以像这样从 dynamicfeature 加载资源:

val splitManager = SplitInstallManagerFactory.create(context)
val featureName = "dynamicfeature"
val installed = splitManager.installedModules.contains(featureName)

if (installed) {
  val refreshedContext = context.createPackageContext(context.packageName, 0)
  val packageName = "${context.applicationContext.packageName}.$featureName"

  val drawableId = refreshedContext.resources.getIdentifier(
    "your_drawable_name", "drawable", packageName
  )
  val drawable = refreshedContext.getDrawable(drawableId)
}

下面是有趣的一行。请注意,我们使用 packageNameapplicationContext 作为前缀。

val packageName = "${context.applicationContext.packageName}.$featureName"